summaryrefslogtreecommitdiff
path: root/output
diff options
context:
space:
mode:
authorChang S. Bae <changseok.bae@gmail.com>2018-10-08 18:49:54 -0700
committerCyrill Gorcunov <gorcunov@gmail.com>2018-10-09 10:23:01 +0300
commitf63d211bcf9a2015276682ce4a9be5960b0aaad4 (patch)
treec72f444df027d5809d5c5a9a84c195363414f8e4 /output
parent960efc3ff2c8a4ecf8b968c6e485b4addd33c92f (diff)
downloadnasm-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.c12
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 */