mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-31 18:20:22 +08:00
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>
This commit is contained in:
parent
fea84d7fec
commit
32575e46ac
@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2010 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@ -715,7 +715,8 @@ static void elf_out(int32_t segto, const void *data,
|
||||
{
|
||||
struct Section *s;
|
||||
int32_t addr;
|
||||
uint8_t mydata[4], *p;
|
||||
uint8_t mydata[8], *p;
|
||||
int reltype, bytes;
|
||||
int i;
|
||||
static struct symlininfo sinfo;
|
||||
|
||||
@ -761,18 +762,24 @@ 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:
|
||||
{
|
||||
bool gnu16 = false;
|
||||
addr = *(int64_t *)data;
|
||||
if (segment != NO_SEG) {
|
||||
@ -781,11 +788,20 @@ static void elf_out(int32_t segto, const void *data,
|
||||
" segment base references");
|
||||
} else {
|
||||
if (wrt == NO_SEG) {
|
||||
if (size == 2) {
|
||||
gnu16 = true;
|
||||
switch (size) {
|
||||
case 1:
|
||||
gnu16 = true;
|
||||
elf_add_reloc(s, segment, R_386_8);
|
||||
break;
|
||||
case 2:
|
||||
gnu16 = true;
|
||||
elf_add_reloc(s, segment, R_386_16);
|
||||
} else {
|
||||
break;
|
||||
case 4:
|
||||
elf_add_reloc(s, segment, R_386_32);
|
||||
break;
|
||||
default: /* Error issued further down */
|
||||
break;
|
||||
}
|
||||
} else if (wrt == elf_gotpc_sect + 1) {
|
||||
/*
|
||||
@ -825,36 +841,45 @@ static void elf_out(int32_t segto, const void *data,
|
||||
p = mydata;
|
||||
if (gnu16) {
|
||||
nasm_error(ERR_WARNING | ERR_WARN_GNUELF,
|
||||
"16-bit relocations in ELF is a GNU extension");
|
||||
WRITESHORT(p, addr);
|
||||
} else {
|
||||
if (size != 4 && segment != NO_SEG) {
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"Unsupported non-32-bit ELF relocation");
|
||||
}
|
||||
WRITELONG(p, addr);
|
||||
"8- or 16-bit relocations in ELF32 is a GNU extension");
|
||||
} else if (size != 4 && segment != NO_SEG) {
|
||||
nasm_error(ERR_NONFATAL, "Unsupported non-32-bit ELF relocation");
|
||||
}
|
||||
WRITEADDR(p, addr, size);
|
||||
elf_sect_write(s, mydata, size);
|
||||
} else if (type == OUT_REL2ADR) {
|
||||
if (segment == segto)
|
||||
nasm_error(ERR_PANIC, "intra-segment OUT_REL2ADR");
|
||||
break;
|
||||
}
|
||||
|
||||
case OUT_REL1ADR:
|
||||
bytes = 1;
|
||||
reltype = R_386_PC8;
|
||||
goto rel12adr;
|
||||
case OUT_REL2ADR:
|
||||
bytes = 2;
|
||||
reltype = R_386_PC16;
|
||||
goto rel12adr;
|
||||
|
||||
rel12adr:
|
||||
nasm_assert(segment != segto);
|
||||
if (segment != NO_SEG && segment % 2) {
|
||||
nasm_error(ERR_NONFATAL, "ELF format does not support"
|
||||
" segment base references");
|
||||
} else {
|
||||
if (wrt == NO_SEG) {
|
||||
nasm_error(ERR_WARNING | ERR_WARN_GNUELF,
|
||||
"16-bit relocations in ELF is a GNU extension");
|
||||
elf_add_reloc(s, segment, R_386_PC16);
|
||||
"8- or 16-bit relocations in ELF is a GNU extension");
|
||||
elf_add_reloc(s, segment, reltype);
|
||||
} else {
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"Unsupported non-32-bit ELF relocation");
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
p = mydata;
|
||||
WRITESHORT(p, *(int64_t *)data - size);
|
||||
elf_sect_write(s, mydata, 2L);
|
||||
} else if (type == OUT_REL4ADR) {
|
||||
elf_sect_write(s, mydata, bytes);
|
||||
break;
|
||||
|
||||
case OUT_REL4ADR:
|
||||
if (segment == segto)
|
||||
nasm_error(ERR_PANIC, "intra-segment OUT_REL4ADR");
|
||||
if (segment != NO_SEG && segment % 2) {
|
||||
@ -876,9 +901,18 @@ static void elf_out(int32_t segto, const void *data,
|
||||
wrt = NO_SEG; /* we can at least _try_ to continue */
|
||||
}
|
||||
}
|
||||
p = mydata;
|
||||
p = mydata;
|
||||
WRITELONG(p, *(int64_t *)data - size);
|
||||
elf_sect_write(s, mydata, 4L);
|
||||
break;
|
||||
|
||||
case OUT_REL8ADR:
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"32-bit ELF format does not support 64-bit relocations");
|
||||
p = mydata;
|
||||
WRITEDLONG(p, 0);
|
||||
elf_sect_write(s, mydata, 8L);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user