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.
This commit is contained in:
herman ten brugge 2022-12-16 20:57:45 +01:00
parent 9cfc8f60ce
commit 8d3930bdb6
5 changed files with 117 additions and 52 deletions

2
configure vendored
View file

@ -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"

View file

@ -1580,6 +1580,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1)
put_ptr(s1, NULL, 0);
#if defined TCC_TARGET_MACHO
/* adjust for __PAGEZERO */
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

View file

@ -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 = 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 | 0;
*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,9 +1685,15 @@ 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);
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;
@ -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));
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;
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
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,8 +2177,9 @@ 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);
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)

View file

@ -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;

View file

@ -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)