@@ -1080,7 +1080,23 @@ void MachObj_term(const(char)[] objfilename)
1080
1080
}
1081
1081
else
1082
1082
{
1083
- if (s.Sclass == SC .extern_ ||
1083
+ if (AArch64 && s.Sclass == SC .locstat && s.Sfl == FL .tlsdata)
1084
+ {
1085
+ rel.r_address = cast (int )r.offset;
1086
+ rel.r_symbolnum = s.Sxtrnnum;
1087
+ rel.r_pcrel = 0 ;
1088
+ rel.r_length = 3 ;
1089
+ rel.r_extern = 1 ;
1090
+ rel.r_type = ARM64_RELOC_UNSIGNED ;
1091
+ fobjbuf.write(&rel, rel.sizeof);
1092
+ foffset += rel.sizeof;
1093
+ nreloc++ ;
1094
+ int32_t * p = patchAddr64(seg, r.offset);
1095
+ // Absolute address; add in addr of start of targ seg
1096
+ * p += SecHdrTab64[SegData[s.Sseg].SDshtidx].addr + s.Soffset;
1097
+ // patch(pseg, r.offset, s.Sseg, s.Soffset);
1098
+ }
1099
+ else if (s.Sclass == SC .extern_ ||
1084
1100
s.Sclass == SC .comdef ||
1085
1101
s.Sclass == SC .comdat)
1086
1102
{
@@ -1346,7 +1362,7 @@ void MachObj_term(const(char)[] objfilename)
1346
1362
for (int i = 0 ; i < dysymtab_cmd.nextdefsym; i++ )
1347
1363
{ Symbol* s = (cast (Symbol** )public_symbuf.buf)[i];
1348
1364
1349
- // printf("Writing public symbol %d:x%x %s\n", s.Sseg, s.Soffset, s.Sident);
1365
+ // printf("Writing public symbol %d:x%x %s\n", s.Sseg, cast(int) s.Soffset, s.Sident.ptr );
1350
1366
nlist_64 sym;
1351
1367
sym.n_strx = mach_addmangled(s);
1352
1368
sym.n_type = N_EXT | N_SECT ;
@@ -1976,6 +1992,68 @@ seg_data* MachObj_tlsseg()
1976
1992
return SegData[seg];
1977
1993
}
1978
1994
1995
+ /* ******************************************
1996
+ * Emit 24 byte __thread_vars section for AArch64.
1997
+ * Returns:
1998
+ * segment to write initialization data to
1999
+ */
2000
+ @trusted
2001
+ int MachObj_thread_vars (ref Symbol s, out targ_size_t offset)
2002
+ {
2003
+ printf(" MachObj_thread_vars(s)\n " );
2004
+ symbol_print(s);
2005
+ /* create _ident$tlv$init Symbol si
2006
+ */
2007
+ Symbol* si;
2008
+ {
2009
+ char [DEST_LEN ] dest = void ;
2010
+ size_t len = strlen(s.Sident.ptr);
2011
+ char * destr = dest.ptr;
2012
+ if (len > DEST_LEN )
2013
+ destr = cast (char * )mem_malloc(len + 1 );
2014
+ destr[0 ] = ' _' ;
2015
+ memcpy(destr + 1 , s.Sident.ptr, len);
2016
+ memcpy(destr + 1 + len, " $tlv$init" .ptr, 9 ); // includes terminating 0
2017
+ si = symbol_name(destr[0 .. 1 + len + 9 ], SC .locstat, type_fake(TYint));
2018
+
2019
+ if (destr != dest.ptr)
2020
+ mem_free(dest.ptr);
2021
+ }
2022
+
2023
+ /* write _ident$tlv$init to __thread_data section
2024
+ */
2025
+ MachObj_tlsseg_data();
2026
+ si.Sseg = seg_tlsseg_data;
2027
+ si.Sfl = FL .tlsdata;
2028
+ offset = SegData[si.Sseg].SDbuf.length();
2029
+ MachObj_pubdef(si.Sseg, si, offset);
2030
+
2031
+ /* Create __thread_vars section, and s will refer to it
2032
+ */
2033
+ seg_data* tvsegdata = MachObj_tlsseg(); // __thread_vars segment
2034
+ int tvseg = seg_tlsseg;
2035
+ s.Sseg = tvseg;
2036
+ MachObj_pubdef(tvseg, &s, tvsegdata.SDbuf.length());
2037
+
2038
+ /* 3 pointers are written to __thread_vars section:
2039
+ * 1. pointer to __tlv_bootstrap
2040
+ * 2. null pointer
2041
+ * 3. pointer to _ident$tlv$init in the __thread_data section
2042
+ */
2043
+
2044
+ // 1. pointer to __tlv_bootstrap
2045
+ Symbol* stlv_bootstrap = MachObj_tlv_bootstrap();
2046
+ MachObj_reftoident(tvseg, tvsegdata.SDbuf.length(), stlv_bootstrap, 0 , CFoff | CFoffset64);
2047
+
2048
+ // 2. null pointer
2049
+ MachObj_write_zeros(tvsegdata, 8 );
2050
+
2051
+ // 3. pointer to _ident$tlv$init in the __thread_data section
2052
+ MachObj_reftoident(tvseg, tvsegdata.SDbuf.length(), si, 0 , CFoff | CFoffset64);
2053
+
2054
+ assert ((tvsegdata.SDbuf.length() % 24 ) == 0 );
2055
+ return si.Sseg;
2056
+ }
1979
2057
1980
2058
/* ********************************
1981
2059
* Define segments for Thread Local Storage.
@@ -2223,7 +2301,7 @@ void MachObj_pubdefsize(int seg, Symbol* s, targ_size_t offset, targ_size_t syms
2223
2301
void MachObj_pubdef (int seg, Symbol* s, targ_size_t offset)
2224
2302
{
2225
2303
// printf("MachObj_pubdef(%d:x%llx s=%p, %s)\n", seg, offset, s, s.Sident.ptr);
2226
- // symbol_print(s);
2304
+ // symbol_print(* s);
2227
2305
symbol_debug(s);
2228
2306
2229
2307
s.Soffset = offset;
0 commit comments