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
66 Darwin)66 Darwin)
67 darwin=yes67 darwin=yes
68 dwarf=468 dwarf=4
69 confvars="$confvars OSX dll=no dwarf=$dwarf"69 confvars="$confvars OSX"
70 cc=`which cc`70 cc=`which cc`
71 cc=`readlink $cc || echo clang`71 cc=`readlink $cc || echo clang`
72 tcc_usrinclude="`xcrun --show-sdk-path`/usr/include"72 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
1580 put_ptr(s1, NULL, 0);1580 put_ptr(s1, NULL, 0);
1581#if defined TCC_TARGET_MACHO1581#if defined TCC_TARGET_MACHO
1582 /* adjust for __PAGEZERO */1582 /* adjust for __PAGEZERO */
1583 write64le(data_section->data + data_section->data_offset - PTR_SIZE,1583 if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE)
1584 (uint64_t)1 << 32);1584 write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1585 (uint64_t)1 << 32);
1585#endif1586#endif
1586 n = 2 * PTR_SIZE;1587 n = 2 * PTR_SIZE;
1587#ifdef CONFIG_TCC_BCHECK1588#ifdef CONFIG_TCC_BCHECK
tccmacho.c+107−46
@@ -40,6 +40,7 @@ · 39 unmodified lines
40 40
41#define MH_EXECUTE (0x2)41#define MH_EXECUTE (0x2)
42#define MH_DYLDLINK (0x4)42#define MH_DYLDLINK (0x4)
43#define MH_DYLIB (0x6)
43#define MH_PIE (0x200000)44#define MH_PIE (0x200000)
44 45
45#define CPU_SUBTYPE_LIB64 (0x80000000)46#define CPU_SUBTYPE_LIB64 (0x80000000)
@@ -104,6 +105,7 @@ struct load_command { · 58 unmodified lines
104#define LC_ID_DYLIB 0xd105#define LC_ID_DYLIB 0xd
105#define LC_LOAD_DYLINKER 0xe106#define LC_LOAD_DYLINKER 0xe
106#define LC_SEGMENT_64 0x19107#define LC_SEGMENT_64 0x19
108#define LC_RPATH (0x1c | LC_REQ_DYLD)
107#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)109#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD)
108#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)110#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)
109#define LC_MAIN (0x28|LC_REQ_DYLD)111#define LC_MAIN (0x28|LC_REQ_DYLD)
@@ -243,6 +245,12 @@ struct dylib_command { · 133 unmodified lines
243 uint32_t compatibility_version; /* library's compatibility vers number*/245 uint32_t compatibility_version; /* library's compatibility vers number*/
244};246};
245 247
248struct 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
246struct dylinker_command {254struct dylinker_command {
247 uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or255 uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or
248 LC_DYLD_ENVIRONMENT */256 LC_DYLD_ENVIRONMENT */
@@ -327,6 +335,8 @@ struct dysymtab_command { · 78 unmodified lines
327#define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70335#define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70
328#define BIND_OPCODE_DO_BIND 0x90336#define BIND_OPCODE_DO_BIND 0x90
329 337
338#define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1
339
330#define BIND_TYPE_POINTER 1340#define BIND_TYPE_POINTER 1
331#define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2341#define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2
332 342
@@ -653,13 +663,12 @@ static void bind_rebase_add(struct macho *mo, int bind, int sh_info, · 320 unmodified lines
653static void check_relocs(TCCState *s1, struct macho *mo)663static void check_relocs(TCCState *s1, struct macho *mo)
654{664{
655 Section *s;665 Section *s;
656 ElfW_Rel *rel;666 ElfW_Rel *rel, save_rel;
657 ElfW(Sym) *sym;667 ElfW(Sym) *sym;
658 int i, type, gotplt_entry, sym_index, for_code;668 int i, type, gotplt_entry, sym_index, for_code;
659 uint32_t *pi, *goti;669 uint32_t *pi, *goti;
660 struct sym_attr *attr;670 struct sym_attr *attr;
661 671
662 mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
663 goti = NULL;672 goti = NULL;
664 mo->nr_plt = mo->n_got = 0;673 mo->nr_plt = mo->n_got = 0;
665 for (i = 1; i < s1->nb_sections; i++) {674 for (i = 1; i < s1->nb_sections; i++) {
@@ -668,6 +677,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 2 unmodified lines
668 !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))677 !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))
669 continue;678 continue;
670 for_each_elem(s, 0, rel, ElfW_Rel) {679 for_each_elem(s, 0, rel, ElfW_Rel) {
680 save_rel = *rel;
671 type = ELFW(R_TYPE)(rel->r_info);681 type = ELFW(R_TYPE)(rel->r_info);
672 gotplt_entry = gotplt_entry_type(type);682 gotplt_entry = gotplt_entry_type(type);
673 for_code = code_reloc(type);683 for_code = code_reloc(type);
@@ -685,7 +695,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 11 unmodified lines
685 attr->dyn_index = 1; /* used as flag */695 attr->dyn_index = 1; /* used as flag */
686 section_ptr_add(s1->got, PTR_SIZE);696 section_ptr_add(s1->got, PTR_SIZE);
687 put_elf_reloc(s1->symtab, s1->got, attr->got_offset,697 put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
688 R_DATA_PTR, sym_index);698 R_JMP_SLOT, sym_index);
689 goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));699 goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));
690 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {700 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
691 if (sym->st_shndx == SHN_UNDEF)701 if (sym->st_shndx == SHN_UNDEF)
@@ -701,7 +711,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 9 unmodified lines
701 && type == R_AARCH64_ADR_GOT_PAGE711 && type == R_AARCH64_ADR_GOT_PAGE
702#endif712#endif
703 ) {713 ) {
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);
705 attr->plt_offset = 0; // ignore next bind715 attr->plt_offset = 0; // ignore next bind
706 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);716 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
707 }717 }
@@ -740,7 +750,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 32 unmodified lines
740 write32le(jmp + 8, // br x16750 write32le(jmp + 8, // br x16
741 0xd61f0200);751 0xd61f0200);
742#endif752#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);
744 pi = section_ptr_add(mo->indirsyms, sizeof(*pi));754 pi = section_ptr_add(mo->indirsyms, sizeof(*pi));
745 *pi = mo->e2msym[sym_index];755 *pi = mo->e2msym[sym_index];
746 mo->nr_plt++;756 mo->nr_plt++;
@@ -749,9 +759,9 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 2 unmodified lines
749 rel->r_addend += attr->plt_offset;759 rel->r_addend += attr->plt_offset;
750 }760 }
751 }761 }
752 if (type == R_DATA_PTR)762 if (type == R_DATA_PTR || type == R_JMP_SLOT)
753 bind_rebase_add(mo, sym->st_shndx == SHN_UNDEF ? 1 : 0,763 bind_rebase_add(mo, sym->st_shndx == SHN_UNDEF ? 1 : 0,
754 s->sh_info, rel, NULL);764 s->sh_info, &save_rel, NULL);
755 }765 }
756 }766 }
757 pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi));767 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
765{775{
766 uint8_t *jmp;776 uint8_t *jmp;
767 Section *s;777 Section *s;
768 ElfW_Rel *rel;778 ElfW_Rel *rel, save_rel;
769 ElfW(Sym) *sym;779 ElfW(Sym) *sym;
770 int i, type, gotplt_entry, sym_index, for_code;780 int i, type, gotplt_entry, sym_index, for_code;
771 int bind_offset, la_symbol_offset;781 int bind_offset, la_symbol_offset;
772 uint32_t *pi, *goti;782 uint32_t *pi, *goti;
773 struct sym_attr *attr;783 struct sym_attr *attr;
774 784
775 mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
776
777#ifdef TCC_TARGET_X86_64785#ifdef TCC_TARGET_X86_64
778 jmp = section_ptr_add(mo->stub_helper, 16);786 jmp = section_ptr_add(mo->stub_helper, 16);
779 jmp[0] = 0x4c; /* leaq _dyld_private(%rip), %r11 */787 jmp[0] = 0x4c; /* leaq _dyld_private(%rip), %r11 */
@@ -814,6 +822,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 34 unmodified lines
814 !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))822 !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7))
815 continue;823 continue;
816 for_each_elem(s, 0, rel, ElfW_Rel) {824 for_each_elem(s, 0, rel, ElfW_Rel) {
825 save_rel = *rel;
817 type = ELFW(R_TYPE)(rel->r_info);826 type = ELFW(R_TYPE)(rel->r_info);
818 gotplt_entry = gotplt_entry_type(type);827 gotplt_entry = gotplt_entry_type(type);
819 for_code = code_reloc(type);828 for_code = code_reloc(type);
@@ -831,7 +840,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 11 unmodified lines
831 attr->dyn_index = 1; /* used as flag */840 attr->dyn_index = 1; /* used as flag */
832 section_ptr_add(s1->got, PTR_SIZE);841 section_ptr_add(s1->got, PTR_SIZE);
833 put_elf_reloc(s1->symtab, s1->got, attr->got_offset,842 put_elf_reloc(s1->symtab, s1->got, attr->got_offset,
834 R_DATA_PTR, sym_index);843 R_JMP_SLOT, sym_index);
835 goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));844 goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti));
836 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {845 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
837 if (sym->st_shndx == SHN_UNDEF)846 if (sym->st_shndx == SHN_UNDEF)
@@ -852,7 +861,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 14 unmodified lines
852 (mo->n_bind + 1) *861 (mo->n_bind + 1) *
853 sizeof(struct bind));862 sizeof(struct bind));
854 mo->bind[mo->n_bind].section = s1->got->reloc->sh_info;863 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;
856 mo->bind[mo->n_bind].rel.r_offset = attr->got_offset;865 mo->bind[mo->n_bind].rel.r_offset = attr->got_offset;
857 mo->n_bind++;866 mo->n_bind++;
858 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);867 s1->got->reloc->data_offset -= sizeof (ElfW_Rel);
@@ -936,7 +945,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 77 unmodified lines
936 bind_offset;945 bind_offset;
937 mo->s_lazy_bind[mo->n_lazy_bind].la_symbol_offset =946 mo->s_lazy_bind[mo->n_lazy_bind].la_symbol_offset =
938 la_symbol_offset;947 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;
940 mo->s_lazy_bind[mo->n_lazy_bind].rel.r_offset =949 mo->s_lazy_bind[mo->n_lazy_bind].rel.r_offset =
941 attr->plt_offset;950 attr->plt_offset;
942 mo->n_lazy_bind++;951 mo->n_lazy_bind++;
@@ -948,13 +957,13 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 5 unmodified lines
948 rel->r_addend += attr->plt_offset;957 rel->r_addend += attr->plt_offset;
949 }958 }
950 }959 }
951 if (type == R_DATA_PTR) {960 if (type == R_DATA_PTR || type == R_JMP_SLOT) {
952 if (sym->st_shndx == SHN_UNDEF) {961 if (sym->st_shndx == SHN_UNDEF) {
953 mo->bind = tcc_realloc(mo->bind,962 mo->bind = tcc_realloc(mo->bind,
954 (mo->n_bind + 1) *963 (mo->n_bind + 1) *
955 sizeof(struct bind));964 sizeof(struct bind));
956 mo->bind[mo->n_bind].section = s->sh_info;965 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;
958 mo->n_bind++;967 mo->n_bind++;
959 }968 }
960 else {969 else {
@@ -962,7 +971,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 1 unmodified line
962 tcc_realloc(mo->s_rebase, (mo->n_rebase + 1) *971 tcc_realloc(mo->s_rebase, (mo->n_rebase + 1) *
963 sizeof(struct s_rebase));972 sizeof(struct s_rebase));
964 mo->s_rebase[mo->n_rebase].section = s->sh_info;973 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;
966 mo->n_rebase++;975 mo->n_rebase++;
967 }976 }
968 }977 }
@@ -1008,6 +1017,7 @@ static int check_symbols(TCCState *s1, struct macho *mo) · 39 unmodified lines
1008 if (mo->iundef == -1)1017 if (mo->iundef == -1)
1009 mo->iundef = sym_index - 1;1018 mo->iundef = sym_index - 1;
1010 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK1019 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK
1020 || s1->output_type != TCC_OUTPUT_EXE
1011 || find_elf_sym(s1->dynsymtab_section, name)) {1021 || find_elf_sym(s1->dynsymtab_section, name)) {
1012 /* Mark the symbol as coming from a dylib so that1022 /* Mark the symbol as coming from a dylib so that
1013 relocate_syms doesn't complain. Normally bind_exe_dynsyms1023 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
1170 mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);1180 mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
1171#endif1181#endif
1172 mo->exports = new_section(s1, "EXPORT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);1182 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);
1173 1184
1174 mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);1185 mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);
1175 mo->strtab = new_section(s1, "LESTRTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE);1186 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
1182 pn[sym_index - 1].n_strx = put_elf_str(mo->strtab, name);1193 pn[sym_index - 1].n_strx = put_elf_str(mo->strtab, name);
1183 pn[sym_index - 1].n_value = sym_index;1194 pn[sym_index - 1].n_value = sym_index;
1184 }1195 }
1196 section_ptr_add(mo->strtab, -mo->strtab->data_offset & (PTR_SIZE - 1));
1185 tcc_qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp, s1);1197 tcc_qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp, s1);
1186 mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym));1198 mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym));
1187 mo->e2msym[0] = -1;1199 mo->e2msym[0] = -1;
@@ -1250,7 +1262,7 @@ static void calc_fixup_size(TCCState *s1, struct macho *mo) · 62 unmodified lines
1250 1262
1251 size = (sizeof(struct dyld_chained_fixups_header) + 7) & -8;1263 size = (sizeof(struct dyld_chained_fixups_header) + 7) & -8;
1252 size += (sizeof(struct dyld_chained_starts_in_image) + (mo->nseg - 1) * sizeof(uint32_t) + 7) & -8;1264 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++) {
1254 int page_count = (get_segment(mo, i)->vmsize + SEG_PAGE_SIZE - 1) / SEG_PAGE_SIZE;1266 int page_count = (get_segment(mo, i)->vmsize + SEG_PAGE_SIZE - 1) / SEG_PAGE_SIZE;
1255 size += (sizeof(struct dyld_chained_starts_in_segment) + (page_count - 1) * sizeof(uint16_t) + 7) & -8;1267 size += (sizeof(struct dyld_chained_starts_in_segment) + (page_count - 1) * sizeof(uint16_t) + 7) & -8;
1256 }1268 }
@@ -1269,14 +1281,14 @@ static void calc_fixup_size(TCCState *s1, struct macho *mo) · 12 unmodified lines
1269 1281
1270#else1282#else
1271 1283
1272static void set_segment_and_offset(struct macho *mo, addr_t addr,1284static void set_segment_and_offset(TCCState *s1, struct macho *mo, addr_t addr,
1273 uint8_t *ptr, int opcode,1285 uint8_t *ptr, int opcode,
1274 Section *sec, addr_t offset)1286 Section *sec, addr_t offset)
1275{1287{
1276 int i;1288 int i;
1277 struct segment_command_64 *seg = NULL;1289 struct segment_command_64 *seg = NULL;
1278 1290
1279 for (i = 1; i < mo->nseg - 1; i++) {1291 for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) {
1280 seg = get_segment(mo, i);1292 seg = get_segment(mo, i);
1281 if (addr >= seg->vmaddr && addr < (seg->vmaddr + seg->vmsize))1293 if (addr >= seg->vmaddr && addr < (seg->vmaddr + seg->vmsize))
1282 break;1294 break;
@@ -1301,7 +1313,7 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 18 unmodified lines
1301 mo->s_lazy_bind[i].bind_offset,1313 mo->s_lazy_bind[i].bind_offset,
1302 mo->lazy_binding->data_offset);1314 mo->lazy_binding->data_offset);
1303 ptr = section_ptr_add(mo->lazy_binding, 1);1315 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,
1305 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,1317 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
1306 mo->lazy_binding,1318 mo->lazy_binding,
1307 mo->s_lazy_bind[i].la_symbol_offset +1319 mo->s_lazy_bind[i].la_symbol_offset +
@@ -1320,7 +1332,7 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 12 unmodified lines
1320 1332
1321 ptr = section_ptr_add(mo->rebase, 2);1333 ptr = section_ptr_add(mo->rebase, 2);
1322 *ptr++ = REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER;1334 *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,
1324 REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,1336 REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
1325 mo->rebase,1337 mo->rebase,
1326 mo->s_rebase[i].rel.r_offset +1338 mo->s_rebase[i].rel.r_offset +
@@ -1337,14 +1349,18 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 10 unmodified lines
1337 name = (char *) symtab_section->link->data + sym->st_name;1349 name = (char *) symtab_section->link->data + sym->st_name;
1338 binding = ELFW(ST_BIND)(sym->st_info) == STB_WEAK1350 binding = ELFW(ST_BIND)(sym->st_info) == STB_WEAK
1339 ? mo->weak_binding : mo->binding;1351 ? mo->weak_binding : mo->binding;
1340 ptr = section_ptr_add(binding, 5 + strlen(name));1352 ptr = section_ptr_add(binding, 4 + (binding == mo->binding) +
1341 *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |1353 strlen(name));
1342 (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);1354 if (binding == mo->binding)
1343 *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;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);
1344 strcpy((char *)ptr, name);1360 strcpy((char *)ptr, name);
1345 ptr += strlen(name) + 1;1361 ptr += strlen(name) + 1;
1346 *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER;1362 *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,
1348 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,1364 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
1349 binding,1365 binding,
1350 mo->bind[i].rel.r_offset + s->sh_addr);1366 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
1488{1504{
1489 struct trie_info *a = (struct trie_info *) _a;1505 struct trie_info *a = (struct trie_info *) _a;
1490 struct trie_info *b = (struct trie_info *) _b;1506 struct trie_info *b = (struct trie_info *) _b;
1507 int len_a = strlen(a->name);
1508 int len_b = strlen(b->name);
1491 1509
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);
1492 return strcmp(a->name, b->name);1513 return strcmp(a->name, b->name);
1493}1514}
1494 1515
@@ -1502,7 +1523,7 @@ static void export_trie(TCCState *s1, struct macho *mo) · 7 unmodified lines
1502 struct trie_info *trie = NULL, *p_trie;1523 struct trie_info *trie = NULL, *p_trie;
1503 struct trie_node node, *p_node;1524 struct trie_node node, *p_node;
1504 struct trie_seq *seq = NULL;1525 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;
1506 1527
1507 for (sym_index = 1; sym_index < sym_end; ++sym_index) {1528 for (sym_index = 1; sym_index < sym_end; ++sym_index) {
1508 ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;1529 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
1576 tcc_free(trie);1597 tcc_free(trie);
1577}1598}
1578 1599
1579static void collect_sections(TCCState *s1, struct macho *mo)1600static void collect_sections(TCCState *s1, struct macho *mo, const char *filename)
1580{1601{
1581 int i, sk, numsec;1602 int i, sk, numsec;
1582 int used_segment[N_SEGMENT];1603 int used_segment[N_SEGMENT];
1583 uint64_t curaddr, fileofs;1604 uint64_t curaddr, fileofs;
1584 Section *s;1605 Section *s;
1585 struct segment_command_64 *seg;1606 struct segment_command_64 *seg;
1607 struct dylib_command *dylib;
1586#ifdef CONFIG_NEW_MACHO1608#ifdef CONFIG_NEW_MACHO
1587 struct linkedit_data_command *chained_fixups_lc;1609 struct linkedit_data_command *chained_fixups_lc;
1588 struct linkedit_data_command *export_trie_lc;1610 struct linkedit_data_command *export_trie_lc;
1589#endif1611#endif
1590 struct build_version_command *dyldbv;1612 struct build_version_command *dyldbv;
1591 struct source_version_command *dyldsv;1613 struct source_version_command *dyldsv;
1614 struct rpath_command *rpath;
1592 struct dylinker_command *dyldlc;1615 struct dylinker_command *dyldlc;
1593 struct symtab_command *symlc;1616 struct symtab_command *symlc;
1594 struct dysymtab_command *dysymlc;1617 struct dysymtab_command *dysymlc;
@@ -1662,10 +1685,16 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 67 unmodified lines
1662 used_segment[skinfo[sk].seg_initial] = 1;1685 used_segment[skinfo[sk].seg_initial] = 1;
1663 }1686 }
1664 1687
1688 if (s1->output_type != TCC_OUTPUT_EXE)
1689 used_segment[0] = 0;
1690
1665 for (i = 0; i < N_SEGMENT; i++)1691 for (i = 0; i < N_SEGMENT; i++)
1666 if (used_segment[i]) {1692 if (used_segment[i]) {
1667 seg = add_segment(mo, all_segment[i].name);1693 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;
1669 seg->vmsize = all_segment[i].vmsize;1698 seg->vmsize = all_segment[i].vmsize;
1670 seg->maxprot = all_segment[i].maxprot;1699 seg->maxprot = all_segment[i].maxprot;
1671 seg->initprot = all_segment[i].initprot;1700 seg->initprot = all_segment[i].initprot;
@@ -1675,6 +1704,17 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 3 unmodified lines
1675 mo->segment[sk] = mo->nseg - 1;1704 mo->segment[sk] = mo->nseg - 1;
1676 }1705 }
1677 1706
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
1678#ifdef CONFIG_NEW_MACHO1718#ifdef CONFIG_NEW_MACHO
1679 chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS,1719 chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS,
1680 sizeof(struct linkedit_data_command));1720 sizeof(struct linkedit_data_command));
@@ -1687,11 +1727,13 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 6 unmodified lines
1687 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));1727 symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc));
1688 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));1728 dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc));
1689 1729
1690 i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8;1730 if (s1->output_type == TCC_OUTPUT_EXE) {
1691 dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i);1731 i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8;
1692 dyldlc->name = sizeof(*dyldlc);1732 dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i);
1693 str = (char*)dyldlc + dyldlc->name;1733 dyldlc->name = sizeof(*dyldlc);
1694 strcpy(str, "/usr/lib/dyld");1734 str = (char*)dyldlc + dyldlc->name;
1735 strcpy(str, "/usr/lib/dyld");
1736 }
1695 1737
1696 dyldbv = add_lc(mo, LC_BUILD_VERSION, sizeof(*dyldbv));1738 dyldbv = add_lc(mo, LC_BUILD_VERSION, sizeof(*dyldbv));
1697 dyldbv->platform = PLATFORM_MACOS;1739 dyldbv->platform = PLATFORM_MACOS;
@@ -1702,8 +1744,10 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 4 unmodified lines
1702 dyldsv = add_lc(mo, LC_SOURCE_VERSION, sizeof(*dyldsv));1744 dyldsv = add_lc(mo, LC_SOURCE_VERSION, sizeof(*dyldsv));
1703 dyldsv->version = 0;1745 dyldsv->version = 0;
1704 1746
1705 mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));1747 if (s1->output_type == TCC_OUTPUT_EXE) {
1706 mo->ep->entryoff = 4096;1748 mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep));
1749 mo->ep->entryoff = 4096;
1750 }
1707 1751
1708 for(i = 0; i < s1->nb_loaded_dlls; i++) {1752 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1709 DLLReference *dllref = s1->loaded_dlls[i];1753 DLLReference *dllref = s1->loaded_dlls[i];
@@ -1711,13 +1755,21 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 1 unmodified line
1711 add_dylib(mo, dllref->name);1755 add_dylib(mo, dllref->name);
1712 }1756 }
1713 1757
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
1714 fileofs = 4096; /* leave space for mach-o headers */1766 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;
1716 curaddr += 4096;1768 curaddr += 4096;
1717 seg = NULL;1769 seg = NULL;
1718 numsec = 0;1770 numsec = 0;
1719 mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections);1771 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++) {
1721 struct section_64 *sec = NULL;1773 struct section_64 *sec = NULL;
1722 if (seg) {1774 if (seg) {
1723 seg->vmsize = curaddr - seg->vmaddr;1775 seg->vmsize = curaddr - seg->vmaddr;
@@ -1734,7 +1786,8 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 10 unmodified lines
1734 export_trie(s1, mo);1786 export_trie(s1, mo);
1735 }1787 }
1736#endif1788#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) {
1738 uint64_t al = 0;1791 uint64_t al = 0;
1739 int si;1792 int si;
1740 seg = get_segment(mo, mo->segment[sk]);1793 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
1889 mo->mh.mh.cputype = CPU_TYPE_ARM64;1942 mo->mh.mh.cputype = CPU_TYPE_ARM64;
1890 mo->mh.mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL;1943 mo->mh.mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL;
1891#endif1944#endif
1892 mo->mh.mh.filetype = MH_EXECUTE;1945 if (s1->output_type == TCC_OUTPUT_EXE) {
1893 mo->mh.mh.flags = MH_DYLDLINK | MH_PIE;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 }
1894 mo->mh.mh.ncmds = mo->nlc;1953 mo->mh.mh.ncmds = mo->nlc;
1895 mo->mh.mh.sizeofcmds = 0;1954 mo->mh.mh.sizeofcmds = 0;
1896 for (i = 0; i < mo->nlc; i++)1955 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
1905 1964
1906 for (sk = sk_unknown; sk < sk_last; sk++) {1965 for (sk = sk_unknown; sk < sk_last; sk++) {
1907 //struct segment_command_64 *seg;1966 //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)
1909 continue;1969 continue;
1910 /*seg =*/ get_segment(mo, mo->segment[sk]);1970 /*seg =*/ get_segment(mo, mo->segment[sk]);
1911 for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {1971 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
1969 image = (struct dyld_chained_starts_in_image *) data;2029 image = (struct dyld_chained_starts_in_image *) data;
1970 data += (size + 7) & -8;2030 data += (size + 7) & -8;
1971 image->seg_count = mo->nseg;2031 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++) {
1973 image->seg_info_offset[i] = (data - mo->chained_fixups->data) -2033 image->seg_info_offset[i] = (data - mo->chained_fixups->data) -
1974 header->starts_offset;2034 header->starts_offset;
1975 seg = get_segment(mo, i);2035 seg = get_segment(mo, i);
@@ -2117,10 +2177,11 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 141 unmodified lines
2117 check_relocs(s1, &mo);2177 check_relocs(s1, &mo);
2118 ret = check_symbols(s1, &mo);2178 ret = check_symbols(s1, &mo);
2119 if (!ret) {2179 if (!ret) {
2120 collect_sections(s1, &mo);2180 collect_sections(s1, &mo, filename);
2121 relocate_syms(s1, s1->symtab, 0);2181 relocate_syms(s1, s1->symtab, 0);
2122 mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1)2182 if (s1->output_type == TCC_OUTPUT_EXE)
2123 - get_segment(&mo, 1)->vmaddr;2183 mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1)
2184 - get_segment(&mo, 1)->vmaddr;
2124 if (s1->nb_errors)2185 if (s1->nb_errors)
2125 goto do_ret;2186 goto do_ret;
2126 relocate_sections(s1);2187 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
772 addr_t last_pc;772 addr_t last_pc;
773 addr_t pc;773 addr_t pc;
774#if defined TCC_TARGET_MACHO774#if defined TCC_TARGET_MACHO
775 addr_t first_pc = 0;775 addr_t first_pc;
776#endif776#endif
777 addr_t func_addr;777 addr_t func_addr;
778 int line;778 int line;
@@ -782,6 +782,9 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, · 3 unmodified lines
782next:782next:
783 ln = rc->dwarf_line;783 ln = rc->dwarf_line;
784 while (ln < rc->dwarf_line_end) {784 while (ln < rc->dwarf_line_end) {
785#if defined TCC_TARGET_MACHO
786 first_pc = 0;
787#endif
785 dir_size = 0;788 dir_size = 0;
786 filename_size = 0;789 filename_size = 0;
787 last_pc = 0;790 last_pc = 0;
@@ -935,7 +938,7 @@ check_pc: · 147 unmodified lines
935#endif938#endif
936#if defined TCC_TARGET_MACHO939#if defined TCC_TARGET_MACHO
937 if (first_pc == 0 && rc->prog_base != (addr_t) -1)940 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;
939 pc += first_pc;942 pc += first_pc;
940#endif943#endif
941 opindex = 0;944 opindex = 0;
tests/Makefile+1−1
@@ -158,7 +158,7 @@ dlltest: · 157 unmodified lines
158 $(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF)158 $(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF)
159 $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)159 $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
160 ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c160 ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
161ifndef CONFIG_WIN32161ifeq (,$(filter Darwin WIN32,$(TARGETOS)))
162 @echo ------------ $@ with PIC ------------162 @echo ------------ $@ with PIC ------------
163 $(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c163 $(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c
164 $(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF)164 $(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