summaryrefslogtreecommitdiff
path: root/output/outelf64.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-05-06 16:14:00 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-05-06 16:14:00 -0700
commit32575e46acd5d569ee3119b6cab1770e92245b89 (patch)
tree3242b2ede25c4bded66be54ec9c86f0334c2b6d1 /output/outelf64.c
parentfea84d7fec9e5cc181ff148a6e49ac60cfdd8193 (diff)
downloadnasm-32575e46acd5d569ee3119b6cab1770e92245b89.tar.gz
ELF support for 8-bit relocations
Support 8-bit relocations (OUT_ADDRESS and OUT_REL1ADR) in ELF. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'output/outelf64.c')
-rw-r--r--output/outelf64.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/output/outelf64.c b/output/outelf64.c
index 47581b4b..76a64648 100644
--- a/output/outelf64.c
+++ b/output/outelf64.c
@@ -724,6 +724,7 @@ static void elf_out(int32_t segto, const void *data,
{
struct Section *s;
int64_t addr, zero;
+ int reltype, bytes;
int i;
static struct symlininfo sinfo;
@@ -783,18 +784,23 @@ static void elf_out(int32_t segto, const void *data,
return;
}
- if (type == OUT_RESERVE) {
+ switch (type) {
+ case OUT_RESERVE:
if (s->type == SHT_PROGBITS) {
nasm_error(ERR_WARNING, "uninitialized space declared in"
" non-BSS section `%s': zeroing", s->name);
elf_sect_write(s, NULL, size);
} else
s->len += size;
- } else if (type == OUT_RAWDATA) {
+ break;
+
+ case OUT_RAWDATA:
if (segment != NO_SEG)
nasm_error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
elf_sect_write(s, data, size);
- } else if (type == OUT_ADDRESS) {
+ break;
+
+ case OUT_ADDRESS:
addr = *(int64_t *)data;
if (segment == NO_SEG) {
/* Do nothing */
@@ -889,10 +895,22 @@ static void elf_out(int32_t segto, const void *data,
}
}
elf_sect_writeaddr(s, addr, size);
- } else if (type == OUT_REL2ADR) {
+ break;
+
+ case OUT_REL1ADR:
+ reltype = R_X86_64_PC8;
+ bytes = 1;
+ goto rel12adr;
+
+ case OUT_REL2ADR:
+ reltype = R_X86_64_PC16;
+ bytes = 2;
+ goto rel12adr;
+
+ rel12adr:
addr = *(int64_t *)data - size;
if (segment == segto)
- nasm_error(ERR_PANIC, "intra-segment OUT_REL2ADR");
+ nasm_error(ERR_PANIC, "intra-segment OUT_REL1ADR");
if (segment == NO_SEG) {
/* Do nothing */
} else if (segment % 2) {
@@ -900,15 +918,17 @@ static void elf_out(int32_t segto, const void *data,
" segment base references");
} else {
if (wrt == NO_SEG) {
- elf_add_reloc(s, segment, addr, R_X86_64_PC16);
+ elf_add_reloc(s, segment, addr, reltype);
addr = 0;
} else {
nasm_error(ERR_NONFATAL,
- "Unsupported non-32-bit ELF relocation [2]");
+ "Unsupported non-32-bit ELF relocation");
}
}
- elf_sect_writeaddr(s, addr, 2);
- } else if (type == OUT_REL4ADR) {
+ elf_sect_writeaddr(s, addr, bytes);
+ break;
+
+ case OUT_REL4ADR:
addr = *(int64_t *)data - size;
if (segment == segto)
nasm_error(ERR_PANIC, "intra-segment OUT_REL4ADR");
@@ -944,7 +964,9 @@ static void elf_out(int32_t segto, const void *data,
}
}
elf_sect_writeaddr(s, addr, 4);
- } else if (type == OUT_REL8ADR) {
+ break;
+
+ case OUT_REL8ADR:
addr = *(int64_t *)data - size;
if (segment == segto)
nasm_error(ERR_PANIC, "intra-segment OUT_REL8ADR");
@@ -975,6 +997,7 @@ static void elf_out(int32_t segto, const void *data,
}
}
elf_sect_writeaddr(s, addr, 8);
+ break;
}
}