diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2010-05-06 16:14:00 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-05-06 16:14:00 -0700 |
commit | 32575e46acd5d569ee3119b6cab1770e92245b89 (patch) | |
tree | 3242b2ede25c4bded66be54ec9c86f0334c2b6d1 /output/outelf64.c | |
parent | fea84d7fec9e5cc181ff148a6e49ac60cfdd8193 (diff) | |
download | nasm-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.c | 43 |
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; } } |