From: nasm-bot f. H. P. A. <hp...@li...> - 2016-02-13 05:21:20
|
Commit-ID: 941356b2ca5499469ec31427b18019b5456b7606 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=941356b2ca5499469ec31427b18019b5456b7606 Author: H. Peter Anvin <hp...@li...> AuthorDate: Fri, 12 Feb 2016 15:06:23 -0800 Committer: H. Peter Anvin <hp...@li...> CommitDate: Fri, 12 Feb 2016 15:06:23 -0800 outmac: generate section-relative relocations for local symbols We generate section-relative relocations for local symbols for all the other output formats, and we should do the same for MachO; this was done in MachO-32 but not in MachO-64, presumably because the MachO spec implies that such relocations shouldn't exist in 64-bit code. They are indeed rare, but that is a programmer's decision, and the spec is clear that they are legal. Signed-off-by: H. Peter Anvin <hp...@li...> --- output/outmac.c | 55 +++++++++++++------------------------------------------ 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/output/outmac.c b/output/outmac.c index dc1111d..a2209c6 100644 --- a/output/outmac.c +++ b/output/outmac.c @@ -328,26 +328,6 @@ static uint8_t get_section_fileindex_by_index(const int32_t index) return NO_SECT; } -static struct symbol *get_closest_section_symbol_by_offset(uint8_t fileindex, int64_t offset) -{ - struct symbol *nearest = NULL; - struct symbol *sym; - - for (sym = syms; sym; sym = sym->next) { - if ((sym->sect != NO_SECT) && (sym->sect == fileindex)) { - if ((int64_t)sym->value > offset) - break; - nearest = sym; - } - } - - if (!nearest) - nasm_error(ERR_FATAL, "No section for index %x offset %llx found\n", - fileindex, (long long)offset); - - return nearest; -} - /* * Special section numbers which are used to define Mach-O special * symbols, which can be used with WRT to provide PIC relocation @@ -390,16 +370,11 @@ enum reltype { RL_GOTLOAD, /* X86_64_RELOC_GOT_LOAD */ }; -static int32_t add_reloc(struct section *sect, int32_t section, - enum reltype reltype, int bytes, int64_t reloff) +static void add_reloc(struct section *sect, int32_t section, + enum reltype reltype, int bytes) { struct reloc *r; - struct symbol *sym; int32_t fi; - int32_t adjustment = 0; - - if (section == NO_SEG) - return 0; /* NeXT as puts relocs in reversed order (address-wise) into the ** files, so we do the same, doesn't seem to make much of a @@ -427,20 +402,19 @@ static int32_t add_reloc(struct section *sect, int32_t section, switch (reltype) { case RL_ABS: if (section == NO_SEG) { - /* intra-section */ + /* absolute (can this even happen?) */ + r->ext = 0; r->snum = R_ABS; } else { /* inter-section */ fi = get_section_fileindex_by_index(section); - if (fi == NO_SECT) { /* external */ r->snum = raa_read(extsyms, section); } else { /* local */ - sym = get_closest_section_symbol_by_offset(fi, reloff); - r->snum = sym->initial_snum; - adjustment = sym->value; + r->ext = 0; + r->snum = fi; } } break; @@ -461,9 +435,8 @@ static int32_t add_reloc(struct section *sect, int32_t section, r->snum = raa_read(extsyms, section); } else { /* local */ - sym = get_closest_section_symbol_by_offset(fi, reloff); - r->snum = sym->initial_snum; - adjustment = sym->value; + r->ext = 0; + r->snum = fi; } } break; @@ -487,8 +460,6 @@ static int32_t add_reloc(struct section *sect, int32_t section, } ++sect->nreloc; - - return adjustment; } static void macho_output(int32_t secto, const void *data, @@ -564,7 +535,7 @@ static void macho_output(int32_t secto, const void *data, nasm_error(ERR_NONFATAL, "Mach-O 64-bit format does not support" " 32-bit absolute addresses"); } else { - addr -= add_reloc(s, section, RL_ABS, asize, addr); + add_reloc(s, section, RL_ABS, asize); } } else { nasm_error(ERR_NONFATAL, "Mach-O format does not support" @@ -595,7 +566,7 @@ static void macho_output(int32_t secto, const void *data, " this use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } else { - addr -= add_reloc(s, section, RL_REL, 2, addr); + add_reloc(s, section, RL_REL, 2); } WRITESHORT(p, addr); @@ -613,7 +584,7 @@ static void macho_output(int32_t secto, const void *data, " section base references"); } else if (wrt == NO_SEG) { /* Plain relative relocation */ - addr -= add_reloc(s, section, RL_REL, 4, addr); + add_reloc(s, section, RL_REL, 4); } else if (wrt == macho_gotpcrel_sect) { if (s->data->datalen > 1) { /* Retrieve instruction opcode */ @@ -623,10 +594,10 @@ static void macho_output(int32_t secto, const void *data, } if (gotload == 0x8B) { /* Check for MOVQ Opcode -> X86_64_RELOC_GOT_LOAD */ - addr -= add_reloc(s, section, RL_GOTLOAD, 4, addr); + add_reloc(s, section, RL_GOTLOAD, 4); } else { /* X86_64_RELOC_GOT */ - addr -= add_reloc(s, section, RL_GOT, 4, addr); + add_reloc(s, section, RL_GOT, 4); } } else { nasm_error(ERR_NONFATAL, "Mach-O format does not support" |