From 894e166ecf68721d1182e7adedf3dbf27a5527d7 Mon Sep 17 00:00:00 2001 From: herman ten brugge Date: Fri, 2 Dec 2022 22:57:49 +0100 Subject: [PATCH] Better fix for old macho format The last commit only worked on arm64. The problem was that the new __DWARF segment was empty. I now remove the __DWARF segment if it is not needed. This resolves the rebase problem on x86_64. --- tccmacho.c | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/tccmacho.c b/tccmacho.c index b31f57d9..f78508b2 100644 --- a/tccmacho.c +++ b/tccmacho.c @@ -422,6 +422,7 @@ struct macho { Section *symtab, *strtab, *wdata, *indirsyms, *stubs, *exports; uint32_t ilocal, iextdef, iundef; int stubsym, n_got, nr_plt; + int segment[sk_last]; #ifdef CONFIG_NEW_MACHO Section *chained_fixups; int n_bind; @@ -1189,14 +1190,14 @@ static void create_symtab(TCCState *s1, struct macho *mo) } const struct { - int seg; + int seg_initial; uint32_t flags; const char *name; } skinfo[sk_last] = { /*[sk_unknown] =*/ { 0 }, /*[sk_discard] =*/ { 0 }, /*[sk_text] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS - | S_ATTR_SOME_INSTRUCTIONS, "__text" }, + | S_ATTR_SOME_INSTRUCTIONS, "__text" }, /*[sk_stubs] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS | S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS , "__stubs" }, /*[sk_stub_helper] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS @@ -1570,6 +1571,9 @@ static void collect_sections(TCCState *s1, struct macho *mo) struct dysymtab_command *dysymlc; char *str; + for (sk = sk_unknown; sk < sk_last; sk++) + mo->segment[sk] = skinfo[sk].seg_initial; + seg = add_segment(mo, "__PAGEZERO"); seg->vmsize = (uint64_t)1 << 32; @@ -1584,10 +1588,16 @@ static void collect_sections(TCCState *s1, struct macho *mo) seg->initprot = 3; // rw- seg->flags = SG_READ_ONLY; - seg = add_segment(mo, "__DWARF"); - seg->vmaddr = -1; - seg->maxprot = 7; // rwx - seg->initprot = 3; // rw- + if (dwarf_info_section) { + seg = add_segment(mo, "__DWARF"); + seg->vmaddr = -1; + seg->maxprot = 7; // rwx + seg->initprot = 3; // rw- + } + else + for (sk = sk_unknown; sk < sk_last; sk++) + if (mo->segment[sk] >= 4) + mo->segment[sk]--; seg = add_segment(mo, "__DATA"); seg->vmaddr = -1; @@ -1599,10 +1609,6 @@ static void collect_sections(TCCState *s1, struct macho *mo) seg->maxprot = 1; // r-- seg->initprot = 1; // r-- - /* trick to avoid __DWARF vmaddr = -1 */ - if (dwarf_info_section == NULL) - dwarf_info_section = new_section(s1, ".debug_info", SHT_PROGBITS, 0); - #ifdef CONFIG_NEW_MACHO chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS, sizeof(struct linkedit_data_command)); @@ -1714,15 +1720,8 @@ static void collect_sections(TCCState *s1, struct macho *mo) for (sk = sk_unknown; sk < sk_last; sk++) { struct section_64 *sec = NULL; if (seg) { -#ifdef CONFIG_NEW_MACHO seg->vmsize = curaddr - seg->vmaddr; seg->filesize = fileofs - seg->fileoff; -#else - seg->vmsize = (curaddr - seg->vmaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE; - seg->filesize = (fileofs - seg->fileoff + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE; - curaddr = seg->vmaddr + seg->vmsize; - fileofs = seg->fileoff + seg->filesize; -#endif } #ifdef CONFIG_NEW_MACHO if (sk == sk_linkedit) { @@ -1735,14 +1734,14 @@ static void collect_sections(TCCState *s1, struct macho *mo) export_trie(s1, mo); } #endif - if (skinfo[sk].seg && mo->sk_to_sect[sk].s) { + if (mo->segment[sk] && mo->sk_to_sect[sk].s) { uint64_t al = 0; int si; - seg = get_segment(mo, skinfo[sk].seg); + seg = get_segment(mo, mo->segment[sk]); if (skinfo[sk].name) { si = add_section(mo, &seg, skinfo[sk].name); numsec++; - mo->lc[mo->seg2lc[skinfo[sk].seg]] = (struct load_command*)seg; + mo->lc[mo->seg2lc[mo->segment[sk]]] = (struct load_command*)seg; mo->sk_to_sect[sk].machosect = si; sec = get_section(seg, si); sec->flags = skinfo[sk].flags; @@ -1760,17 +1759,10 @@ static void collect_sections(TCCState *s1, struct macho *mo) #endif } if (seg->vmaddr == -1) { -#ifdef CONFIG_NEW_MACHO curaddr = (curaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE; seg->vmaddr = curaddr; fileofs = (fileofs + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE; seg->fileoff = fileofs; -#else - curaddr = (curaddr + 4095) & -4096; - seg->vmaddr = curaddr; - fileofs = (fileofs + 4095) & -4096; - seg->fileoff = fileofs; -#endif } for (s = mo->sk_to_sect[sk].s; s; s = s->prev) { @@ -1913,9 +1905,9 @@ 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 (!skinfo[sk].seg || !mo->sk_to_sect[sk].s) + if (!mo->segment[sk] || !mo->sk_to_sect[sk].s) continue; - /*seg =*/ get_segment(mo, skinfo[sk].seg); + /*seg =*/ get_segment(mo, mo->segment[sk]); for (s = mo->sk_to_sect[sk].s; s; s = s->prev) { if (s->sh_type != SHT_NOBITS) { while (fileofs < s->sh_offset) -- 2.11.4.GIT