History

Add dll support for macho

Update configure and remove dll=no for Darwin. Also removed dwarf=$dwarf because this is not a config option. In tccelf.c only add __PAGEZERO if stabs and executable. In tccrun.c correct rt_printline_dwarf code for dll. In tests/Makefile disable dlltest with PIC for Darwin because object format of .o file is still in elf. In tccmacho.c add dll support and and rpath support. Corrected trie code. For some reason symbol 'xx' should be after 'xx1'. Corrected weak symbol support for old macho code. Used R_JMP_SLOT instead of R_DATA_PTR in check_relocs.

herman ten brugge committed 3 years ago

Commit 8d3930b1 parent 9cfc8f65 files · +117 −52Browse files

Unified · Split

5 files
  1. configure +1 −1
  2. tccelf.c +3 −2
  3. tccmacho.c +107 −46
  4. tccrun.c +5 −2
  5. tests/Makefile +1 −1
configure+1−1
@@ -66,7 +66,7 @@ case $targetos in · 65 unmodified lines
6666 Darwin)
6767 darwin=yes
6868 dwarf=4
69− confvars="$confvars OSX dll=no dwarf=$dwarf"
69+ confvars="$confvars OSX"
7070 cc=`which cc`
7171 cc=`readlink $cc || echo clang`
7272 tcc_usrinclude="`xcrun --show-sdk-path`/usr/include"
tccelf.c+3−2
@@ -1580,8 +1580,9 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 1579 unmodified lines
15801580 put_ptr(s1, NULL, 0);
15811581 #if defined TCC_TARGET_MACHO
15821582 /* adjust for __PAGEZERO */
1583− write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1584− (uint64_t)1 << 32);
1583+ if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE)
1584+ write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1585+ (uint64_t)1 << 32);
15851586 #endif
15861587 n = 2 * PTR_SIZE;
15871588 #ifdef CONFIG_TCC_BCHECK
tccmacho.c+107−46
@@ -40,6 +40,7 @@ · 39 unmodified lines
4040
4141 #define MH_EXECUTE (0x2)
4242 #define MH_DYLDLINK (0x4)
43+#define MH_DYLIB (0x6)
4344 #define MH_PIE (0x200000)
4445
4546 #define CPU_SUBTYPE_LIB64 (0x80000000)
@@ -104,6 +105,7 @@ struct load_command { · 58 unmodified lines
104105 #define LC_ID_DYLIB 0xd
105106 #define LC_LOAD_DYLINKER 0xe
106107 #define LC_SEGMENT_64 0x19
108+#define LC_RPATH (0x1c | LC_REQ_DYLD)
107109 #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
108110 #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)
109111 #define LC_MAIN (0x28|LC_REQ_DYLD)
@@ -243,6 +245,12 @@ struct dylib_command { · 133 unmodified lines
243245 uint32_t compatibility_version; /* library's compatibility vers number*/
244246 };
245247
248+struct rpath_command {
249+ uint32_t cmd; /* LC_RPATH */
250+ uint32_t cmdsize; /* includes string */
251+ lc_str path; /* path to add to run path */
252+};
253+
246254 struct dylinker_command {
247255 uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or
248256 LC_DYLD_ENVIRONMENT */
@@ -327,6 +335,8 @@ struct dysymtab_command { · 78 unmodified lines
327335 #define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70
328336 #define BIND_OPCODE_DO_BIND 0x90
329337
338+#define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1
339+
330340 #define BIND_TYPE_POINTER 1
331341 #define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2
332342
@@ -653,13 +663,12 @@ static void bind_rebase_add(struct macho *mo, int bind, int sh_info, · 320 unmodified lines
653663 static void check_relocs(TCCState *s1, struct macho *mo)
654664 {
655665 Section *s;
656− ElfW_Rel *rel;
666+ ElfW_Rel *rel, save_rel;
657667 ElfW(Sym) *sym;
658668 int i, type, gotplt_entry, sym_index, for_code;
659669 uint32_t *pi, *goti;
660670 struct sym_attr *attr;
661671
662− mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
663672 goti = NULL;
664673 mo->nr_plt = mo->n_got = 0;
665674 for (i = 1; i < s1->nb_sections; i++) {
@@ -668,6 +677,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 2 unmodified lines
668677 !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))
669678 continue;
670679 for_each_elem(s, 0, rel, ElfW_Rel) {
680+ save_rel = *rel;
671681 type = ELFW(R_TYPE)(rel->r_info);
672682 gotplt_entry = gotplt_entry_type(type);
673683 for_code = code_reloc(type);
@@ -685,7 +695,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 11 unmodified lines
685695 attr->dyn_index = 1; /* used as flag */
686696 section_ptr_add(s1->got, PTR_SIZE);
687697 put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
688− R_DATA_PTR, sym_index);
698+ R_JMP_SLOT, sym_index);
689699 goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));
690700 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
691701 if (sym->st_shndx == SHN_UNDEF)
@@ -701,7 +711,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 9 unmodified lines
701711 && type == R_AARCH64_ADR_GOT_PAGE
702712 #endif
703713 ) {
704− bind_rebase_add(mo, 1, s1->got->reloc->sh_info, rel, attr);
714+ bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr);
705715 attr->plt_offset = 0; // ignore next bind
706716 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
707717 }
@@ -740,7 +750,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 32 unmodified lines
740750 write32le(jmp + 8, // br x16
741751 0xd61f0200);
742752 #endif
743− bind_rebase_add(mo, 1, s1->got->reloc->sh_info, rel, attr);
753+ bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr);
744754 pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
745755 *pi = mo->e2msym[sym_index];
746756 mo->nr_plt++;
@@ -749,9 +759,9 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 2 unmodified lines
749759 rel->r_addend += attr->plt_offset;
750760 }
751761 }
752− if (type == R_DATA_PTR)
762+ if (type == R_DATA_PTR || type == R_JMP_SLOT)
753763 bind_rebase_add(mo, sym->st_shndx == SHN_UNDEF ? 1 : 0,
754− s->sh_info, rel, NULL);
764+ s->sh_info, &save_rel, NULL);
755765 }
756766 }
757767 pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi));
@@ -765,15 +775,13 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 7 unmodified lines
765775 {
766776 uint8_t *jmp;
767777 Section *s;
768− ElfW_Rel *rel;
778+ ElfW_Rel *rel, save_rel;
769779 ElfW(Sym) *sym;
770780 int i, type, gotplt_entry, sym_index, for_code;
771781 int bind_offset, la_symbol_offset;
772782 uint32_t *pi, *goti;
773783 struct sym_attr *attr;
774784
775− mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
776−
777785 #ifdef TCC_TARGET_X86_64
778786 jmp = section_ptr_add(mo->stub_helper, 16);
779787 jmp[0] = 0x4c; /* leaq _dyld_private(%rip), %r11 */
@@ -814,6 +822,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 34 unmodified lines
814822 !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))
815823 continue;
816824 for_each_elem(s, 0, rel, ElfW_Rel) {
825+ save_rel = *rel;
817826 type = ELFW(R_TYPE)(rel->r_info);
818827 gotplt_entry = gotplt_entry_type(type);
819828 for_code = code_reloc(type);
@@ -831,7 +840,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 11 unmodified lines
831840 attr->dyn_index = 1; /* used as flag */
832841 section_ptr_add(s1->got, PTR_SIZE);
833842 put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
834− R_DATA_PTR, sym_index);
843+ R_JMP_SLOT, sym_index);
835844 goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));
836845 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
837846 if (sym->st_shndx == SHN_UNDEF)
@@ -852,7 +861,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 14 unmodified lines
852861 (mo->n_bind + 1) *
853862 sizeof(struct bind));
854863 mo->bind[mo->n_bind].section = s1->got->reloc->sh_info;
855− mo->bind[mo->n_bind].rel = *rel;
864+ mo->bind[mo->n_bind].rel = save_rel;
856865 mo->bind[mo->n_bind].rel.r_offset = attr->got_offset;
857866 mo->n_bind++;
858867 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
@@ -936,7 +945,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 77 unmodified lines
936945 bind_offset;
937946 mo->s_lazy_bind[mo->n_lazy_bind].la_symbol_offset =
938947 la_symbol_offset;
939− mo->s_lazy_bind[mo->n_lazy_bind].rel = *rel;
948+ mo->s_lazy_bind[mo->n_lazy_bind].rel = save_rel;
940949 mo->s_lazy_bind[mo->n_lazy_bind].rel.r_offset =
941950 attr->plt_offset;
942951 mo->n_lazy_bind++;
@@ -948,13 +957,13 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 5 unmodified lines
948957 rel->r_addend += attr->plt_offset;
949958 }
950959 }
951− if (type == R_DATA_PTR) {
960+ if (type == R_DATA_PTR || type == R_JMP_SLOT) {
952961 if (sym->st_shndx == SHN_UNDEF) {
953962 mo->bind = tcc_realloc(mo->bind,
954963 (mo->n_bind + 1) *
955964 sizeof(struct bind));
956965 mo->bind[mo->n_bind].section = s->sh_info;
957− mo->bind[mo->n_bind].rel = *rel;
966+ mo->bind[mo->n_bind].rel = save_rel;
958967 mo->n_bind++;
959968 }
960969 else {
@@ -962,7 +971,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 1 unmodified line
962971 tcc_realloc(mo->s_rebase, (mo->n_rebase + 1) *
963972 sizeof(struct s_rebase));
964973 mo->s_rebase[mo->n_rebase].section = s->sh_info;
965− mo->s_rebase[mo->n_rebase].rel = *rel;
974+ mo->s_rebase[mo->n_rebase].rel = save_rel;
966975 mo->n_rebase++;
967976 }
968977 }
@@ -1008,6 +1017,7 @@ static int check_symbols(TCCState *s1, struct macho *mo) · 39 unmodified lines
10081017 if (mo->iundef == -1)
10091018 mo->iundef = sym_index - 1;
10101019 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK
1020+ || s1->output_type != TCC_OUTPUT_EXE
10111021 || find_elf_sym(s1->dynsymtab_section, name)) {
10121022 /* Mark the symbol as coming from a dylib so that
10131023 relocate_syms doesn't complain. Normally bind_exe_dynsyms
@@ -1170,6 +1180,7 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 156 unmodified lines
11701180 mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
11711181 #endif
11721182 mo->exports = new_section(s1, "EXPORT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
1183+ mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
11731184
11741185 mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
11751186 mo->strtab = new_section(s1, "LESTRTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
@@ -1182,6 +1193,7 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 6 unmodified lines
11821193 pn[sym_index - 1].n_strx = put_elf_str(mo->strtab, name);
11831194 pn[sym_index - 1].n_value = sym_index;
11841195 }
1196+ section_ptr_add(mo->strtab, -mo->strtab->data_offset & (PTR_SIZE - 1));
11851197 tcc_qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp, s1);
11861198 mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym));
11871199 mo->e2msym[0] = -1;
@@ -1250,7 +1262,7 @@ static void calc_fixup_size(TCCState *s1, struct macho *mo) · 62 unmodified lines
12501262
12511263 size = (sizeof(struct dyld_chained_fixups_header) + 7) & -8;
12521264 size += (sizeof(struct dyld_chained_starts_in_image) + (mo->nseg - 1) * sizeof(uint32_t) + 7) & -8;
1253− for (i = 1; i < mo->nseg - 1; i++) {
1265+ for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) {
12541266 int page_count = (get_segment(mo, i)->vmsize + SEG_PAGE_SIZE - 1) / SEG_PAGE_SIZE;
12551267 size += (sizeof(struct dyld_chained_starts_in_segment) + (page_count - 1) * sizeof(uint16_t) + 7) & -8;
12561268 }
@@ -1269,14 +1281,14 @@ static void calc_fixup_size(TCCState *s1, struct macho *mo) · 12 unmodified lines
12691281
12701282 #else
12711283
1272−static void set_segment_and_offset(struct macho *mo, addr_t addr,
1284+static void set_segment_and_offset(TCCState *s1, struct macho *mo, addr_t addr,
12731285 uint8_t *ptr, int opcode,
12741286 Section *sec, addr_t offset)
12751287 {
12761288 int i;
12771289 struct segment_command_64 *seg = NULL;
12781290
1279− for (i = 1; i < mo->nseg - 1; i++) {
1291+ for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) {
12801292 seg = get_segment(mo, i);
12811293 if (addr >= seg->vmaddr && addr < (seg->vmaddr + seg->vmsize))
12821294 break;
@@ -1301,7 +1313,7 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 18 unmodified lines
13011313 mo->s_lazy_bind[i].bind_offset,
13021314 mo->lazy_binding->data_offset);
13031315 ptr = section_ptr_add(mo->lazy_binding, 1);
1304− set_segment_and_offset(mo, mo->la_symbol_ptr->sh_addr, ptr,
1316+ set_segment_and_offset(s1, mo, mo->la_symbol_ptr->sh_addr, ptr,
13051317 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
13061318 mo->lazy_binding,
13071319 mo->s_lazy_bind[i].la_symbol_offset +
@@ -1320,7 +1332,7 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 12 unmodified lines
13201332
13211333 ptr = section_ptr_add(mo->rebase, 2);
13221334 *ptr++ = REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER;
1323− set_segment_and_offset(mo, s->sh_addr, ptr,
1335+ set_segment_and_offset(s1, mo, s->sh_addr, ptr,
13241336 REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
13251337 mo->rebase,
13261338 mo->s_rebase[i].rel.r_offset +
@@ -1337,14 +1349,18 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 10 unmodified lines
13371349 name = (char *) symtab_section->link->data + sym->st_name;
13381350 binding = ELFW(ST_BIND)(sym->st_info) == STB_WEAK
13391351 ? mo->weak_binding : mo->binding;
1340− ptr = section_ptr_add(binding, 5 + strlen(name));
1341− *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
1342− (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
1343− *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;
1352+ ptr = section_ptr_add(binding, 4 + (binding == mo->binding) +
1353+ strlen(name));
1354+ if (binding == mo->binding)
1355+ *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
1356+ (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
1357+ *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM |
1358+ (binding == mo->weak_binding
1359+ ? BIND_SYMBOL_FLAGS_WEAK_IMPORT : 0);
13441360 strcpy((char *)ptr, name);
13451361 ptr += strlen(name) + 1;
13461362 *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER;
1347− set_segment_and_offset(mo, s->sh_addr, ptr,
1363+ set_segment_and_offset(s1, mo, s->sh_addr, ptr,
13481364 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
13491365 binding,
13501366 mo->bind[i].rel.r_offset + s->sh_addr);
@@ -1488,7 +1504,12 @@ static int triecmp(const void *_a, const void *_b, void *arg) · 137 unmodified lines
14881504 {
14891505 struct trie_info *a = (struct trie_info *) _a;
14901506 struct trie_info *b = (struct trie_info *) _b;
1507+ int len_a = strlen(a->name);
1508+ int len_b = strlen(b->name);
14911509
1510+ /* strange sorting needed. Name 'xx' should be after 'xx1' */
1511+ if (!strncmp(a->name, b->name, len_a < len_b ? len_a : len_b))
1512+ return len_a < len_b ? 1 : (len_a > len_b ? -1 : 0);
14921513 return strcmp(a->name, b->name);
14931514 }
14941515
@@ -1502,7 +1523,7 @@ static void export_trie(TCCState *s1, struct macho *mo) · 7 unmodified lines
15021523 struct trie_info *trie = NULL, *p_trie;
15031524 struct trie_node node, *p_node;
15041525 struct trie_seq *seq = NULL;
1505− addr_t vm_addr = get_segment(mo, 1)->vmaddr;
1526+ addr_t vm_addr = get_segment(mo, s1->output_type == TCC_OUTPUT_EXE)->vmaddr;
15061527
15071528 for (sym_index = 1; sym_index < sym_end; ++sym_index) {
15081529 ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
@@ -1576,19 +1597,21 @@ static void export_trie(TCCState *s1, struct macho *mo) · 67 unmodified lines
15761597 tcc_free(trie);
15771598 }
15781599
1579−static void collect_sections(TCCState *s1, struct macho *mo)
1600+static void collect_sections(TCCState *s1, struct macho *mo, const char *filename)
15801601 {
15811602 int i, sk, numsec;
15821603 int used_segment[N_SEGMENT];
15831604 uint64_t curaddr, fileofs;
15841605 Section *s;
15851606 struct segment_command_64 *seg;
1607+ struct dylib_command *dylib;
15861608 #ifdef CONFIG_NEW_MACHO
15871609 struct linkedit_data_command *chained_fixups_lc;
15881610 struct linkedit_data_command *export_trie_lc;
15891611 #endif
15901612 struct build_version_command *dyldbv;
15911613 struct source_version_command *dyldsv;
1614+ struct rpath_command *rpath;
15921615 struct dylinker_command *dyldlc;
15931616 struct symtab_command *symlc;
15941617 struct dysymtab_command *dysymlc;
@@ -1662,10 +1685,16 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 67 unmodified lines
16621685 used_segment[skinfo[sk].seg_initial] = 1;
16631686 }
16641687
1688+ if (s1->output_type != TCC_OUTPUT_EXE)
1689+ used_segment[0] = 0;
1690+
16651691 for (i = 0; i < N_SEGMENT; i++)
16661692 if (used_segment[i]) {
16671693 seg = add_segment(mo, all_segment[i].name);
1668− seg->vmaddr = all_segment[i].vmaddr;
1694+ if (i == 1 && s1->output_type != TCC_OUTPUT_EXE)
1695+ seg->vmaddr = 0;
1696+ else
1697+ seg->vmaddr = all_segment[i].vmaddr;
16691698 seg->vmsize = all_segment[i].vmsize;
16701699 seg->maxprot = all_segment[i].maxprot;
16711700 seg->initprot = all_segment[i].initprot;
@@ -1675,6 +1704,17 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 3 unmodified lines
16751704 mo->segment[sk] = mo->nseg - 1;
16761705 }
16771706
1707+ if (s1->output_type != TCC_OUTPUT_EXE) {
1708+ i = (sizeof(*dylib) + strlen(filename) + 1 + 7) &-8;
1709+ dylib = add_lc(mo, LC_ID_DYLIB, i);
1710+ dylib->name = sizeof(*dylib);
1711+ dylib->timestamp = 1;
1712+ dylib->current_version = 1 << 16;
1713+ dylib->compatibility_version = 1 << 16;
1714+ str = (char*)dylib + dylib->name;
1715+ strcpy(str, filename);
1716+ }
1717+
16781718 #ifdef CONFIG_NEW_MACHO
16791719 chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS,
16801720 sizeof(struct linkedit_data_command));
@@ -1687,11 +1727,13 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 6 unmodified lines
16871727 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));
16881728 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));
16891729
1690− i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8;
1691− dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i);
1692− dyldlc->name = sizeof(*dyldlc);
1693− str = (char*)dyldlc + dyldlc->name;
1694− strcpy(str, "/usr/lib/dyld");
1730+ if (s1->output_type == TCC_OUTPUT_EXE) {
1731+ i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8;
1732+ dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i);
1733+ dyldlc->name = sizeof(*dyldlc);
1734+ str = (char*)dyldlc + dyldlc->name;
1735+ strcpy(str, "/usr/lib/dyld");
1736+ }
16951737
16961738 dyldbv = add_lc(mo, LC_BUILD_VERSION, sizeof(*dyldbv));
16971739 dyldbv->platform = PLATFORM_MACOS;
@@ -1702,8 +1744,10 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 4 unmodified lines
17021744 dyldsv = add_lc(mo, LC_SOURCE_VERSION, sizeof(*dyldsv));
17031745 dyldsv->version = 0;
17041746
1705− mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));
1706− mo->ep->entryoff = 4096;
1747+ if (s1->output_type == TCC_OUTPUT_EXE) {
1748+ mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));
1749+ mo->ep->entryoff = 4096;
1750+ }
17071751
17081752 for(i = 0; i < s1->nb_loaded_dlls; i++) {
17091753 DLLReference *dllref = s1->loaded_dlls[i];
@@ -1711,13 +1755,21 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 1 unmodified line
17111755 add_dylib(mo, dllref->name);
17121756 }
17131757
1758+ if (s1->rpath) {
1759+ i = (sizeof(*rpath) + strlen(s1->rpath) + 1 + 7) &-8;
1760+ rpath = add_lc(mo, LC_RPATH, i);
1761+ rpath->path = sizeof(*rpath);
1762+ str = (char*)rpath + rpath->path;
1763+ strcpy(str, s1->rpath);
1764+ }
1765+
17141766 fileofs = 4096; /* leave space for mach-o headers */
1715− curaddr = get_segment(mo, 1)->vmaddr;
1767+ curaddr = get_segment(mo, s1->output_type == TCC_OUTPUT_EXE)->vmaddr;
17161768 curaddr += 4096;
17171769 seg = NULL;
17181770 numsec = 0;
17191771 mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections);
1720− for (sk = sk_unknown; sk < sk_last; sk++) {
1772+ for (sk = sk_text; sk < sk_last; sk++) {
17211773 struct section_64 *sec = NULL;
17221774 if (seg) {
17231775 seg->vmsize = curaddr - seg->vmaddr;
@@ -1734,7 +1786,8 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 10 unmodified lines
17341786 export_trie(s1, mo);
17351787 }
17361788 #endif
1737− if (mo->segment[sk] && mo->sk_to_sect[sk].s) {
1789+ if ((s1->output_type != TCC_OUTPUT_EXE || mo->segment[sk]) &&
1790+ mo->sk_to_sect[sk].s) {
17381791 uint64_t al = 0;
17391792 int si;
17401793 seg = get_segment(mo, mo->segment[sk]);
@@ -1889,8 +1942,14 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) · 148 unmodified lines
18891942 mo->mh.mh.cputype = CPU_TYPE_ARM64;
18901943 mo->mh.mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL;
18911944 #endif
1892− mo->mh.mh.filetype = MH_EXECUTE;
1893− mo->mh.mh.flags = MH_DYLDLINK | MH_PIE;
1945+ if (s1->output_type == TCC_OUTPUT_EXE) {
1946+ mo->mh.mh.filetype = MH_EXECUTE;
1947+ mo->mh.mh.flags = MH_DYLDLINK | MH_PIE;
1948+ }
1949+ else {
1950+ mo->mh.mh.filetype = MH_DYLIB;
1951+ mo->mh.mh.flags = MH_DYLDLINK;
1952+ }
18941953 mo->mh.mh.ncmds = mo->nlc;
18951954 mo->mh.mh.sizeofcmds = 0;
18961955 for (i = 0; i < mo->nlc; i++)
@@ -1905,7 +1964,8 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) · 8 unmodified lines
19051964
19061965 for (sk = sk_unknown; sk < sk_last; sk++) {
19071966 //struct segment_command_64 *seg;
1908− if (!mo->segment[sk] || !mo->sk_to_sect[sk].s)
1967+ if ((s1->output_type == TCC_OUTPUT_EXE && !mo->segment[sk]) ||
1968+ !mo->sk_to_sect[sk].s)
19091969 continue;
19101970 /*seg =*/ get_segment(mo, mo->segment[sk]);
19111971 for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
@@ -1969,7 +2029,7 @@ ST_FUNC void bind_rebase_import(TCCState *s1, struct macho *mo) · 57 unmodified lines
19692029 image = (struct dyld_chained_starts_in_image *) data;
19702030 data += (size + 7) & -8;
19712031 image->seg_count = mo->nseg;
1972− for (i = 1; i < mo->nseg - 1; i++) {
2032+ for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) {
19732033 image->seg_info_offset[i] = (data - mo->chained_fixups->data) -
19742034 header->starts_offset;
19752035 seg = get_segment(mo, i);
@@ -2117,10 +2177,11 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 141 unmodified lines
21172177 check_relocs(s1, &mo);
21182178 ret = check_symbols(s1, &mo);
21192179 if (!ret) {
2120− collect_sections(s1, &mo);
2180+ collect_sections(s1, &mo, filename);
21212181 relocate_syms(s1, s1->symtab, 0);
2122− mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1)
2123− - get_segment(&mo, 1)->vmaddr;
2182+ if (s1->output_type == TCC_OUTPUT_EXE)
2183+ mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1)
2184+ - get_segment(&mo, 1)->vmaddr;
21242185 if (s1->nb_errors)
21252186 goto do_ret;
21262187 relocate_sections(s1);
tccrun.c+5−2
@@ -772,7 +772,7 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, · 771 unmodified lines
772772 addr_t last_pc;
773773 addr_t pc;
774774 #if defined TCC_TARGET_MACHO
775− addr_t first_pc = 0;
775+ addr_t first_pc;
776776 #endif
777777 addr_t func_addr;
778778 int line;
@@ -782,6 +782,9 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, · 3 unmodified lines
782782 next:
783783 ln = rc->dwarf_line;
784784 while (ln < rc->dwarf_line_end) {
785+#if defined TCC_TARGET_MACHO
786+ first_pc = 0;
787+#endif
785788 dir_size = 0;
786789 filename_size = 0;
787790 last_pc = 0;
@@ -935,7 +938,7 @@ check_pc: · 147 unmodified lines
935938 #endif
936939 #if defined TCC_TARGET_MACHO
937940 if (first_pc == 0 && rc->prog_base != (addr_t) -1)
938− first_pc += rc->prog_base - ((uint64_t)1 << 32);
941+ first_pc += rc->prog_base;
939942 pc += first_pc;
940943 #endif
941944 opindex = 0;
tests/Makefile+1−1
@@ -158,7 +158,7 @@ dlltest: · 157 unmodified lines
158158 $(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF)
159159 $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
160160 ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
161−ifndef CONFIG_WIN32
161+ifeq (,$(filter Darwin WIN32,$(TARGETOS)))
162162 @echo ------------ $@ with PIC ------------
163163 $(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c
164164 $(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF)

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