History

Add new macho object format to tccmacho

Apple has a new object format that uses chained fixups. I have implemented this with a configure option '--config-new_macho' See configure and Makefile tccmacho.c contains the biggest change. I split the lazy_bind_rebase structure into lazy_bind and rebase for the old format. Under the macro CONFIG_NEW_MACHO there is the new macho format code. In arm64-gen.c we do not need to push all registers on stack for variadic functions. variadic parameters are pushed on stack for apple. There is still one open isue. The export trie is empty. This only effects dlsym when a local symbol is used. tested on apple x86_64(10.5) and arm64(12.3).

herman ten brugge committed 3 years ago

Commit b86d82c1 parent d605d754 files · +597 −84Browse files

Unified · Split

4 files
  1. Makefile +1 −0
  2. arm64-gen.c +2 −2
  3. configure +1 −0
  4. tccmacho.c +593 −82
Makefile+1−0
@@ -93,6 +93,7 @@ NATIVE_DEFINES_$(CONFIG_BSD) += -DTARGETOS_$(TARGETOS) · 92 unmodified lines
9393 NATIVE_DEFINES_$(CONFIG_Android) += -DTARGETOS_ANDROID
9494 NATIVE_DEFINES_$(CONFIG_pie) += -DCONFIG_TCC_PIE
9595 NATIVE_DEFINES_$(CONFIG_pic) += -DCONFIG_TCC_PIC
96+NATIVE_DEFINES_$(CONFIG_new_macho) += -DCONFIG_NEW_MACHO
9697 NATIVE_DEFINES_$(CONFIG_new-dtags) += -DCONFIG_NEW_DTAGS
9798 NATIVE_DEFINES_no_$(CONFIG_bcheck) += -DCONFIG_TCC_BCHECK=0
9899 NATIVE_DEFINES_no_$(CONFIG_backtrace) += -DCONFIG_TCC_BACKTRACE=0
arm64-gen.c+2−2
@@ -1202,16 +1202,16 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 1201 unmodified lines
12021202
12031203 arm64_func_va_list_stack = arm64_pcs(variadic ? var_nb_arg : 0, n - 1, t, a);
12041204
1205+#if !defined(__APPLE__)
12051206 if (variadic) {
12061207 use_x8 = 1;
12071208 last_int = 4;
12081209 last_float = 4;
12091210 }
1211+#endif
12101212 if (a && a[0] == 1)
12111213 use_x8 = 1;
12121214 for (i = 1, sym = func_type->ref->next; sym; i++, sym = sym->next) {
1213− if (a[i] == 1)
1214− use_x8 = 1;
12151215 if (a[i] < 16) {
12161216 int last, align, size = type_size(&sym->type, &align);
12171217 last = a[i] / 4 + 1 + (size - 1) / 8;
configure+1−0
@@ -350,6 +350,7 @@ Advanced options (experts only): · 349 unmodified lines
350350 --config-backtrace=no disable stack backtraces (with -run or -bt)
351351 --config-bcheck=no disable bounds checker (-b)
352352 --config-predefs=no do not compile tccdefs.h, instead just include
353+ --config-new_macho Use apple new macho object format
353354 --dwarf=x Use dwarf debug info instead of stabs (x=2..5)
354355 EOF
355356 exit 1
tccmacho.c+593−82
@@ -107,6 +107,8 @@ struct load_command { · 106 unmodified lines
107107 #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
108108 #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)
109109 #define LC_MAIN (0x28|LC_REQ_DYLD)
110+#define LC_DYLD_EXPORTS_TRIE (0x33 | LC_REQ_DYLD)
111+#define LC_DYLD_CHAINED_FIXUPS (0x34 | LC_REQ_DYLD)
110112
111113 typedef int vm_prot_t;
112114
@@ -139,6 +141,79 @@ struct section_64 { /* for 64-bit architectures */ · 26 unmodified lines
139141 uint32_t reserved3; /* reserved */
140142 };
141143
144+enum {
145+ DYLD_CHAINED_IMPORT = 1,
146+};
147+
148+struct dyld_chained_fixups_header {
149+ uint32_t fixups_version; ///< 0
150+ uint32_t starts_offset; ///< Offset of dyld_chained_starts_in_image.
151+ uint32_t imports_offset; ///< Offset of imports table in chain_data.
152+ uint32_t symbols_offset; ///< Offset of symbol strings in chain_data.
153+ uint32_t imports_count; ///< Number of imported symbol names.
154+ uint32_t imports_format; ///< DYLD_CHAINED_IMPORT*
155+ uint32_t symbols_format; ///< 0 => uncompressed, 1 => zlib compressed
156+};
157+
158+struct dyld_chained_starts_in_image
159+{
160+ uint32_t seg_count;
161+ uint32_t seg_info_offset[1]; // each entry is offset into this struct for that segment
162+ // followed by pool of dyld_chain_starts_in_segment data
163+};
164+
165+enum {
166+ DYLD_CHAINED_PTR_64 = 2, // target is vmaddr
167+ DYLD_CHAINED_PTR_64_OFFSET = 6, // target is vm offset
168+};
169+
170+enum {
171+ DYLD_CHAINED_PTR_START_NONE = 0xFFFF, // used in page_start[] to denote a page with no fixups
172+};
173+
174+#define SEG_PAGE_SIZE 16384
175+
176+struct dyld_chained_starts_in_segment
177+{
178+ uint32_t size; // size of this (amount kernel needs to copy)
179+ uint16_t page_size; // 0x1000 or 0x4000
180+ uint16_t pointer_format; // DYLD_CHAINED_PTR_*
181+ uint64_t segment_offset; // offset in memory to start of segment
182+ uint32_t max_valid_pointer; // for 32-bit OS, any value beyond this is not a pointer
183+ uint16_t page_count; // how many pages are in array
184+ uint16_t page_start[1]; // each entry is offset in each page of first element in chain
185+ // or DYLD_CHAINED_PTR_START_NONE if no fixups on page
186+};
187+
188+enum BindSpecialDylib {
189+ BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2,
190+};
191+
192+struct dyld_chained_import
193+{
194+ uint32_t lib_ordinal : 8,
195+ weak_import : 1,
196+ name_offset : 23;
197+};
198+
199+struct dyld_chained_ptr_64_rebase
200+{
201+ uint64_t target : 36, // vmaddr, 64GB max image size
202+ high8 : 8, // top 8 bits set to this after slide added
203+ reserved : 7, // all zeros
204+ next : 12, // 4-byte stride
205+ bind : 1; // == 0
206+};
207+
208+struct dyld_chained_ptr_64_bind
209+{
210+ uint64_t ordinal : 24,
211+ addend : 8, // 0 thru 255
212+ reserved : 19, // all zeros
213+ next : 12, // 4-byte stride
214+ bind : 1; // == 1
215+};
216+
142217 #define S_REGULAR 0x0
143218 #define S_ZEROFILL 0x1
144219 #define S_NON_LAZY_SYMBOL_POINTERS 0x6
@@ -169,6 +244,18 @@ struct dylinker_command { · 24 unmodified lines
169244 lc_str name; /* dynamic linker's path name */
170245 };
171246
247+struct linkedit_data_command {
248+ uint32_t cmd; /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
249+ LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
250+ LC_DYLIB_CODE_SIGN_DRS,
251+ LC_LINKER_OPTIMIZATION_HINT,
252+ LC_DYLD_EXPORTS_TRIE, or
253+ LC_DYLD_CHAINED_FIXUPS. */
254+ uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */
255+ uint32_t dataoff; /* file offset of data in __LINKEDIT segment */
256+ uint32_t datasize; /* file size of data in __LINKEDIT segment */
257+};
258+
172259 struct symtab_command {
173260 uint32_t cmd; /* LC_SYMTAB */
174261 uint32_t cmdsize; /* sizeof(struct symtab_command) */
@@ -226,6 +313,10 @@ struct dysymtab_command { · 51 unmodified lines
226313
227314 #define REBASE_TYPE_POINTER 1
228315
316+#define EXPORT_SYMBOL_FLAGS_KIND_REGULAR 0x00
317+#define EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE 0x02
318+#define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04
319+
229320 struct dyld_info_command {
230321 uint32_t cmd; /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */
231322 uint32_t cmdsize; /* sizeof(struct dyld_info_command) */
@@ -304,26 +395,41 @@ struct macho { · 72 unmodified lines
304395 } sk_to_sect[sk_last];
305396 int *elfsectomacho;
306397 int *e2msym;
307− Section *rebase, *binding, *weak_binding, *lazy_binding, *exports;
308− Section *symtab, *strtab, *wdata, *indirsyms;
309− Section *stubs, *stub_helper, *la_symbol_ptr;
310− int nr_plt, n_got;
311− struct dyld_info_command *dyldinfo;
312− int stubsym, helpsym, lasym, dyld_private, dyld_stub_binder;
398+ Section *symtab, *strtab, *wdata, *indirsyms, *stubs, *exports;
313399 uint32_t ilocal, iextdef, iundef;
314− int n_lazy_bind_rebase;
315− struct lazy_bind_rebase {
400+ int stubsym, n_got, nr_plt;
401+#ifdef CONFIG_NEW_MACHO
402+ Section *chained_fixups;
403+ int n_bind;
404+ int n_bind_rebase;
405+ struct bind_rebase {
406+ int section;
407+ int bind;
408+ ElfW_Rel rel;
409+ } *bind_rebase;
410+#else
411+ Section *rebase, *binding, *weak_binding, *lazy_binding;
412+ Section *stub_helper, *la_symbol_ptr;
413+ struct dyld_info_command *dyldinfo;
414+ int helpsym, lasym, dyld_private, dyld_stub_binder;
415+ int n_lazy_bind;
416+ struct s_lazy_bind {
316417 int section;
317− int bind;
318418 int bind_offset;
319419 int la_symbol_offset;
320420 ElfW_Rel rel;
321− } *lazy_bind_rebase;
421+ } *s_lazy_bind;
422+ int n_rebase;
423+ struct s_rebase {
424+ int section;
425+ ElfW_Rel rel;
426+ } *s_rebase;
322427 int n_bind;
323428 struct bind {
324429 int section;
325430 ElfW_Rel rel;
326431 } *bind;
432+#endif
327433 };
328434
329435 #define SHT_LINKEDIT (SHT_LOOS + 42)
@@ -386,6 +492,7 @@ static void * add_dylib(struct macho *mo, char *name) · 56 unmodified lines
386492 return lc;
387493 }
388494
495+#ifndef CONFIG_NEW_MACHO
389496 static void write_uleb128(Section *section, uint64_t value)
390497 {
391498 do {
@@ -396,6 +503,7 @@ static void write_uleb128(Section *section, uint64_t value) · 4 unmodified lines
396503 *ptr = byte | (value ? 0x80 : 0);
397504 } while (value != 0);
398505 }
506+#endif
399507
400508 static void tcc_macho_add_destructor(TCCState *s1)
401509 {
@@ -492,6 +600,135 @@ static void tcc_macho_add_destructor(TCCState *s1) · 90 unmodified lines
492600 add_array (s1, ".init_array", init_sym);
493601 }
494602
603+#ifdef CONFIG_NEW_MACHO
604+static void bind_rebase_add(struct macho *mo, int bind, int sh_info,
605+ ElfW_Rel *rel, struct sym_attr *attr)
606+{
607+ mo->bind_rebase = tcc_realloc(mo->bind_rebase, (mo->n_bind_rebase + 1) *
608+ sizeof(struct bind_rebase));
609+ mo->bind_rebase[mo->n_bind_rebase].section = sh_info;
610+ mo->bind_rebase[mo->n_bind_rebase].bind = bind;
611+ mo->bind_rebase[mo->n_bind_rebase].rel = *rel;
612+ if (attr)
613+ mo->bind_rebase[mo->n_bind_rebase].rel.r_offset = attr->got_offset;
614+ mo->n_bind_rebase++;
615+ mo->n_bind += bind;
616+}
617+
618+static void check_relocs(TCCState *s1, struct macho *mo)
619+{
620+ Section *s;
621+ ElfW_Rel *rel;
622+ ElfW(Sym) *sym;
623+ int i, type, gotplt_entry, sym_index, for_code;
624+ int sh_num, debug;
625+ uint32_t *pi, *goti;
626+ struct sym_attr *attr;
627+
628+ mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
629+ goti = NULL;
630+ mo->nr_plt = mo->n_got = 0;
631+ for (i = 1; i < s1->nb_sections; i++) {
632+ s = s1->sections[i];
633+ if (s->sh_type != SHT_RELX)
634+ continue;
635+ sh_num = s1->sections[s->sh_info]->sh_num;
636+ debug = sh_num >= s1->dwlo && sh_num < s1->dwhi;
637+ if (debug)
638+ continue;
639+ for_each_elem(s, 0, rel, ElfW_Rel) {
640+ type = ELFW(R_TYPE)(rel->r_info);
641+ gotplt_entry = gotplt_entry_type(type);
642+ for_code = code_reloc(type);
643+ /* We generate a non-lazy pointer for used undefined symbols
644+ and for defined symbols that must have a place for their
645+ address due to codegen (i.e. a reloc requiring a got slot). */
646+ sym_index = ELFW(R_SYM)(rel->r_info);
647+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
648+ if (sym->st_shndx == SHN_UNDEF
649+ || gotplt_entry == ALWAYS_GOTPLT_ENTRY) {
650+ attr = get_sym_attr(s1, sym_index, 1);
651+ if (!attr->dyn_index) {
652+ attr->got_offset = s1->got->data_offset;
653+ attr->plt_offset = -1;
654+ attr->dyn_index = 1; /* used as flag */
655+ section_ptr_add(s1->got, PTR_SIZE);
656+ put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
657+ R_DATA_PTR, sym_index);
658+ goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));
659+ if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
660+ if (sym->st_shndx == SHN_UNDEF)
661+ tcc_error("undefined local symbo: '%s'",
662+ (char *) symtab_section->link->data + sym->st_name);
663+ goti[mo->n_got++] = INDIRECT_SYMBOL_LOCAL;
664+ } else {
665+ goti[mo->n_got++] = mo->e2msym[sym_index];
666+ if (sym->st_shndx == SHN_UNDEF
667+#ifdef TCC_TARGET_X86_64
668+ && type == R_X86_64_GOTPCREL
669+#elif defined TCC_TARGET_ARM64
670+ && type == R_AARCH64_ADR_GOT_PAGE
671+#endif
672+ ) {
673+ bind_rebase_add(mo, 1, s1->got->reloc->sh_info, rel, attr);
674+ attr->plt_offset = 0; // ignore next bind
675+ s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
676+ }
677+ if (for_code)
678+ s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
679+ }
680+ }
681+ if (for_code) {
682+ if (attr->plt_offset == -1) {
683+ uint8_t *jmp;
684+
685+ attr->plt_offset = mo->stubs->data_offset;
686+#ifdef TCC_TARGET_X86_64
687+ if (type != R_X86_64_PLT32)
688+ continue;
689+ jmp = section_ptr_add(mo->stubs, 6);
690+ jmp[0] = 0xff; /* jmpq *ofs(%rip) */
691+ jmp[1] = 0x25;
692+ put_elf_reloc(s1->symtab, mo->stubs,
693+ attr->plt_offset + 2,
694+ R_X86_64_GOTPCREL, sym_index);
695+#elif defined TCC_TARGET_ARM64
696+ if (type != R_AARCH64_CALL26)
697+ continue;
698+ jmp = section_ptr_add(mo->stubs, 12);
699+ put_elf_reloc(s1->symtab, mo->stubs,
700+ attr->plt_offset,
701+ R_AARCH64_ADR_GOT_PAGE, sym_index);
702+ write32le(jmp, // adrp x16, #sym
703+ 0x90000010);
704+ put_elf_reloc(s1->symtab, mo->stubs,
705+ attr->plt_offset + 4,
706+ R_AARCH64_LD64_GOT_LO12_NC, sym_index);
707+ write32le(jmp + 4, // ld x16,[x16, #sym]
708+ 0xf9400210);
709+ write32le(jmp + 8, // br x16
710+ 0xd61f0200);
711+#endif
712+ bind_rebase_add(mo, 1, s1->got->reloc->sh_info, rel, attr);
713+ pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
714+ *pi = mo->e2msym[sym_index];
715+ mo->nr_plt++;
716+ }
717+ rel->r_info = ELFW(R_INFO)(mo->stubsym, type);
718+ rel->r_addend += attr->plt_offset;
719+ }
720+ }
721+ if (type == R_DATA_PTR)
722+ bind_rebase_add(mo, 0, s->sh_info, rel, NULL);
723+ }
724+ }
725+ pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi));
726+ memcpy(pi, goti, mo->n_got * sizeof(*pi));
727+ tcc_free(goti);
728+}
729+
730+#else
731+
495732 static void check_relocs(TCCState *s1, struct macho *mo)
496733 {
497734 uint8_t *jmp;
@@ -594,9 +831,6 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 96 unmodified lines
594831 }
595832 if (for_code && sym->st_shndx == SHN_UNDEF) {
596833 if (attr->plt_offset == -1) {
597− pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
598− *pi = mo->e2msym[sym_index];
599− mo->nr_plt++;
600834 attr->plt_offset = mo->stubs->data_offset;
601835 #ifdef TCC_TARGET_X86_64
602836 if (type != R_X86_64_PLT32)
@@ -623,7 +857,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 20 unmodified lines
623857 mo->la_symbol_ptr->data_offset,
624858 R_DATA_PTR, mo->helpsym,
625859 mo->stub_helper->data_offset - 10);
626− jmp = section_ptr_add(mo->la_symbol_ptr, PTR_SIZE);
860+ section_ptr_add(mo->la_symbol_ptr, PTR_SIZE);
627861 #elif defined TCC_TARGET_ARM64
628862 if (type != R_AARCH64_CALL26)
629863 continue;
@@ -661,35 +895,36 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 31 unmodified lines
661895 mo->la_symbol_ptr->data_offset,
662896 R_DATA_PTR, mo->helpsym,
663897 mo->stub_helper->data_offset - 12);
664− jmp = section_ptr_add(mo->la_symbol_ptr, PTR_SIZE);
898+ section_ptr_add(mo->la_symbol_ptr, PTR_SIZE);
665899 #endif
666− mo->lazy_bind_rebase =
667− tcc_realloc(mo->lazy_bind_rebase,
668− (mo->n_lazy_bind_rebase + 1) *
669− sizeof(struct lazy_bind_rebase));
670− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].section =
900+ mo->s_lazy_bind =
901+ tcc_realloc(mo->s_lazy_bind, (mo->n_lazy_bind + 1) *
902+ sizeof(struct s_lazy_bind));
903+ mo->s_lazy_bind[mo->n_lazy_bind].section =
671904 mo->stub_helper->reloc->sh_info;
672− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].bind = 1;
673− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].bind_offset = bind_offset;
674− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].la_symbol_offset = la_symbol_offset;
675− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].rel = *rel;
676− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].rel.r_offset =
905+ mo->s_lazy_bind[mo->n_lazy_bind].bind_offset =
906+ bind_offset;
907+ mo->s_lazy_bind[mo->n_lazy_bind].la_symbol_offset =
908+ la_symbol_offset;
909+ mo->s_lazy_bind[mo->n_lazy_bind].rel = *rel;
910+ mo->s_lazy_bind[mo->n_lazy_bind].rel.r_offset =
677911 attr->plt_offset;
678− mo->n_lazy_bind_rebase++;
912+ mo->n_lazy_bind++;
913+ pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
914+ *pi = mo->e2msym[sym_index];
915+ mo->nr_plt++;
679916 }
680917 rel->r_info = ELFW(R_INFO)(mo->stubsym, type);
681918 rel->r_addend += attr->plt_offset;
682919 }
683920 }
684921 if (type == R_DATA_PTR) {
685− mo->lazy_bind_rebase =
686− tcc_realloc(mo->lazy_bind_rebase,
687− (mo->n_lazy_bind_rebase + 1) *
688− sizeof(struct lazy_bind_rebase));
689− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].section = s->sh_info;
690− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].bind = 0;
691− mo->lazy_bind_rebase[mo->n_lazy_bind_rebase].rel = *rel;
692− mo->n_lazy_bind_rebase++;
922+ mo->s_rebase =
923+ tcc_realloc(mo->s_rebase, (mo->n_rebase + 1) *
924+ sizeof(struct s_rebase));
925+ mo->s_rebase[mo->n_rebase].section = s->sh_info;
926+ mo->s_rebase[mo->n_rebase].rel = *rel;
927+ mo->n_rebase++;
693928 }
694929 }
695930 }
@@ -699,6 +934,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 3 unmodified lines
699934 memcpy(pi, mo->indirsyms->data, mo->nr_plt * sizeof(*pi));
700935 tcc_free(goti);
701936 }
937+#endif
702938
703939 static int check_symbols(TCCState *s1, struct macho *mo)
704940 {
@@ -865,12 +1101,16 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 160 unmodified lines
8651101 /* Stub creation belongs to check_relocs, but we need to create
8661102 the symbol now, so its included in the sorting. */
8671103 mo->stubs = new_section(s1, "__stubs", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
868− mo->stub_helper = new_section(s1, "__stub_helper", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
8691104 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
870− mo->la_symbol_ptr = new_section(s1, "__la_symbol_ptr", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
8711105 mo->stubsym = put_elf_sym(s1->symtab, 0, 0,
8721106 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
8731107 mo->stubs->sh_num, ".__stubs");
1108+#ifdef CONFIG_NEW_MACHO
1109+ mo->chained_fixups = new_section(s1, "CHAINED_FIXUPS",
1110+ SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
1111+#else
1112+ mo->stub_helper = new_section(s1, "__stub_helper", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1113+ mo->la_symbol_ptr = new_section(s1, "__la_symbol_ptr", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
8741114 mo->helpsym = put_elf_sym(s1->symtab, 0, 0,
8751115 ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
8761116 mo->stub_helper->sh_num, ".__stub_helper");
@@ -889,6 +1129,7 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 12 unmodified lines
8891129 mo->binding = new_section(s1, "BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
8901130 mo->weak_binding = new_section(s1, "WEAK_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
8911131 mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
1132+#endif
8921133 mo->exports = new_section(s1, "EXPORT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
8931134
8941135 mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
@@ -942,6 +1183,32 @@ const struct { · 47 unmodified lines
9421183 /*[sk_linkedit] =*/ { 3, S_REGULAR, NULL },
9431184 };
9441185
1186+#ifdef CONFIG_NEW_MACHO
1187+static void calc_fixup_size(TCCState *s1, struct macho *mo)
1188+{
1189+ int i, size;
1190+
1191+ size = (sizeof(struct dyld_chained_fixups_header) + 7) & -8;
1192+ size += (sizeof(struct dyld_chained_starts_in_image) + (mo->nseg - 1) * sizeof(uint32_t) + 7) & -8;
1193+ for (i = 1; i < mo->nseg - 1; i++) {
1194+ int page_count = (get_segment(mo, i)->vmsize + SEG_PAGE_SIZE - 1) / SEG_PAGE_SIZE;
1195+ size += (sizeof(struct dyld_chained_starts_in_segment) + (page_count - 1) * sizeof(uint16_t) + 7) & -8;
1196+ }
1197+ size += mo->n_bind * sizeof (struct dyld_chained_import) + 1;
1198+ for (i = 0; i < mo->n_bind_rebase; i++) {
1199+ if (mo->bind_rebase[i].bind) {
1200+ int sym_index = ELFW(R_SYM)(mo->bind_rebase[i].rel.r_info);
1201+ ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1202+ const char *name = (char *) symtab_section->link->data + sym->st_name;
1203+ size += strlen(name) + 1;
1204+ }
1205+ }
1206+ size = (size + 7) & -8;
1207+ section_ptr_add(mo->chained_fixups, size);
1208+}
1209+
1210+#else
1211+
9451212 static void set_segment_and_offset(struct macho *mo, addr_t addr,
9461213 uint8_t *ptr, int opcode,
9471214 Section *sec, addr_t offset)
@@ -958,49 +1225,51 @@ static void set_segment_and_offset(struct macho *mo, addr_t addr, · 10 unmodified lines
9581225 write_uleb128(sec, offset - seg->vmaddr);
9591226 }
9601227
961−static void do_bind_rebase(TCCState *s1, struct macho *mo)
1228+static void bind_rebase(TCCState *s1, struct macho *mo)
9621229 {
9631230 int i;
9641231 uint8_t *ptr;
9651232 ElfW(Sym) *sym;
966− char *name;
1233+ const char *name;
9671234
968− for (i = 0; i < mo->n_lazy_bind_rebase; i++) {
969− int sym_index = ELFW(R_SYM)(mo->lazy_bind_rebase[i].rel.r_info);
970− Section *s = s1->sections[mo->lazy_bind_rebase[i].section];
1235+ for (i = 0; i < mo->n_lazy_bind; i++) {
1236+ int sym_index = ELFW(R_SYM)(mo->s_lazy_bind[i].rel.r_info);
9711237
9721238 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
9731239 name = (char *) symtab_section->link->data + sym->st_name;
974− if (mo->lazy_bind_rebase[i].bind) {
975− write32le(mo->stub_helper->data +
976− mo->lazy_bind_rebase[i].bind_offset,
977− mo->lazy_binding->data_offset);
978− ptr = section_ptr_add(mo->lazy_binding, 1);
979− set_segment_and_offset(mo, mo->la_symbol_ptr->sh_addr, ptr,
980− BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
981− mo->lazy_binding,
982− mo->la_symbol_ptr->sh_addr +
983− mo->lazy_bind_rebase[i].la_symbol_offset);
984− ptr = section_ptr_add(mo->lazy_binding, 5 + strlen(name));
985− *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
986− (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
987− *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;
988− strcpy(ptr, name);
989− ptr += strlen(name) + 1;
990− *ptr++ = BIND_OPCODE_DO_BIND;
991− *ptr = BIND_OPCODE_DONE;
992− }
993− else {
994− ptr = section_ptr_add(mo->rebase, 2);
995− *ptr++ = REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER;
996− set_segment_and_offset(mo, s->sh_addr, ptr,
997− REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
998− mo->rebase,
999− mo->lazy_bind_rebase[i].rel.r_offset +
1000− s->sh_addr);
1001− ptr = section_ptr_add(mo->rebase, 1);
1002− *ptr = REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1;
1003− }
1240+ write32le(mo->stub_helper->data +
1241+ mo->s_lazy_bind[i].bind_offset,
1242+ mo->lazy_binding->data_offset);
1243+ ptr = section_ptr_add(mo->lazy_binding, 1);
1244+ set_segment_and_offset(mo, mo->la_symbol_ptr->sh_addr, ptr,
1245+ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
1246+ mo->lazy_binding,
1247+ mo->s_lazy_bind[i].la_symbol_offset +
1248+ mo->la_symbol_ptr->sh_addr);
1249+ ptr = section_ptr_add(mo->lazy_binding, 5 + strlen(name));
1250+ *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
1251+ (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
1252+ *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;
1253+ strcpy(ptr, name);
1254+ ptr += strlen(name) + 1;
1255+ *ptr++ = BIND_OPCODE_DO_BIND;
1256+ *ptr = BIND_OPCODE_DONE;
1257+ }
1258+ for (i = 0; i < mo->n_rebase; i++) {
1259+ int sym_index = ELFW(R_SYM)(mo->s_rebase[i].rel.r_info);
1260+ Section *s = s1->sections[mo->s_rebase[i].section];
1261+
1262+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1263+ name = (char *) symtab_section->link->data + sym->st_name;
1264+ ptr = section_ptr_add(mo->rebase, 2);
1265+ *ptr++ = REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER;
1266+ set_segment_and_offset(mo, s->sh_addr, ptr,
1267+ REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
1268+ mo->rebase,
1269+ mo->s_rebase[i].rel.r_offset +
1270+ s->sh_addr);
1271+ ptr = section_ptr_add(mo->rebase, 1);
1272+ *ptr = REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1;
10041273 }
10051274 for (i = 0; i < mo->n_bind; i++) {
10061275 int sym_index = ELFW(R_SYM)(mo->bind[i].rel.r_info);
@@ -1018,10 +1287,10 @@ static void do_bind_rebase(TCCState *s1, struct macho *mo) · 11 unmodified lines
10181287 strcpy(ptr, name);
10191288 ptr += strlen(name) + 1;
10201289 *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER;
1021− set_segment_and_offset(mo, s->sh_addr, ptr,
1022− BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
1023− binding,
1024− mo->bind[i].rel.r_offset + s->sh_addr);
1290+ set_segment_and_offset(mo, s->sh_addr, ptr,
1291+ BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
1292+ binding,
1293+ mo->bind[i].rel.r_offset + s->sh_addr);
10251294 ptr = section_ptr_add(binding, 1);
10261295 *ptr++ = BIND_OPCODE_DO_BIND;
10271296 }
@@ -1029,9 +1298,42 @@ static void do_bind_rebase(TCCState *s1, struct macho *mo) · 1 unmodified line
10291298 ptr = section_ptr_add(mo->rebase, 1);
10301299 *ptr = REBASE_OPCODE_DONE;
10311300 }
1032− tcc_free(mo->lazy_bind_rebase);
1301+ if (mo->binding->data_offset) {
1302+ ptr = section_ptr_add(mo->binding, 1);
1303+ *ptr = BIND_OPCODE_DONE;
1304+ }
1305+ if (mo->weak_binding->data_offset) {
1306+ ptr = section_ptr_add(mo->weak_binding, 1);
1307+ *ptr = BIND_OPCODE_DONE;
1308+ }
1309+ tcc_free(mo->s_lazy_bind);
1310+ tcc_free(mo->s_rebase);
10331311 tcc_free(mo->bind);
10341312 }
1313+#endif
1314+
1315+/* FIXME */
1316+static void export_trie(TCCState *s1, struct macho *mo)
1317+{
1318+ int sym_index;
1319+ int sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));;
1320+
1321+ for (sym_index = 1; sym_index < sym_end; ++sym_index) {
1322+ ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
1323+ const char *name = (char*)symtab_section->link->data + sym->st_name;
1324+
1325+ if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE &&
1326+ ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL) {
1327+ int flag = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
1328+
1329+ if (sym->st_shndx == SHN_ABS)
1330+ flag = EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE;
1331+ if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1332+ flag |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1333+ dprintf ("%s %d %llx\n", name, flag, sym->st_value + s1->sections[sym->st_shndx]->sh_addr);
1334+ }
1335+ }
1336+}
10351337
10361338 static void collect_sections(TCCState *s1, struct macho *mo)
10371339 {
@@ -1039,6 +1341,10 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 1 unmodified line
10391341 uint64_t curaddr, fileofs;
10401342 Section *s;
10411343 struct segment_command_64 *seg = NULL;
1344+#ifdef CONFIG_NEW_MACHO
1345+ struct linkedit_data_command *chained_fixups_lc;
1346+ struct linkedit_data_command *export_trie_lc;
1347+#endif
10421348 struct dylinker_command *dyldlc;
10431349 struct symtab_command *symlc;
10441350 struct dysymtab_command *dysymlc;
@@ -1062,6 +1368,15 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 17 unmodified lines
10621368 seg->maxprot = 7; // rwx
10631369 seg->initprot = 1; // r--
10641370
1371+#ifdef CONFIG_NEW_MACHO
1372+ chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS,
1373+ sizeof(struct linkedit_data_command));
1374+ export_trie_lc = add_lc(mo, LC_DYLD_EXPORTS_TRIE,
1375+ sizeof(struct linkedit_data_command));
1376+#else
1377+ mo->dyldinfo = add_lc(mo, LC_DYLD_INFO_ONLY, sizeof(*mo->dyldinfo));
1378+#endif
1379+
10651380 mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));
10661381 mo->ep->entryoff = 4096;
10671382
@@ -1071,7 +1386,6 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 3 unmodified lines
10711386 str = (char*)dyldlc + dyldlc->name;
10721387 strcpy(str, "/usr/lib/dyld");
10731388
1074− mo->dyldinfo = add_lc(mo, LC_DYLD_INFO_ONLY, sizeof(*mo->dyldinfo));
10751389 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));
10761390 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));
10771391
@@ -1109,12 +1423,14 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 31 unmodified lines
11091423 case SHT_PROGBITS:
11101424 if (s == mo->stubs)
11111425 sk = sk_stubs;
1426+#ifndef CONFIG_NEW_MACHO
11121427 else if (s == mo->stub_helper)
11131428 sk = sk_stub_helper;
1114− else if (s == s1->got)
1115− sk = sk_nl_ptr;
11161429 else if (s == mo->la_symbol_ptr)
11171430 sk = sk_la_ptr;
1431+#endif
1432+ else if (s == s1->got)
1433+ sk = sk_nl_ptr;
11181434 else if (s == stab_section)
11191435 sk = sk_stab;
11201436 else if (s == dwarf_info_section)
@@ -1150,15 +1466,23 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 29 unmodified lines
11501466 mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections);
11511467 for (sk = sk_unknown; sk < sk_last; sk++) {
11521468 struct section_64 *sec = NULL;
1153−#define SEG_PAGE_SIZE 16384
1154− if (sk == sk_linkedit)
1155− do_bind_rebase(s1, mo);
11561469 if (seg) {
11571470 seg->vmsize = (curaddr - seg->vmaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
11581471 seg->filesize = (fileofs - seg->fileoff + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
11591472 curaddr = seg->vmaddr + seg->vmsize;
11601473 fileofs = seg->fileoff + seg->filesize;
11611474 }
1475+#ifdef CONFIG_NEW_MACHO
1476+ if (sk == sk_linkedit) {
1477+ calc_fixup_size(s1, mo);
1478+ export_trie(s1, mo);
1479+ }
1480+#else
1481+ if (sk == sk_linkedit) {
1482+ bind_rebase(s1, mo);
1483+ export_trie(s1, mo);
1484+ }
1485+#endif
11621486 if (skinfo[sk].seg && mo->sk_to_sect[sk].s) {
11631487 uint64_t al = 0;
11641488 int si;
@@ -1178,14 +1502,23 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 13 unmodified lines
11781502 #endif
11791503 if (sk == sk_nl_ptr)
11801504 sec->reserved1 = mo->nr_plt;
1505+#ifndef CONFIG_NEW_MACHO
11811506 if (sk == sk_la_ptr)
11821507 sec->reserved1 = mo->nr_plt + mo->n_got;
1508+#endif
11831509 }
11841510 if (seg->vmaddr == -1) {
1511+#ifdef CONFIG_NEW_MACHO
1512+ curaddr = (curaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
1513+ seg->vmaddr = curaddr;
1514+ fileofs = (fileofs + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
1515+ seg->fileoff = fileofs;
1516+#else
11851517 curaddr = (curaddr + 4095) & -4096;
11861518 seg->vmaddr = curaddr;
11871519 fileofs = (fileofs + 4095) & -4096;
11881520 seg->fileoff = fileofs;
1521+#endif
11891522 }
11901523
11911524 for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
@@ -1266,6 +1599,16 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 74 unmodified lines
12661599 dysymlc->indirectsymoff = mo->indirsyms->sh_offset;
12671600 dysymlc->nindirectsyms = mo->indirsyms->data_offset / sizeof(uint32_t);
12681601
1602+#ifdef CONFIG_NEW_MACHO
1603+ if (mo->chained_fixups->data_offset) {
1604+ chained_fixups_lc->dataoff = mo->chained_fixups->sh_offset;
1605+ chained_fixups_lc->datasize = mo->chained_fixups->data_offset;
1606+ }
1607+ if (mo->exports->data_offset) {
1608+ export_trie_lc->dataoff = mo->exports->sh_offset;
1609+ export_trie_lc->datasize = mo->exports->data_offset;
1610+ }
1611+#else
12691612 if (mo->rebase->data_offset) {
12701613 mo->dyldinfo->rebase_off = mo->rebase->sh_offset;
12711614 mo->dyldinfo->rebase_size = mo->rebase->data_offset;
@@ -1286,6 +1629,7 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 14 unmodified lines
12861629 mo->dyldinfo->export_off = mo->exports->sh_offset;
12871630 mo->dyldinfo->export_size = mo->exports->data_offset;
12881631 }
1632+#endif
12891633 }
12901634
12911635 static void macho_write(TCCState *s1, struct macho *mo, FILE *fp)
@@ -1333,6 +1677,170 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) · 41 unmodified lines
13331677 }
13341678 }
13351679
1680+#ifdef CONFIG_NEW_MACHO
1681+static int bind_rebase_cmp(const void *_a, const void *_b, void *arg)
1682+{
1683+ TCCState *s1 = arg;
1684+ struct bind_rebase *a = (struct bind_rebase *) _a;
1685+ struct bind_rebase *b = (struct bind_rebase *) _b;
1686+ addr_t aa = s1->sections[a->section]->sh_addr + a->rel.r_offset;
1687+ addr_t ab = s1->sections[b->section]->sh_addr + b->rel.r_offset;
1688+
1689+ return aa > ab ? 1 : aa < ab ? -1 : 0;
1690+}
1691+
1692+ST_FUNC void bind_rebase_import(TCCState *s1, struct macho *mo)
1693+{
1694+ int i, j, k, bind_index, size, page_count, sym_index;
1695+ const char *name;
1696+ ElfW_Rel rel;
1697+ ElfW(Sym) *sym;
1698+ unsigned char *data = mo->chained_fixups->data;
1699+ struct segment_command_64 *seg;
1700+ struct dyld_chained_fixups_header *header;
1701+ struct dyld_chained_starts_in_image *image;
1702+ struct dyld_chained_starts_in_segment *segment;
1703+ struct dyld_chained_import *import;
1704+
1705+ tcc_qsort(mo->bind_rebase, mo->n_bind_rebase, sizeof(struct bind_rebase),
1706+ bind_rebase_cmp, s1);
1707+ for (i = 0; i < mo->n_bind_rebase - 1; i++)
1708+ if (mo->bind_rebase[i].section == mo->bind_rebase[i + 1].section &&
1709+ mo->bind_rebase[i].rel.r_offset == mo->bind_rebase[i + 1].rel.r_offset) {
1710+ sym_index = ELFW(R_SYM)(mo->bind_rebase[i].rel.r_info);
1711+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1712+ name = (char *) symtab_section->link->data + sym->st_name;
1713+ tcc_error("Overlap bind/rebase %s:%s",
1714+ s1->sections[mo->bind_rebase[i].section]->name, name);
1715+ }
1716+ header = (struct dyld_chained_fixups_header *) data;
1717+ data += (sizeof(struct dyld_chained_fixups_header) + 7) & -8;
1718+ header->starts_offset = data - mo->chained_fixups->data;
1719+ header->imports_count = mo->n_bind;
1720+ header->imports_format = DYLD_CHAINED_IMPORT;
1721+ header->symbols_format = 0;
1722+ size = sizeof(struct dyld_chained_starts_in_image) +
1723+ (mo->nseg - 1) * sizeof(uint32_t);
1724+ image = (struct dyld_chained_starts_in_image *) data;
1725+ data += (size + 7) & -8;
1726+ image->seg_count = mo->nseg;
1727+ for (i = 1; i < mo->nseg - 1; i++) {
1728+ image->seg_info_offset[i] = (data - mo->chained_fixups->data) -
1729+ header->starts_offset;
1730+ seg = get_segment(mo, i);
1731+ page_count = (seg->vmsize + SEG_PAGE_SIZE - 1) / SEG_PAGE_SIZE;
1732+ size = sizeof(struct dyld_chained_starts_in_segment) +
1733+ (page_count - 1) * sizeof(uint16_t);
1734+ segment = (struct dyld_chained_starts_in_segment *) data;
1735+ data += (size + 7) & -8;
1736+ segment->size = size;
1737+ segment->page_size = SEG_PAGE_SIZE;
1738+#if 1
1739+#define PTR_64_OFFSET 0
1740+#define PTR_64_MASK 0x7FFFFFFFFFFULL
1741+ segment->pointer_format = DYLD_CHAINED_PTR_64;
1742+#else
1743+#define PTR_64_OFFSET 0x100000000ULL
1744+#define PTR_64_MASK 0xFFFFFFFFFFFFFFULL
1745+ segment->pointer_format = DYLD_CHAINED_PTR_64_OFFSET;
1746+#endif
1747+ segment->segment_offset = seg->fileoff;
1748+ segment->max_valid_pointer = 0;
1749+ segment->page_count = page_count;
1750+ // add bind/rebase
1751+ for (j = 0; j < page_count; j++) {
1752+ uint64_t start = seg->vmaddr + j * SEG_PAGE_SIZE;
1753+ uint64_t end = start + SEG_PAGE_SIZE;
1754+ void *last;
1755+ addr_t last_o = 0;
1756+ uint64_t cur_o, cur;
1757+ struct dyld_chained_ptr_64_rebase *rebase;
1758+ struct dyld_chained_ptr_64_bind *bind;
1759+ Section *s;
1760+
1761+ segment->page_start[j] = DYLD_CHAINED_PTR_START_NONE;
1762+ for (k = 0, bind_index = 0; k < mo->n_bind_rebase; k++) {
1763+ uint64_t addr;
1764+
1765+ s = s1->sections[mo->bind_rebase[k].section];
1766+ rel = mo->bind_rebase[k].rel;
1767+ if ((rel.r_offset & 3) ||
1768+ (rel.r_offset & (SEG_PAGE_SIZE - 1)) >
1769+ SEG_PAGE_SIZE - PTR_SIZE)
1770+ tcc_error("Illegal rel_offset %s %lld",
1771+ s->name, (long long)rel.r_offset);
1772+ addr = s->sh_addr + rel.r_offset;
1773+ if (addr >= start && addr < end) {
1774+ cur_o = addr - start;
1775+ if (mo->bind_rebase[k].bind) {
1776+ if (segment->page_start[j] == DYLD_CHAINED_PTR_START_NONE)
1777+ segment->page_start[j] = cur_o;
1778+ else {
1779+ bind = (struct dyld_chained_ptr_64_bind *) last;
1780+ bind->next = (cur_o - last_o) / 4;
1781+ }
1782+ bind = (struct dyld_chained_ptr_64_bind *)
1783+ (s->data + rel.r_offset);
1784+ last = bind;
1785+ last_o = cur_o;
1786+ bind->ordinal = bind_index;
1787+ bind->addend = 0;
1788+ bind->reserved = 0;
1789+ bind->next = 0;
1790+ bind->bind = 1;
1791+ }
1792+ else {
1793+ if (segment->page_start[j] == DYLD_CHAINED_PTR_START_NONE)
1794+ segment->page_start[j] = cur_o;
1795+ else {
1796+ rebase = (struct dyld_chained_ptr_64_rebase *) last;
1797+ rebase->next = (cur_o - last_o) / 4;
1798+ }
1799+ rebase = (struct dyld_chained_ptr_64_rebase *)
1800+ (s->data + rel.r_offset);
1801+ last = rebase;
1802+ last_o = cur_o;
1803+ cur = (*(uint64_t *) (s->data + rel.r_offset)) -
1804+ PTR_64_OFFSET;
1805+ rebase->target = cur & PTR_64_MASK;
1806+ rebase->high8 = cur >> (64 - 8);
1807+ if (cur != ((uint64_t)rebase->high8 << (64 - 8)) + rebase->target)
1808+ tcc_error("rebase error");
1809+ rebase->reserved = 0;
1810+ rebase->next = 0;
1811+ rebase->bind = 0;
1812+ }
1813+ }
1814+ bind_index += mo->bind_rebase[k].bind;
1815+ }
1816+ }
1817+ }
1818+ // add imports
1819+ header->imports_offset = data - mo->chained_fixups->data;
1820+ import = (struct dyld_chained_import *) data;
1821+ data += mo->n_bind * sizeof (struct dyld_chained_import);
1822+ header->symbols_offset = data - mo->chained_fixups->data;
1823+ data++;
1824+ for (i = 0, bind_index = 0; i < mo->n_bind_rebase; i++) {
1825+ if (mo->bind_rebase[i].bind) {
1826+ import[bind_index].lib_ordinal =
1827+ BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xffu;
1828+ import[bind_index].name_offset =
1829+ (data - mo->chained_fixups->data) - header->symbols_offset;
1830+ sym_index = ELFW(R_SYM)(mo->bind_rebase[i].rel.r_info);
1831+ sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1832+ import[bind_index].weak_import =
1833+ ELFW(ST_BIND)(sym->st_info) == STB_WEAK;
1834+ name = (char *) symtab_section->link->data + sym->st_name;
1835+ strcpy(data, name);
1836+ data += strlen(name) + 1;
1837+ bind_index++;
1838+ }
1839+ }
1840+ tcc_free(mo->bind_rebase);
1841+}
1842+#endif
1843+
13361844 ST_FUNC int macho_output_file(TCCState *s1, const char *filename)
13371845 {
13381846 int fd, mode, file_type;
@@ -1370,6 +1878,9 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 31 unmodified lines
13701878 if (s1->nb_errors)
13711879 goto do_ret;
13721880 relocate_sections(s1);
1881+#ifdef CONFIG_NEW_MACHO
1882+ bind_rebase_import(s1, &mo);
1883+#endif
13731884 convert_symbols(s1, &mo);
13741885 macho_write(s1, &mo, fp);
13751886 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t