diff --git a/configure b/configure index 7148626c..6fe82482 100755 --- a/configure +++ b/configure @@ -66,7 +66,7 @@ case $targetos in Darwin) darwin=yes dwarf=4 - confvars="$confvars OSX dll=no dwarf=$dwarf" + confvars="$confvars OSX" cc=`which cc` cc=`readlink $cc || echo clang` tcc_usrinclude="`xcrun --show-sdk-path`/usr/include" diff --git a/tccelf.c b/tccelf.c index dd3d6be6..bb9c6806 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1580,8 +1580,9 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) put_ptr(s1, NULL, 0); #if defined TCC_TARGET_MACHO /* adjust for __PAGEZERO */ - write64le(data_section->data + data_section->data_offset - PTR_SIZE, - (uint64_t)1 << 32); + if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE) + write64le(data_section->data + data_section->data_offset - PTR_SIZE, + (uint64_t)1 << 32); #endif n = 2 * PTR_SIZE; #ifdef CONFIG_TCC_BCHECK diff --git a/tccmacho.c b/tccmacho.c index 109eaa86..faa16248 100644 --- a/tccmacho.c +++ b/tccmacho.c @@ -40,6 +40,7 @@ #define MH_EXECUTE (0x2) #define MH_DYLDLINK (0x4) +#define MH_DYLIB (0x6) #define MH_PIE (0x200000) #define CPU_SUBTYPE_LIB64 (0x80000000) @@ -104,6 +105,7 @@ struct load_command { #define LC_ID_DYLIB 0xd #define LC_LOAD_DYLINKER 0xe #define LC_SEGMENT_64 0x19 +#define LC_RPATH (0x1c | LC_REQ_DYLD) #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) #define LC_MAIN (0x28|LC_REQ_DYLD) @@ -243,6 +245,12 @@ struct dylib_command { uint32_t compatibility_version; /* library's compatibility vers number*/ }; +struct rpath_command { + uint32_t cmd; /* LC_RPATH */ + uint32_t cmdsize; /* includes string */ + lc_str path; /* path to add to run path */ +}; + struct dylinker_command { uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT */ @@ -327,6 +335,8 @@ struct dysymtab_command { #define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70 #define BIND_OPCODE_DO_BIND 0x90 +#define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1 + #define BIND_TYPE_POINTER 1 #define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2 @@ -653,13 +663,12 @@ static void bind_rebase_add(struct macho *mo, int bind, int sh_info, static void check_relocs(TCCState *s1, struct macho *mo) { Section *s; - ElfW_Rel *rel; + ElfW_Rel *rel, save_rel; ElfW(Sym) *sym; int i, type, gotplt_entry, sym_index, for_code; uint32_t *pi, *goti; struct sym_attr *attr; - mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); goti = NULL; mo->nr_plt = mo->n_got = 0; for (i = 1; i < s1->nb_sections; i++) { @@ -668,6 +677,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7)) continue; for_each_elem(s, 0, rel, ElfW_Rel) { + save_rel = *rel; type = ELFW(R_TYPE)(rel->r_info); gotplt_entry = gotplt_entry_type(type); for_code = code_reloc(type); @@ -685,7 +695,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) attr->dyn_index = 1; /* used as flag */ section_ptr_add(s1->got, PTR_SIZE); put_elf_reloc(s1->symtab, s1->got, attr->got_offset, - R_DATA_PTR, sym_index); + R_JMP_SLOT, sym_index); goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti)); if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) { if (sym->st_shndx == SHN_UNDEF) @@ -701,7 +711,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) && type == R_AARCH64_ADR_GOT_PAGE #endif ) { - bind_rebase_add(mo, 1, s1->got->reloc->sh_info, rel, attr); + bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr); attr->plt_offset = 0; // ignore next bind s1->got->reloc->data_offset -= sizeof (ElfW_Rel); } @@ -740,7 +750,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) write32le(jmp + 8, // br x16 0xd61f0200); #endif - bind_rebase_add(mo, 1, s1->got->reloc->sh_info, rel, attr); + bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr); pi = section_ptr_add(mo->indirsyms, sizeof(*pi)); *pi = mo->e2msym[sym_index]; mo->nr_plt++; @@ -749,9 +759,9 @@ static void check_relocs(TCCState *s1, struct macho *mo) rel->r_addend += attr->plt_offset; } } - if (type == R_DATA_PTR) + if (type == R_DATA_PTR || type == R_JMP_SLOT) bind_rebase_add(mo, sym->st_shndx == SHN_UNDEF ? 1 : 0, - s->sh_info, rel, NULL); + s->sh_info, &save_rel, NULL); } } pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi)); @@ -765,15 +775,13 @@ static void check_relocs(TCCState *s1, struct macho *mo) { uint8_t *jmp; Section *s; - ElfW_Rel *rel; + ElfW_Rel *rel, save_rel; ElfW(Sym) *sym; int i, type, gotplt_entry, sym_index, for_code; int bind_offset, la_symbol_offset; uint32_t *pi, *goti; struct sym_attr *attr; - mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); - #ifdef TCC_TARGET_X86_64 jmp = section_ptr_add(mo->stub_helper, 16); jmp[0] = 0x4c; /* leaq _dyld_private(%rip), %r11 */ @@ -814,6 +822,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) !strncmp(s1->sections[s->sh_info]->name, ".debug_", 7)) continue; for_each_elem(s, 0, rel, ElfW_Rel) { + save_rel = *rel; type = ELFW(R_TYPE)(rel->r_info); gotplt_entry = gotplt_entry_type(type); for_code = code_reloc(type); @@ -831,7 +840,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) attr->dyn_index = 1; /* used as flag */ section_ptr_add(s1->got, PTR_SIZE); put_elf_reloc(s1->symtab, s1->got, attr->got_offset, - R_DATA_PTR, sym_index); + R_JMP_SLOT, sym_index); goti = tcc_realloc(goti, (mo->n_got + 1) * sizeof(*goti)); if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) { if (sym->st_shndx == SHN_UNDEF) @@ -852,7 +861,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) (mo->n_bind + 1) * sizeof(struct bind)); mo->bind[mo->n_bind].section = s1->got->reloc->sh_info; - mo->bind[mo->n_bind].rel = *rel; + mo->bind[mo->n_bind].rel = save_rel; mo->bind[mo->n_bind].rel.r_offset = attr->got_offset; mo->n_bind++; s1->got->reloc->data_offset -= sizeof (ElfW_Rel); @@ -936,7 +945,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) bind_offset; mo->s_lazy_bind[mo->n_lazy_bind].la_symbol_offset = la_symbol_offset; - mo->s_lazy_bind[mo->n_lazy_bind].rel = *rel; + mo->s_lazy_bind[mo->n_lazy_bind].rel = save_rel; mo->s_lazy_bind[mo->n_lazy_bind].rel.r_offset = attr->plt_offset; mo->n_lazy_bind++; @@ -948,13 +957,13 @@ static void check_relocs(TCCState *s1, struct macho *mo) rel->r_addend += attr->plt_offset; } } - if (type == R_DATA_PTR) { + if (type == R_DATA_PTR || type == R_JMP_SLOT) { if (sym->st_shndx == SHN_UNDEF) { mo->bind = tcc_realloc(mo->bind, (mo->n_bind + 1) * sizeof(struct bind)); mo->bind[mo->n_bind].section = s->sh_info; - mo->bind[mo->n_bind].rel = *rel; + mo->bind[mo->n_bind].rel = save_rel; mo->n_bind++; } else { @@ -962,7 +971,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) tcc_realloc(mo->s_rebase, (mo->n_rebase + 1) * sizeof(struct s_rebase)); mo->s_rebase[mo->n_rebase].section = s->sh_info; - mo->s_rebase[mo->n_rebase].rel = *rel; + mo->s_rebase[mo->n_rebase].rel = save_rel; mo->n_rebase++; } } @@ -1008,6 +1017,7 @@ static int check_symbols(TCCState *s1, struct macho *mo) if (mo->iundef == -1) mo->iundef = sym_index - 1; if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK + || s1->output_type != TCC_OUTPUT_EXE || find_elf_sym(s1->dynsymtab_section, name)) { /* Mark the symbol as coming from a dylib so that relocate_syms doesn't complain. Normally bind_exe_dynsyms @@ -1170,6 +1180,7 @@ static void create_symtab(TCCState *s1, struct macho *mo) mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); #endif mo->exports = new_section(s1, "EXPORT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); + mo->indirsyms = new_section(s1, "LEINDIR", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); mo->symtab = new_section(s1, "LESYMTAB", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); 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) pn[sym_index - 1].n_strx = put_elf_str(mo->strtab, name); pn[sym_index - 1].n_value = sym_index; } + section_ptr_add(mo->strtab, -mo->strtab->data_offset & (PTR_SIZE - 1)); tcc_qsort(pn, sym_end - 1, sizeof(*pn), machosymcmp, s1); mo->e2msym = tcc_malloc(sym_end * sizeof(*mo->e2msym)); mo->e2msym[0] = -1; @@ -1250,7 +1262,7 @@ static void calc_fixup_size(TCCState *s1, struct macho *mo) size = (sizeof(struct dyld_chained_fixups_header) + 7) & -8; size += (sizeof(struct dyld_chained_starts_in_image) + (mo->nseg - 1) * sizeof(uint32_t) + 7) & -8; - for (i = 1; i < mo->nseg - 1; i++) { + for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) { int page_count = (get_segment(mo, i)->vmsize + SEG_PAGE_SIZE - 1) / SEG_PAGE_SIZE; size += (sizeof(struct dyld_chained_starts_in_segment) + (page_count - 1) * sizeof(uint16_t) + 7) & -8; } @@ -1269,14 +1281,14 @@ static void calc_fixup_size(TCCState *s1, struct macho *mo) #else -static void set_segment_and_offset(struct macho *mo, addr_t addr, +static void set_segment_and_offset(TCCState *s1, struct macho *mo, addr_t addr, uint8_t *ptr, int opcode, Section *sec, addr_t offset) { int i; struct segment_command_64 *seg = NULL; - for (i = 1; i < mo->nseg - 1; i++) { + for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) { seg = get_segment(mo, i); if (addr >= seg->vmaddr && addr < (seg->vmaddr + seg->vmsize)) break; @@ -1301,7 +1313,7 @@ static void bind_rebase(TCCState *s1, struct macho *mo) mo->s_lazy_bind[i].bind_offset, mo->lazy_binding->data_offset); ptr = section_ptr_add(mo->lazy_binding, 1); - set_segment_and_offset(mo, mo->la_symbol_ptr->sh_addr, ptr, + set_segment_and_offset(s1, mo, mo->la_symbol_ptr->sh_addr, ptr, BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB, mo->lazy_binding, mo->s_lazy_bind[i].la_symbol_offset + @@ -1320,7 +1332,7 @@ static void bind_rebase(TCCState *s1, struct macho *mo) ptr = section_ptr_add(mo->rebase, 2); *ptr++ = REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER; - set_segment_and_offset(mo, s->sh_addr, ptr, + set_segment_and_offset(s1, mo, s->sh_addr, ptr, REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB, mo->rebase, mo->s_rebase[i].rel.r_offset + @@ -1337,14 +1349,18 @@ static void bind_rebase(TCCState *s1, struct macho *mo) name = (char *) symtab_section->link->data + sym->st_name; binding = ELFW(ST_BIND)(sym->st_info) == STB_WEAK ? mo->weak_binding : mo->binding; - ptr = section_ptr_add(binding, 5 + strlen(name)); - *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | - (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf); - *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0; + ptr = section_ptr_add(binding, 4 + (binding == mo->binding) + + strlen(name)); + if (binding == mo->binding) + *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | + (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf); + *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | + (binding == mo->weak_binding + ? BIND_SYMBOL_FLAGS_WEAK_IMPORT : 0); strcpy((char *)ptr, name); ptr += strlen(name) + 1; *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER; - set_segment_and_offset(mo, s->sh_addr, ptr, + set_segment_and_offset(s1, mo, s->sh_addr, ptr, BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB, binding, mo->bind[i].rel.r_offset + s->sh_addr); @@ -1488,7 +1504,12 @@ static int triecmp(const void *_a, const void *_b, void *arg) { struct trie_info *a = (struct trie_info *) _a; struct trie_info *b = (struct trie_info *) _b; + int len_a = strlen(a->name); + int len_b = strlen(b->name); + /* strange sorting needed. Name 'xx' should be after 'xx1' */ + if (!strncmp(a->name, b->name, len_a < len_b ? len_a : len_b)) + return len_a < len_b ? 1 : (len_a > len_b ? -1 : 0); return strcmp(a->name, b->name); } @@ -1502,7 +1523,7 @@ static void export_trie(TCCState *s1, struct macho *mo) struct trie_info *trie = NULL, *p_trie; struct trie_node node, *p_node; struct trie_seq *seq = NULL; - addr_t vm_addr = get_segment(mo, 1)->vmaddr; + addr_t vm_addr = get_segment(mo, s1->output_type == TCC_OUTPUT_EXE)->vmaddr; for (sym_index = 1; sym_index < sym_end; ++sym_index) { ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index; @@ -1576,19 +1597,21 @@ static void export_trie(TCCState *s1, struct macho *mo) tcc_free(trie); } -static void collect_sections(TCCState *s1, struct macho *mo) +static void collect_sections(TCCState *s1, struct macho *mo, const char *filename) { int i, sk, numsec; int used_segment[N_SEGMENT]; uint64_t curaddr, fileofs; Section *s; struct segment_command_64 *seg; + struct dylib_command *dylib; #ifdef CONFIG_NEW_MACHO struct linkedit_data_command *chained_fixups_lc; struct linkedit_data_command *export_trie_lc; #endif struct build_version_command *dyldbv; struct source_version_command *dyldsv; + struct rpath_command *rpath; struct dylinker_command *dyldlc; struct symtab_command *symlc; struct dysymtab_command *dysymlc; @@ -1662,10 +1685,16 @@ static void collect_sections(TCCState *s1, struct macho *mo) used_segment[skinfo[sk].seg_initial] = 1; } + if (s1->output_type != TCC_OUTPUT_EXE) + used_segment[0] = 0; + for (i = 0; i < N_SEGMENT; i++) if (used_segment[i]) { seg = add_segment(mo, all_segment[i].name); - seg->vmaddr = all_segment[i].vmaddr; + if (i == 1 && s1->output_type != TCC_OUTPUT_EXE) + seg->vmaddr = 0; + else + seg->vmaddr = all_segment[i].vmaddr; seg->vmsize = all_segment[i].vmsize; seg->maxprot = all_segment[i].maxprot; seg->initprot = all_segment[i].initprot; @@ -1675,6 +1704,17 @@ static void collect_sections(TCCState *s1, struct macho *mo) mo->segment[sk] = mo->nseg - 1; } + if (s1->output_type != TCC_OUTPUT_EXE) { + i = (sizeof(*dylib) + strlen(filename) + 1 + 7) &-8; + dylib = add_lc(mo, LC_ID_DYLIB, i); + dylib->name = sizeof(*dylib); + dylib->timestamp = 1; + dylib->current_version = 1 << 16; + dylib->compatibility_version = 1 << 16; + str = (char*)dylib + dylib->name; + strcpy(str, filename); + } + #ifdef CONFIG_NEW_MACHO chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS, sizeof(struct linkedit_data_command)); @@ -1687,11 +1727,13 @@ static void collect_sections(TCCState *s1, struct macho *mo) symlc = add_lc(mo, LC_SYMTAB, sizeof(*symlc)); dysymlc = add_lc(mo, LC_DYSYMTAB, sizeof(*dysymlc)); - i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8; - dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i); - dyldlc->name = sizeof(*dyldlc); - str = (char*)dyldlc + dyldlc->name; - strcpy(str, "/usr/lib/dyld"); + if (s1->output_type == TCC_OUTPUT_EXE) { + i = (sizeof(*dyldlc) + strlen("/usr/lib/dyld") + 1 + 7) &-8; + dyldlc = add_lc(mo, LC_LOAD_DYLINKER, i); + dyldlc->name = sizeof(*dyldlc); + str = (char*)dyldlc + dyldlc->name; + strcpy(str, "/usr/lib/dyld"); + } dyldbv = add_lc(mo, LC_BUILD_VERSION, sizeof(*dyldbv)); dyldbv->platform = PLATFORM_MACOS; @@ -1702,8 +1744,10 @@ static void collect_sections(TCCState *s1, struct macho *mo) dyldsv = add_lc(mo, LC_SOURCE_VERSION, sizeof(*dyldsv)); dyldsv->version = 0; - mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep)); - mo->ep->entryoff = 4096; + if (s1->output_type == TCC_OUTPUT_EXE) { + mo->ep = add_lc(mo, LC_MAIN, sizeof(*mo->ep)); + mo->ep->entryoff = 4096; + } for(i = 0; i < s1->nb_loaded_dlls; i++) { DLLReference *dllref = s1->loaded_dlls[i]; @@ -1711,13 +1755,21 @@ static void collect_sections(TCCState *s1, struct macho *mo) add_dylib(mo, dllref->name); } + if (s1->rpath) { + i = (sizeof(*rpath) + strlen(s1->rpath) + 1 + 7) &-8; + rpath = add_lc(mo, LC_RPATH, i); + rpath->path = sizeof(*rpath); + str = (char*)rpath + rpath->path; + strcpy(str, s1->rpath); + } + fileofs = 4096; /* leave space for mach-o headers */ - curaddr = get_segment(mo, 1)->vmaddr; + curaddr = get_segment(mo, s1->output_type == TCC_OUTPUT_EXE)->vmaddr; curaddr += 4096; seg = NULL; numsec = 0; mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections); - for (sk = sk_unknown; sk < sk_last; sk++) { + for (sk = sk_text; sk < sk_last; sk++) { struct section_64 *sec = NULL; if (seg) { seg->vmsize = curaddr - seg->vmaddr; @@ -1734,7 +1786,8 @@ static void collect_sections(TCCState *s1, struct macho *mo) export_trie(s1, mo); } #endif - if (mo->segment[sk] && mo->sk_to_sect[sk].s) { + if ((s1->output_type != TCC_OUTPUT_EXE || mo->segment[sk]) && + mo->sk_to_sect[sk].s) { uint64_t al = 0; int si; seg = get_segment(mo, mo->segment[sk]); @@ -1889,8 +1942,14 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) mo->mh.mh.cputype = CPU_TYPE_ARM64; mo->mh.mh.cpusubtype = CPU_SUBTYPE_ARM64_ALL; #endif - mo->mh.mh.filetype = MH_EXECUTE; - mo->mh.mh.flags = MH_DYLDLINK | MH_PIE; + if (s1->output_type == TCC_OUTPUT_EXE) { + mo->mh.mh.filetype = MH_EXECUTE; + mo->mh.mh.flags = MH_DYLDLINK | MH_PIE; + } + else { + mo->mh.mh.filetype = MH_DYLIB; + mo->mh.mh.flags = MH_DYLDLINK; + } mo->mh.mh.ncmds = mo->nlc; mo->mh.mh.sizeofcmds = 0; for (i = 0; i < mo->nlc; i++) @@ -1905,7 +1964,8 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) for (sk = sk_unknown; sk < sk_last; sk++) { //struct segment_command_64 *seg; - if (!mo->segment[sk] || !mo->sk_to_sect[sk].s) + if ((s1->output_type == TCC_OUTPUT_EXE && !mo->segment[sk]) || + !mo->sk_to_sect[sk].s) continue; /*seg =*/ get_segment(mo, mo->segment[sk]); 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) image = (struct dyld_chained_starts_in_image *) data; data += (size + 7) & -8; image->seg_count = mo->nseg; - for (i = 1; i < mo->nseg - 1; i++) { + for (i = (s1->output_type == TCC_OUTPUT_EXE); i < mo->nseg - 1; i++) { image->seg_info_offset[i] = (data - mo->chained_fixups->data) - header->starts_offset; seg = get_segment(mo, i); @@ -2117,10 +2177,11 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) check_relocs(s1, &mo); ret = check_symbols(s1, &mo); if (!ret) { - collect_sections(s1, &mo); + collect_sections(s1, &mo, filename); relocate_syms(s1, s1->symtab, 0); - mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1) - - get_segment(&mo, 1)->vmaddr; + if (s1->output_type == TCC_OUTPUT_EXE) + mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1) + - get_segment(&mo, 1)->vmaddr; if (s1->nb_errors) goto do_ret; relocate_sections(s1); diff --git a/tccrun.c b/tccrun.c index 07d9dbd6..852d1591 100644 --- a/tccrun.c +++ b/tccrun.c @@ -772,7 +772,7 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, addr_t last_pc; addr_t pc; #if defined TCC_TARGET_MACHO - addr_t first_pc = 0; + addr_t first_pc; #endif addr_t func_addr; int line; @@ -782,6 +782,9 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, next: ln = rc->dwarf_line; while (ln < rc->dwarf_line_end) { +#if defined TCC_TARGET_MACHO + first_pc = 0; +#endif dir_size = 0; filename_size = 0; last_pc = 0; @@ -935,7 +938,7 @@ check_pc: #endif #if defined TCC_TARGET_MACHO if (first_pc == 0 && rc->prog_base != (addr_t) -1) - first_pc += rc->prog_base - ((uint64_t)1 << 32); + first_pc += rc->prog_base; pc += first_pc; #endif opindex = 0; diff --git a/tests/Makefile b/tests/Makefile index e850b958..a46c8524 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -158,7 +158,7 @@ dlltest: $(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF) $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF) ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c -ifndef CONFIG_WIN32 +ifeq (,$(filter Darwin WIN32,$(TARGETOS))) @echo ------------ $@ with PIC ------------ $(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c $(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF)