output: Allow OUT_ADDRESS with a negative size to mean signed relocation

This only matters for ELF64/ELFx32, at least for now.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2013-11-26 18:09:56 -08:00
parent 80d18b5555
commit fd52c277dd
13 changed files with 154 additions and 86 deletions

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -635,6 +635,7 @@ static void aout_out(int32_t segto, const void *data,
nasm_error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG"); nasm_error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
aout_sect_write(s, data, size); aout_sect_write(s, data, size);
} else if (type == OUT_ADDRESS) { } else if (type == OUT_ADDRESS) {
int asize = abs(size);
addr = *(int64_t *)data; addr = *(int64_t *)data;
if (segment != NO_SEG) { if (segment != NO_SEG) {
if (segment % 2) { if (segment % 2) {
@ -642,8 +643,7 @@ static void aout_out(int32_t segto, const void *data,
" segment base references"); " segment base references");
} else { } else {
if (wrt == NO_SEG) { if (wrt == NO_SEG) {
aout_add_reloc(s, segment, RELTYPE_ABSOLUTE, aout_add_reloc(s, segment, RELTYPE_ABSOLUTE, asize);
size);
} else if (!bsd) { } else if (!bsd) {
nasm_error(ERR_NONFATAL, nasm_error(ERR_NONFATAL,
"Linux a.out format does not support" "Linux a.out format does not support"
@ -651,19 +651,17 @@ static void aout_out(int32_t segto, const void *data,
wrt = NO_SEG; /* we can at least _try_ to continue */ wrt = NO_SEG; /* we can at least _try_ to continue */
} else if (wrt == aout_gotpc_sect + 1) { } else if (wrt == aout_gotpc_sect + 1) {
is_pic = 0x40; is_pic = 0x40;
aout_add_reloc(s, segment, RELTYPE_GOTPC, size); aout_add_reloc(s, segment, RELTYPE_GOTPC, asize);
} else if (wrt == aout_gotoff_sect + 1) { } else if (wrt == aout_gotoff_sect + 1) {
is_pic = 0x40; is_pic = 0x40;
addr = aout_add_gotoff_reloc(s, segment, addr = aout_add_gotoff_reloc(s, segment, addr, asize);
addr, size);
} else if (wrt == aout_got_sect + 1) { } else if (wrt == aout_got_sect + 1) {
is_pic = 0x40; is_pic = 0x40;
addr = addr = aout_add_gsym_reloc(s, segment, addr, RELTYPE_GOT,
aout_add_gsym_reloc(s, segment, addr, RELTYPE_GOT, asize, true);
size, true);
} else if (wrt == aout_sym_sect + 1) { } else if (wrt == aout_sym_sect + 1) {
addr = aout_add_gsym_reloc(s, segment, addr, addr = aout_add_gsym_reloc(s, segment, addr,
RELTYPE_ABSOLUTE, size, RELTYPE_ABSOLUTE, asize,
false); false);
} else if (wrt == aout_plt_sect + 1) { } else if (wrt == aout_plt_sect + 1) {
is_pic = 0x40; is_pic = 0x40;

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -345,19 +345,20 @@ static void as86_out(int32_t segto, const void *data,
as86_sect_write(s, data, size); as86_sect_write(s, data, size);
as86_add_piece(s, 0, 0L, 0L, size, 0); as86_add_piece(s, 0, 0L, 0L, size, 0);
} else if (type == OUT_ADDRESS) { } else if (type == OUT_ADDRESS) {
int asize = abs(size);
if (segment != NO_SEG) { if (segment != NO_SEG) {
if (segment % 2) { if (segment % 2) {
nasm_error(ERR_NONFATAL, "as86 format does not support" nasm_error(ERR_NONFATAL, "as86 format does not support"
" segment base references"); " segment base references");
} else { } else {
offset = *(int64_t *)data; offset = *(int64_t *)data;
as86_add_piece(s, 1, offset, segment, size, 0); as86_add_piece(s, 1, offset, segment, asize, 0);
} }
} else { } else {
p = mydata; p = mydata;
WRITELONG(p, *(int64_t *)data); WRITELONG(p, *(int64_t *)data);
as86_sect_write(s, data, size); as86_sect_write(s, data, asize);
as86_add_piece(s, 0, 0L, 0L, size, 0); as86_add_piece(s, 0, 0L, 0L, asize, 0);
} }
} else if (type == OUT_REL2ADR) { } else if (type == OUT_REL2ADR) {
if (segment == segto) if (segment == segto)

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -762,6 +762,9 @@ static void bin_out(int32_t segto, const void *data,
switch (type) { switch (type) {
case OUT_ADDRESS: case OUT_ADDRESS:
{
int asize = abs(size);
if (segment != NO_SEG && !find_section_by_index(segment)) { if (segment != NO_SEG && !find_section_by_index(segment)) {
if (segment % 2) if (segment % 2)
nasm_error(ERR_NONFATAL, "binary output format does not support" nasm_error(ERR_NONFATAL, "binary output format does not support"
@ -775,10 +778,11 @@ static void bin_out(int32_t segto, const void *data,
if (segment != NO_SEG) if (segment != NO_SEG)
add_reloc(s, size, segment, -1L); add_reloc(s, size, segment, -1L);
p = mydata; p = mydata;
WRITEADDR(p, *(int64_t *)data, size); WRITEADDR(p, *(int64_t *)data, asize);
saa_wbytes(s->contents, mydata, size); saa_wbytes(s->contents, mydata, asize);
} }
break; break;
}
case OUT_RAWDATA: case OUT_RAWDATA:
if (s->flags & TYPE_PROGBITS) if (s->flags & TYPE_PROGBITS)

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2010 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -646,8 +646,9 @@ static void coff_out(int32_t segto, const void *data,
nasm_error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG"); nasm_error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
coff_sect_write(s, data, size); coff_sect_write(s, data, size);
} else if (type == OUT_ADDRESS) { } else if (type == OUT_ADDRESS) {
if (!(win64)) { int asize = abs(size);
if (size != 4 && (segment != NO_SEG || wrt != NO_SEG)) { if (!win64) {
if (asize != 4 && (segment != NO_SEG || wrt != NO_SEG)) {
nasm_error(ERR_NONFATAL, "COFF format does not support non-32-bit" nasm_error(ERR_NONFATAL, "COFF format does not support non-32-bit"
" relocations"); " relocations");
} else { } else {
@ -664,25 +665,25 @@ static void coff_out(int32_t segto, const void *data,
} }
p = mydata; p = mydata;
WRITELONG(p, *(int64_t *)data + fix); WRITELONG(p, *(int64_t *)data + fix);
coff_sect_write(s, mydata, size); coff_sect_write(s, mydata, asize);
} }
} else { } else {
int32_t fix = 0; int32_t fix = 0;
p = mydata; p = mydata;
if (size == 8) { if (asize == 8) {
if (wrt == imagebase_sect) { if (wrt == imagebase_sect) {
nasm_error(ERR_NONFATAL, "operand size mismatch: 'wrt " nasm_error(ERR_NONFATAL, "operand size mismatch: 'wrt "
WRT_IMAGEBASE "' is a 32-bit operand"); WRT_IMAGEBASE "' is a 32-bit operand");
} }
fix = coff_add_reloc(s, segment, IMAGE_REL_AMD64_ADDR64); fix = coff_add_reloc(s, segment, IMAGE_REL_AMD64_ADDR64);
WRITEDLONG(p, *(int64_t *)data + fix); WRITEDLONG(p, *(int64_t *)data + fix);
coff_sect_write(s, mydata, size); coff_sect_write(s, mydata, asize);
} else { } else {
fix = coff_add_reloc(s, segment, fix = coff_add_reloc(s, segment,
wrt == imagebase_sect ? IMAGE_REL_AMD64_ADDR32NB: wrt == imagebase_sect ? IMAGE_REL_AMD64_ADDR32NB:
IMAGE_REL_AMD64_ADDR32); IMAGE_REL_AMD64_ADDR32);
WRITELONG(p, *(int64_t *)data + fix); WRITELONG(p, *(int64_t *)data + fix);
coff_sect_write(s, mydata, size); coff_sect_write(s, mydata, asize);
} }
} }
} else if (type == OUT_REL2ADR) { } else if (type == OUT_REL2ADR) {

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -127,7 +127,10 @@ static void dbg_out(int32_t segto, const void *data,
int32_t ldata; int32_t ldata;
int id; int id;
fprintf(ofile, "out to %"PRIx32", len = %"PRIu64": ", segto, size); if (type == OUT_ADDRESS)
fprintf(ofile, "out to %"PRIx32", len = %d: ", segto, (int)size);
else
fprintf(ofile, "out to %"PRIx32", len = %"PRIu64": ", segto, size);
switch (type) { switch (type) {
case OUT_RESERVE: case OUT_RESERVE:
@ -144,8 +147,8 @@ static void dbg_out(int32_t segto, const void *data,
break; break;
case OUT_ADDRESS: case OUT_ADDRESS:
ldata = *(int64_t *)data; ldata = *(int64_t *)data;
fprintf(ofile, "addr %08"PRIx32" (seg %08"PRIx32", wrt %08"PRIx32")\n", ldata, fprintf(ofile, "addr %08"PRIx32" (seg %08"PRIx32", wrt %08"PRIx32")\n",
segment, wrt); ldata, segment, wrt);
break; break;
case OUT_REL1ADR: case OUT_REL1ADR:
fprintf(ofile, "rel1adr %02"PRIx8" (seg %08"PRIx32")\n", fprintf(ofile, "rel1adr %02"PRIx8" (seg %08"PRIx32")\n",

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2010 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -767,6 +767,7 @@ static void elf_out(int32_t segto, const void *data,
case OUT_ADDRESS: case OUT_ADDRESS:
{ {
bool gnu16 = false; bool gnu16 = false;
int asize = abs(size);
addr = *(int64_t *)data; addr = *(int64_t *)data;
if (segment != NO_SEG) { if (segment != NO_SEG) {
if (segment % 2) { if (segment % 2) {
@ -779,22 +780,20 @@ static void elf_out(int32_t segto, const void *data,
* don't handle switch() statements with 64-bit * don't handle switch() statements with 64-bit
* expressions. * expressions.
*/ */
if (size < UINT_MAX) { switch (asize) {
switch ((unsigned int)size) { case 1:
case 1: gnu16 = true;
gnu16 = true; elf_add_reloc(s, segment, R_386_8);
elf_add_reloc(s, segment, R_386_8); break;
break; case 2:
case 2: gnu16 = true;
gnu16 = true; elf_add_reloc(s, segment, R_386_16);
elf_add_reloc(s, segment, R_386_16); break;
break; case 4:
case 4: elf_add_reloc(s, segment, R_386_32);
elf_add_reloc(s, segment, R_386_32); break;
break; default: /* Error issued further down */
default: /* Error issued further down */ break;
break;
}
} }
} else if (wrt == elf_gotpc_sect + 1) { } else if (wrt == elf_gotpc_sect + 1) {
/* /*
@ -813,13 +812,23 @@ static void elf_out(int32_t segto, const void *data,
addr = elf_add_gsym_reloc(s, segment, addr, addr = elf_add_gsym_reloc(s, segment, addr,
R_386_GOT32, true); R_386_GOT32, true);
} else if (wrt == elf_sym_sect + 1) { } else if (wrt == elf_sym_sect + 1) {
if (size == 2) { switch (asize) {
case 1:
gnu16 = true;
addr = elf_add_gsym_reloc(s, segment, addr,
R_386_8, false);
break;
case 2:
gnu16 = true; gnu16 = true;
addr = elf_add_gsym_reloc(s, segment, addr, addr = elf_add_gsym_reloc(s, segment, addr,
R_386_16, false); R_386_16, false);
} else { break;
case 4:
addr = elf_add_gsym_reloc(s, segment, addr, addr = elf_add_gsym_reloc(s, segment, addr,
R_386_32, false); R_386_32, false);
break;
default:
break;
} }
} else if (wrt == elf_plt_sect + 1) { } else if (wrt == elf_plt_sect + 1) {
nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-" nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
@ -835,7 +844,7 @@ static void elf_out(int32_t segto, const void *data,
if (gnu16) { if (gnu16) {
nasm_error(ERR_WARNING | ERR_WARN_GNUELF, nasm_error(ERR_WARNING | ERR_WARN_GNUELF,
"8- or 16-bit relocations in ELF32 is a GNU extension"); "8- or 16-bit relocations in ELF32 is a GNU extension");
} else if (size != 4 && segment != NO_SEG) { } else if (asize != 4 && segment != NO_SEG) {
nasm_error(ERR_NONFATAL, "Unsupported non-32-bit ELF relocation"); nasm_error(ERR_NONFATAL, "Unsupported non-32-bit ELF relocation");
} }
WRITEADDR(p, addr, size); WRITEADDR(p, addr, size);

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2010 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -785,6 +785,10 @@ static void elf_out(int32_t segto, const void *data,
break; break;
case OUT_ADDRESS: case OUT_ADDRESS:
{
int isize = (int)size;
int asize = abs(size);
addr = *(int64_t *)data; addr = *(int64_t *)data;
if (segment == NO_SEG) { if (segment == NO_SEG) {
/* Do nothing */ /* Do nothing */
@ -793,17 +797,23 @@ static void elf_out(int32_t segto, const void *data,
" segment base references"); " segment base references");
} else { } else {
if (wrt == NO_SEG) { if (wrt == NO_SEG) {
switch ((int)size) { switch (isize) {
case 1: case 1:
case -1:
elf_add_reloc(s, segment, addr, R_X86_64_8); elf_add_reloc(s, segment, addr, R_X86_64_8);
break; break;
case 2: case 2:
case -2:
elf_add_reloc(s, segment, addr, R_X86_64_16); elf_add_reloc(s, segment, addr, R_X86_64_16);
break; break;
case 4: case 4:
elf_add_reloc(s, segment, addr, R_X86_64_32); elf_add_reloc(s, segment, addr, R_X86_64_32);
break; break;
case -4:
elf_add_reloc(s, segment, addr, R_X86_64_32S);
break;
case 8: case 8:
case -8:
elf_add_reloc(s, segment, addr, R_X86_64_64); elf_add_reloc(s, segment, addr, R_X86_64_64);
break; break;
default: default:
@ -821,7 +831,7 @@ static void elf_out(int32_t segto, const void *data,
elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32); elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
addr = 0; addr = 0;
} else if (wrt == elf_gotoff_sect + 1) { } else if (wrt == elf_gotoff_sect + 1) {
if (size != 8) { if (asize != 8) {
nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff " nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff "
"references to be qword"); "references to be qword");
} else { } else {
@ -829,7 +839,7 @@ static void elf_out(int32_t segto, const void *data,
addr = 0; addr = 0;
} }
} else if (wrt == elf_got_sect + 1) { } else if (wrt == elf_got_sect + 1) {
switch ((int)size) { switch (asize) {
case 4: case 4:
elf_add_gsym_reloc(s, segment, addr, 0, elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_GOT32, true); R_X86_64_GOT32, true);
@ -845,13 +855,15 @@ static void elf_out(int32_t segto, const void *data,
break; break;
} }
} else if (wrt == elf_sym_sect + 1) { } else if (wrt == elf_sym_sect + 1) {
switch ((int)size) { switch (isize) {
case 1: case 1:
case -1:
elf_add_gsym_reloc(s, segment, addr, 0, elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_8, false); R_X86_64_8, false);
addr = 0; addr = 0;
break; break;
case 2: case 2:
case -2:
elf_add_gsym_reloc(s, segment, addr, 0, elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_16, false); R_X86_64_16, false);
addr = 0; addr = 0;
@ -861,7 +873,13 @@ static void elf_out(int32_t segto, const void *data,
R_X86_64_32, false); R_X86_64_32, false);
addr = 0; addr = 0;
break; break;
case -4:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_32S, false);
addr = 0;
break;
case 8: case 8:
case -8:
elf_add_gsym_reloc(s, segment, addr, 0, elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_64, false); R_X86_64_64, false);
addr = 0; addr = 0;
@ -878,8 +896,9 @@ static void elf_out(int32_t segto, const void *data,
" use of WRT"); " use of WRT");
} }
} }
elf_sect_writeaddr(s, addr, size); elf_sect_writeaddr(s, addr, asize);
break; break;
}
case OUT_REL1ADR: case OUT_REL1ADR:
reltype = R_X86_64_PC8; reltype = R_X86_64_PC8;

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 2012 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -783,6 +783,10 @@ static void elf_out(int32_t segto, const void *data,
break; break;
case OUT_ADDRESS: case OUT_ADDRESS:
{
int isize = (int)size;
int asize = abs(size);
addr = *(int64_t *)data; addr = *(int64_t *)data;
if (segment == NO_SEG) { if (segment == NO_SEG) {
/* Do nothing */ /* Do nothing */
@ -791,17 +795,23 @@ static void elf_out(int32_t segto, const void *data,
" segment base references"); " segment base references");
} else { } else {
if (wrt == NO_SEG) { if (wrt == NO_SEG) {
switch ((int)size) { switch (isize) {
case 1: case 1:
case -1:
elf_add_reloc(s, segment, addr, R_X86_64_8); elf_add_reloc(s, segment, addr, R_X86_64_8);
break; break;
case 2: case 2:
case -2:
elf_add_reloc(s, segment, addr, R_X86_64_16); elf_add_reloc(s, segment, addr, R_X86_64_16);
break; break;
case 4: case 4:
elf_add_reloc(s, segment, addr, R_X86_64_32); elf_add_reloc(s, segment, addr, R_X86_64_32);
break; break;
case -4:
elf_add_reloc(s, segment, addr, R_X86_64_32S);
break;
case 8: case 8:
case -8:
elf_add_reloc(s, segment, addr, R_X86_64_64); elf_add_reloc(s, segment, addr, R_X86_64_64);
break; break;
default: default:
@ -822,7 +832,7 @@ static void elf_out(int32_t segto, const void *data,
nasm_error(ERR_NONFATAL, "ELFX32 doesn't support " nasm_error(ERR_NONFATAL, "ELFX32 doesn't support "
"R_X86_64_GOTOFF64"); "R_X86_64_GOTOFF64");
} else if (wrt == elf_got_sect + 1) { } else if (wrt == elf_got_sect + 1) {
switch ((int)size) { switch (asize) {
case 4: case 4:
elf_add_gsym_reloc(s, segment, addr, 0, elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_GOT32, true); R_X86_64_GOT32, true);
@ -833,13 +843,15 @@ static void elf_out(int32_t segto, const void *data,
break; break;
} }
} else if (wrt == elf_sym_sect + 1) { } else if (wrt == elf_sym_sect + 1) {
switch ((int)size) { switch (isize) {
case 1: case 1:
case -1:
elf_add_gsym_reloc(s, segment, addr, 0, elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_8, false); R_X86_64_8, false);
addr = 0; addr = 0;
break; break;
case 2: case 2:
case -2:
elf_add_gsym_reloc(s, segment, addr, 0, elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_16, false); R_X86_64_16, false);
addr = 0; addr = 0;
@ -849,7 +861,13 @@ static void elf_out(int32_t segto, const void *data,
R_X86_64_32, false); R_X86_64_32, false);
addr = 0; addr = 0;
break; break;
case -4:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_32S, false);
addr = 0;
break;
case 8: case 8:
case -8:
elf_add_gsym_reloc(s, segment, addr, 0, elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_64, false); R_X86_64_64, false);
addr = 0; addr = 0;
@ -866,8 +884,9 @@ static void elf_out(int32_t segto, const void *data,
" use of WRT"); " use of WRT");
} }
} }
elf_sect_writeaddr(s, addr, size); elf_sect_writeaddr(s, addr, asize);
break; break;
}
case OUT_REL1ADR: case OUT_REL1ADR:
reltype = R_X86_64_PC8; reltype = R_X86_64_PC8;

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -437,7 +437,9 @@ static void ieee_out(int32_t segto, const void *data,
ieee_write_byte(seg, *ucdata++); ieee_write_byte(seg, *ucdata++);
} else if (type == OUT_ADDRESS || type == OUT_REL2ADR || } else if (type == OUT_ADDRESS || type == OUT_REL2ADR ||
type == OUT_REL4ADR) { type == OUT_REL4ADR) {
if (segment == NO_SEG && type != OUT_ADDRESS) if (type == OUT_ADDRESS)
size = abs(size);
else if (segment == NO_SEG)
nasm_error(ERR_NONFATAL, "relative call to absolute address not" nasm_error(ERR_NONFATAL, "relative call to absolute address not"
" supported by IEEE format"); " supported by IEEE format");
ldata = *(int64_t *)data; ldata = *(int64_t *)data;

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -431,20 +431,24 @@ static void macho_output(int32_t secto, const void *data,
break; break;
case OUT_ADDRESS: case OUT_ADDRESS:
addr = *(int64_t *)data; {
int asize = abs(size);
if (section != NO_SEG) {
if (section % 2) { addr = *(int64_t *)data;
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
" section base references"); if (section != NO_SEG) {
} else if (section % 2) {
add_reloc(s, section, 0, size); nasm_error(ERR_NONFATAL, "Mach-O format does not support"
} " section base references");
} else
p = mydata; add_reloc(s, section, 0, asize);
WRITEADDR(p, addr, size); }
sect_write(s, mydata, size);
break; p = mydata;
WRITEADDR(p, addr, asize);
sect_write(s, mydata, asize);
break;
}
case OUT_REL2ADR: case OUT_REL2ADR:
if (section == secto) if (section == secto)

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -528,6 +528,9 @@ static void macho_output(int32_t secto, const void *data,
break; break;
case OUT_ADDRESS: case OUT_ADDRESS:
{
int asize = abs(size);
addr = *(int64_t *)data; addr = *(int64_t *)data;
if (section != NO_SEG) { if (section != NO_SEG) {
if (section % 2) { if (section % 2) {
@ -535,7 +538,7 @@ static void macho_output(int32_t secto, const void *data,
" section base references"); " section base references");
} else { } else {
if (wrt == NO_SEG) { if (wrt == NO_SEG) {
if (size < 8) { if (asize < 8) {
nasm_error(ERR_NONFATAL, "Mach-O 64-bit format does not support" nasm_error(ERR_NONFATAL, "Mach-O 64-bit format does not support"
" 32-bit absolute addresses"); " 32-bit absolute addresses");
/* /*
@ -544,7 +547,7 @@ static void macho_output(int32_t secto, const void *data,
making it impractical for use in intermediate object files making it impractical for use in intermediate object files
*/ */
} else { } else {
addr -= add_reloc(s, section, 0, size, addr); // X86_64_RELOC_UNSIGNED addr -= add_reloc(s, section, 0, asize, addr); // X86_64_RELOC_UNSIGNED
} }
} else { } else {
nasm_error(ERR_NONFATAL, "Mach-O format does not support" nasm_error(ERR_NONFATAL, "Mach-O format does not support"
@ -554,9 +557,10 @@ static void macho_output(int32_t secto, const void *data,
} }
p = mydata; p = mydata;
WRITEADDR(p, addr, size); WRITEADDR(p, addr, asize);
sect_write(s, mydata, size); sect_write(s, mydata, asize);
break; break;
}
case OUT_REL2ADR: case OUT_REL2ADR:
p = mydata; p = mydata;

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -1086,6 +1086,9 @@ static void obj_out(int32_t segto, const void *data,
{ {
int rsize; int rsize;
if (type == OUT_ADDRESS)
size = abs(size);
if (segment == NO_SEG && type != OUT_ADDRESS) if (segment == NO_SEG && type != OUT_ADDRESS)
nasm_error(ERR_NONFATAL, "relative call to absolute address not" nasm_error(ERR_NONFATAL, "relative call to absolute address not"
" supported by OBJ format"); " supported by OBJ format");

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* *
* Copyright 1996-2009 The NASM Authors - All Rights Reserved * Copyright 1996-2013 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -583,6 +583,7 @@ static void rdf2_out(int32_t segto, const void *data,
membufwrite(segto, data, size); membufwrite(segto, data, size);
} else if (type == OUT_ADDRESS) { } else if (type == OUT_ADDRESS) {
int asize = abs(size);
/* if segment == NO_SEG then we are writing an address of an /* if segment == NO_SEG then we are writing an address of an
object within the same segment - do not produce reloc rec. */ object within the same segment - do not produce reloc rec. */
@ -597,14 +598,14 @@ static void rdf2_out(int32_t segto, const void *data,
rr.reclen = 8; rr.reclen = 8;
rr.segment = segto; /* segment we're currently in */ rr.segment = segto; /* segment we're currently in */
rr.offset = getsegmentlength(segto); /* current offset */ rr.offset = getsegmentlength(segto); /* current offset */
rr.length = size; /* length of reference */ rr.length = asize; /* length of reference */
rr.refseg = segment; /* segment referred to */ rr.refseg = segment; /* segment referred to */
write_reloc_rec(&rr); write_reloc_rec(&rr);
} }
pd = databuf; /* convert address to little-endian */ pd = databuf; /* convert address to little-endian */
WRITEADDR(pd, *(int64_t *)data, size); WRITEADDR(pd, *(int64_t *)data, asize);
membufwrite(segto, databuf, size); membufwrite(segto, databuf, asize);
} else if (type == OUT_REL2ADR) { } else if (type == OUT_REL2ADR) {
if (segment == segto) if (segment == segto)
nasm_error(ERR_PANIC, "intra-segment OUT_REL2ADR"); nasm_error(ERR_PANIC, "intra-segment OUT_REL2ADR");