diff options
author | Chang S. Bae <changseok.bae@gmail.com> | 2018-10-08 18:49:54 -0700 |
---|---|---|
committer | Cyrill Gorcunov <gorcunov@gmail.com> | 2018-10-09 10:23:01 +0300 |
commit | f63d211bcf9a2015276682ce4a9be5960b0aaad4 (patch) | |
tree | c72f444df027d5809d5c5a9a84c195363414f8e4 /output | |
parent | 960efc3ff2c8a4ecf8b968c6e485b4addd33c92f (diff) | |
download | nasm-f63d211bcf9a2015276682ce4a9be5960b0aaad4.tar.gz |
macho/reloc: Fixed offset adjustment in add_reloc()
If the target symbol is in the same file, add_reloc() emits an
internal reloc for the target section, and the offset written
is the offset in the target section. If the target symbol is
external, its offset is zero (or an explicit addend), and
add_reloc() emits an external reloc for the symbol.
Based-on-code-from: zenith432 <zenith432@users.sourceforge.net>
Signed-off-by: Chang S. Bae <changseok.bae@gmail.com>
Diffstat (limited to 'output')
-rw-r--r-- | output/outmacho.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/output/outmacho.c b/output/outmacho.c index b7bf9813..d1f81803 100644 --- a/output/outmacho.c +++ b/output/outmacho.c @@ -495,7 +495,7 @@ static int64_t add_reloc(struct section *sect, int32_t section, r = nasm_malloc(sizeof(struct reloc)); r->addr = sect->size & ~R_SCATTERED; r->ext = 1; - adjust = bytes; + adjust = 0; /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */ r->length = ilog2_32(bytes); @@ -521,7 +521,6 @@ static int64_t add_reloc(struct section *sect, int32_t section, /* local */ r->ext = 0; r->snum = fi; - adjust = -sect->size; } break; @@ -538,15 +537,12 @@ static int64_t add_reloc(struct section *sect, int32_t section, r->snum = raa_read(extsyms, section); if (reltype == RL_BRANCH) r->type = X86_64_RELOC_BRANCH; - else if (r->type == GENERIC_RELOC_VANILLA) - adjust = -sect->size; } else { /* local */ r->ext = 0; r->snum = fi; if (reltype == RL_BRANCH) r->type = X86_64_RELOC_BRANCH; - adjust = -sect->size; } break; @@ -587,6 +583,7 @@ static int64_t add_reloc(struct section *sect, int32_t section, goto bail; } + adjust -= sym->symv[0].key; r->snum = sym->initial_snum; } break; @@ -600,12 +597,15 @@ static int64_t add_reloc(struct section *sect, int32_t section, struct symbol *sym = macho_find_sym(s ? s : &absolute_sect, offset, false, false); if (sym) { - adjust = bytes - sym->symv[0].key; + adjust -= sym->symv[0].key; r->snum = sym->initial_snum; r->ext = 1; } } + if (r->pcrel) + adjust += ((r->ext && fmt.ptrsize == 8) ? bytes : -(int64_t)sect->size); + /* 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 ** difference either way */ |