mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
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.
This commit is contained in:
parent
14e78d7cc2
commit
894e166ecf
50
tccmacho.c
50
tccmacho.c
@ -422,6 +422,7 @@ struct macho {
|
|||||||
Section *symtab, *strtab, *wdata, *indirsyms, *stubs, *exports;
|
Section *symtab, *strtab, *wdata, *indirsyms, *stubs, *exports;
|
||||||
uint32_t ilocal, iextdef, iundef;
|
uint32_t ilocal, iextdef, iundef;
|
||||||
int stubsym, n_got, nr_plt;
|
int stubsym, n_got, nr_plt;
|
||||||
|
int segment[sk_last];
|
||||||
#ifdef CONFIG_NEW_MACHO
|
#ifdef CONFIG_NEW_MACHO
|
||||||
Section *chained_fixups;
|
Section *chained_fixups;
|
||||||
int n_bind;
|
int n_bind;
|
||||||
@ -1189,14 +1190,14 @@ static void create_symtab(TCCState *s1, struct macho *mo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const struct {
|
const struct {
|
||||||
int seg;
|
int seg_initial;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
const char *name;
|
const char *name;
|
||||||
} skinfo[sk_last] = {
|
} skinfo[sk_last] = {
|
||||||
/*[sk_unknown] =*/ { 0 },
|
/*[sk_unknown] =*/ { 0 },
|
||||||
/*[sk_discard] =*/ { 0 },
|
/*[sk_discard] =*/ { 0 },
|
||||||
/*[sk_text] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
|
/*[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
|
/*[sk_stubs] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS | S_SYMBOL_STUBS
|
||||||
| S_ATTR_SOME_INSTRUCTIONS , "__stubs" },
|
| S_ATTR_SOME_INSTRUCTIONS , "__stubs" },
|
||||||
/*[sk_stub_helper] =*/ { 1, S_REGULAR | S_ATTR_PURE_INSTRUCTIONS
|
/*[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;
|
struct dysymtab_command *dysymlc;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
|
for (sk = sk_unknown; sk < sk_last; sk++)
|
||||||
|
mo->segment[sk] = skinfo[sk].seg_initial;
|
||||||
|
|
||||||
seg = add_segment(mo, "__PAGEZERO");
|
seg = add_segment(mo, "__PAGEZERO");
|
||||||
seg->vmsize = (uint64_t)1 << 32;
|
seg->vmsize = (uint64_t)1 << 32;
|
||||||
|
|
||||||
@ -1584,10 +1588,16 @@ static void collect_sections(TCCState *s1, struct macho *mo)
|
|||||||
seg->initprot = 3; // rw-
|
seg->initprot = 3; // rw-
|
||||||
seg->flags = SG_READ_ONLY;
|
seg->flags = SG_READ_ONLY;
|
||||||
|
|
||||||
seg = add_segment(mo, "__DWARF");
|
if (dwarf_info_section) {
|
||||||
seg->vmaddr = -1;
|
seg = add_segment(mo, "__DWARF");
|
||||||
seg->maxprot = 7; // rwx
|
seg->vmaddr = -1;
|
||||||
seg->initprot = 3; // rw-
|
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 = add_segment(mo, "__DATA");
|
||||||
seg->vmaddr = -1;
|
seg->vmaddr = -1;
|
||||||
@ -1599,10 +1609,6 @@ static void collect_sections(TCCState *s1, struct macho *mo)
|
|||||||
seg->maxprot = 1; // r--
|
seg->maxprot = 1; // r--
|
||||||
seg->initprot = 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
|
#ifdef CONFIG_NEW_MACHO
|
||||||
chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS,
|
chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS,
|
||||||
sizeof(struct linkedit_data_command));
|
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++) {
|
for (sk = sk_unknown; sk < sk_last; sk++) {
|
||||||
struct section_64 *sec = NULL;
|
struct section_64 *sec = NULL;
|
||||||
if (seg) {
|
if (seg) {
|
||||||
#ifdef CONFIG_NEW_MACHO
|
|
||||||
seg->vmsize = curaddr - seg->vmaddr;
|
seg->vmsize = curaddr - seg->vmaddr;
|
||||||
seg->filesize = fileofs - seg->fileoff;
|
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
|
#ifdef CONFIG_NEW_MACHO
|
||||||
if (sk == sk_linkedit) {
|
if (sk == sk_linkedit) {
|
||||||
@ -1735,14 +1734,14 @@ static void collect_sections(TCCState *s1, struct macho *mo)
|
|||||||
export_trie(s1, mo);
|
export_trie(s1, mo);
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
uint64_t al = 0;
|
||||||
int si;
|
int si;
|
||||||
seg = get_segment(mo, skinfo[sk].seg);
|
seg = get_segment(mo, mo->segment[sk]);
|
||||||
if (skinfo[sk].name) {
|
if (skinfo[sk].name) {
|
||||||
si = add_section(mo, &seg, skinfo[sk].name);
|
si = add_section(mo, &seg, skinfo[sk].name);
|
||||||
numsec++;
|
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;
|
mo->sk_to_sect[sk].machosect = si;
|
||||||
sec = get_section(seg, si);
|
sec = get_section(seg, si);
|
||||||
sec->flags = skinfo[sk].flags;
|
sec->flags = skinfo[sk].flags;
|
||||||
@ -1760,17 +1759,10 @@ static void collect_sections(TCCState *s1, struct macho *mo)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (seg->vmaddr == -1) {
|
if (seg->vmaddr == -1) {
|
||||||
#ifdef CONFIG_NEW_MACHO
|
|
||||||
curaddr = (curaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
|
curaddr = (curaddr + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
|
||||||
seg->vmaddr = curaddr;
|
seg->vmaddr = curaddr;
|
||||||
fileofs = (fileofs + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
|
fileofs = (fileofs + SEG_PAGE_SIZE - 1) & -SEG_PAGE_SIZE;
|
||||||
seg->fileoff = fileofs;
|
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) {
|
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++) {
|
for (sk = sk_unknown; sk < sk_last; sk++) {
|
||||||
//struct segment_command_64 *seg;
|
//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;
|
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) {
|
for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
|
||||||
if (s->sh_type != SHT_NOBITS) {
|
if (s->sh_type != SHT_NOBITS) {
|
||||||
while (fileofs < s->sh_offset)
|
while (fileofs < s->sh_offset)
|
||||||
|
Loading…
Reference in New Issue
Block a user