summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2013-11-26 18:09:56 -0800
committerH. Peter Anvin <hpa@zytor.com>2013-11-26 18:12:39 -0800
commitfd52c277dd6d768545cee39b154e706904581966 (patch)
tree57ffb4113bc8871ca3679ae765c92a1076efa297
parent80d18b55551e43f0c3e390550ecd396b90265fd3 (diff)
downloadnasm-fd52c277dd6d768545cee39b154e706904581966.tar.gz
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>
-rw-r--r--output/outaout.c18
-rw-r--r--output/outas86.c9
-rw-r--r--output/outbin.c10
-rw-r--r--output/outcoff.c15
-rw-r--r--output/outdbg.c11
-rw-r--r--output/outelf32.c49
-rw-r--r--output/outelf64.c31
-rw-r--r--output/outelfx32.c29
-rw-r--r--output/outieee.c6
-rw-r--r--output/outmac32.c34
-rw-r--r--output/outmac64.c14
-rw-r--r--output/outobj.c5
-rw-r--r--output/outrdf2.c9
13 files changed, 154 insertions, 86 deletions
diff --git a/output/outaout.c b/output/outaout.c
index e0963924..b9f21ec6 100644
--- a/output/outaout.c
+++ b/output/outaout.c
@@ -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
* 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");
aout_sect_write(s, data, size);
} else if (type == OUT_ADDRESS) {
+ int asize = abs(size);
addr = *(int64_t *)data;
if (segment != NO_SEG) {
if (segment % 2) {
@@ -642,8 +643,7 @@ static void aout_out(int32_t segto, const void *data,
" segment base references");
} else {
if (wrt == NO_SEG) {
- aout_add_reloc(s, segment, RELTYPE_ABSOLUTE,
- size);
+ aout_add_reloc(s, segment, RELTYPE_ABSOLUTE, asize);
} else if (!bsd) {
nasm_error(ERR_NONFATAL,
"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 */
} else if (wrt == aout_gotpc_sect + 1) {
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) {
is_pic = 0x40;
- addr = aout_add_gotoff_reloc(s, segment,
- addr, size);
+ addr = aout_add_gotoff_reloc(s, segment, addr, asize);
} else if (wrt == aout_got_sect + 1) {
is_pic = 0x40;
- addr =
- aout_add_gsym_reloc(s, segment, addr, RELTYPE_GOT,
- size, true);
+ addr = aout_add_gsym_reloc(s, segment, addr, RELTYPE_GOT,
+ asize, true);
} else if (wrt == aout_sym_sect + 1) {
addr = aout_add_gsym_reloc(s, segment, addr,
- RELTYPE_ABSOLUTE, size,
+ RELTYPE_ABSOLUTE, asize,
false);
} else if (wrt == aout_plt_sect + 1) {
is_pic = 0x40;
diff --git a/output/outas86.c b/output/outas86.c
index b288637b..7af8d785 100644
--- a/output/outas86.c
+++ b/output/outas86.c
@@ -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
* 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_add_piece(s, 0, 0L, 0L, size, 0);
} else if (type == OUT_ADDRESS) {
+ int asize = abs(size);
if (segment != NO_SEG) {
if (segment % 2) {
nasm_error(ERR_NONFATAL, "as86 format does not support"
" segment base references");
} else {
offset = *(int64_t *)data;
- as86_add_piece(s, 1, offset, segment, size, 0);
+ as86_add_piece(s, 1, offset, segment, asize, 0);
}
} else {
p = mydata;
WRITELONG(p, *(int64_t *)data);
- as86_sect_write(s, data, size);
- as86_add_piece(s, 0, 0L, 0L, size, 0);
+ as86_sect_write(s, data, asize);
+ as86_add_piece(s, 0, 0L, 0L, asize, 0);
}
} else if (type == OUT_REL2ADR) {
if (segment == segto)
diff --git a/output/outbin.c b/output/outbin.c
index 21c042db..6dc4b2a6 100644
--- a/output/outbin.c
+++ b/output/outbin.c
@@ -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
* the specific copyright holders.
*
@@ -762,6 +762,9 @@ static void bin_out(int32_t segto, const void *data,
switch (type) {
case OUT_ADDRESS:
+ {
+ int asize = abs(size);
+
if (segment != NO_SEG && !find_section_by_index(segment)) {
if (segment % 2)
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)
add_reloc(s, size, segment, -1L);
p = mydata;
- WRITEADDR(p, *(int64_t *)data, size);
- saa_wbytes(s->contents, mydata, size);
+ WRITEADDR(p, *(int64_t *)data, asize);
+ saa_wbytes(s->contents, mydata, asize);
}
break;
+ }
case OUT_RAWDATA:
if (s->flags & TYPE_PROGBITS)
diff --git a/output/outcoff.c b/output/outcoff.c
index d0fcb775..3949028b 100644
--- a/output/outcoff.c
+++ b/output/outcoff.c
@@ -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
* 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");
coff_sect_write(s, data, size);
} else if (type == OUT_ADDRESS) {
- if (!(win64)) {
- if (size != 4 && (segment != NO_SEG || wrt != NO_SEG)) {
+ int asize = abs(size);
+ if (!win64) {
+ if (asize != 4 && (segment != NO_SEG || wrt != NO_SEG)) {
nasm_error(ERR_NONFATAL, "COFF format does not support non-32-bit"
" relocations");
} else {
@@ -664,25 +665,25 @@ static void coff_out(int32_t segto, const void *data,
}
p = mydata;
WRITELONG(p, *(int64_t *)data + fix);
- coff_sect_write(s, mydata, size);
+ coff_sect_write(s, mydata, asize);
}
} else {
int32_t fix = 0;
p = mydata;
- if (size == 8) {
+ if (asize == 8) {
if (wrt == imagebase_sect) {
nasm_error(ERR_NONFATAL, "operand size mismatch: 'wrt "
WRT_IMAGEBASE "' is a 32-bit operand");
}
fix = coff_add_reloc(s, segment, IMAGE_REL_AMD64_ADDR64);
WRITEDLONG(p, *(int64_t *)data + fix);
- coff_sect_write(s, mydata, size);
+ coff_sect_write(s, mydata, asize);
} else {
fix = coff_add_reloc(s, segment,
wrt == imagebase_sect ? IMAGE_REL_AMD64_ADDR32NB:
IMAGE_REL_AMD64_ADDR32);
WRITELONG(p, *(int64_t *)data + fix);
- coff_sect_write(s, mydata, size);
+ coff_sect_write(s, mydata, asize);
}
}
} else if (type == OUT_REL2ADR) {
diff --git a/output/outdbg.c b/output/outdbg.c
index 2b750396..bf145585 100644
--- a/output/outdbg.c
+++ b/output/outdbg.c
@@ -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
* the specific copyright holders.
*
@@ -127,7 +127,10 @@ static void dbg_out(int32_t segto, const void *data,
int32_t ldata;
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) {
case OUT_RESERVE:
@@ -144,8 +147,8 @@ static void dbg_out(int32_t segto, const void *data,
break;
case OUT_ADDRESS:
ldata = *(int64_t *)data;
- fprintf(ofile, "addr %08"PRIx32" (seg %08"PRIx32", wrt %08"PRIx32")\n", ldata,
- segment, wrt);
+ fprintf(ofile, "addr %08"PRIx32" (seg %08"PRIx32", wrt %08"PRIx32")\n",
+ ldata, segment, wrt);
break;
case OUT_REL1ADR:
fprintf(ofile, "rel1adr %02"PRIx8" (seg %08"PRIx32")\n",
diff --git a/output/outelf32.c b/output/outelf32.c
index 48f91776..413270bf 100644
--- a/output/outelf32.c
+++ b/output/outelf32.c
@@ -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
* the specific copyright holders.
*
@@ -767,6 +767,7 @@ static void elf_out(int32_t segto, const void *data,
case OUT_ADDRESS:
{
bool gnu16 = false;
+ int asize = abs(size);
addr = *(int64_t *)data;
if (segment != NO_SEG) {
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
* expressions.
*/
- if (size < UINT_MAX) {
- switch ((unsigned int)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);
- break;
- case 4:
- elf_add_reloc(s, segment, R_386_32);
- break;
- default: /* Error issued further down */
- break;
- }
+ switch (asize) {
+ 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);
+ 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) {
/*
@@ -813,13 +812,23 @@ static void elf_out(int32_t segto, const void *data,
addr = elf_add_gsym_reloc(s, segment, addr,
R_386_GOT32, true);
} 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;
addr = elf_add_gsym_reloc(s, segment, addr,
R_386_16, false);
- } else {
+ break;
+ case 4:
addr = elf_add_gsym_reloc(s, segment, addr,
R_386_32, false);
+ break;
+ default:
+ break;
}
} else if (wrt == elf_plt_sect + 1) {
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) {
nasm_error(ERR_WARNING | ERR_WARN_GNUELF,
"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");
}
WRITEADDR(p, addr, size);
diff --git a/output/outelf64.c b/output/outelf64.c
index 8175aedc..9f93fc82 100644
--- a/output/outelf64.c
+++ b/output/outelf64.c
@@ -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
* the specific copyright holders.
*
@@ -785,6 +785,10 @@ static void elf_out(int32_t segto, const void *data,
break;
case OUT_ADDRESS:
+ {
+ int isize = (int)size;
+ int asize = abs(size);
+
addr = *(int64_t *)data;
if (segment == NO_SEG) {
/* Do nothing */
@@ -793,17 +797,23 @@ static void elf_out(int32_t segto, const void *data,
" segment base references");
} else {
if (wrt == NO_SEG) {
- switch ((int)size) {
+ switch (isize) {
case 1:
+ case -1:
elf_add_reloc(s, segment, addr, R_X86_64_8);
break;
case 2:
+ case -2:
elf_add_reloc(s, segment, addr, R_X86_64_16);
break;
case 4:
elf_add_reloc(s, segment, addr, R_X86_64_32);
break;
+ case -4:
+ elf_add_reloc(s, segment, addr, R_X86_64_32S);
+ break;
case 8:
+ case -8:
elf_add_reloc(s, segment, addr, R_X86_64_64);
break;
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);
addr = 0;
} else if (wrt == elf_gotoff_sect + 1) {
- if (size != 8) {
+ if (asize != 8) {
nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff "
"references to be qword");
} else {
@@ -829,7 +839,7 @@ static void elf_out(int32_t segto, const void *data,
addr = 0;
}
} else if (wrt == elf_got_sect + 1) {
- switch ((int)size) {
+ switch (asize) {
case 4:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_GOT32, true);
@@ -845,13 +855,15 @@ static void elf_out(int32_t segto, const void *data,
break;
}
} else if (wrt == elf_sym_sect + 1) {
- switch ((int)size) {
+ switch (isize) {
case 1:
+ case -1:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_8, false);
addr = 0;
break;
case 2:
+ case -2:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_16, false);
addr = 0;
@@ -861,7 +873,13 @@ static void elf_out(int32_t segto, const void *data,
R_X86_64_32, false);
addr = 0;
break;
+ case -4:
+ elf_add_gsym_reloc(s, segment, addr, 0,
+ R_X86_64_32S, false);
+ addr = 0;
+ break;
case 8:
+ case -8:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_64, false);
addr = 0;
@@ -878,8 +896,9 @@ static void elf_out(int32_t segto, const void *data,
" use of WRT");
}
}
- elf_sect_writeaddr(s, addr, size);
+ elf_sect_writeaddr(s, addr, asize);
break;
+ }
case OUT_REL1ADR:
reltype = R_X86_64_PC8;
diff --git a/output/outelfx32.c b/output/outelfx32.c
index 57bbf75b..bbedc482 100644
--- a/output/outelfx32.c
+++ b/output/outelfx32.c
@@ -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
* the specific copyright holders.
*
@@ -783,6 +783,10 @@ static void elf_out(int32_t segto, const void *data,
break;
case OUT_ADDRESS:
+ {
+ int isize = (int)size;
+ int asize = abs(size);
+
addr = *(int64_t *)data;
if (segment == NO_SEG) {
/* Do nothing */
@@ -791,17 +795,23 @@ static void elf_out(int32_t segto, const void *data,
" segment base references");
} else {
if (wrt == NO_SEG) {
- switch ((int)size) {
+ switch (isize) {
case 1:
+ case -1:
elf_add_reloc(s, segment, addr, R_X86_64_8);
break;
case 2:
+ case -2:
elf_add_reloc(s, segment, addr, R_X86_64_16);
break;
case 4:
elf_add_reloc(s, segment, addr, R_X86_64_32);
break;
+ case -4:
+ elf_add_reloc(s, segment, addr, R_X86_64_32S);
+ break;
case 8:
+ case -8:
elf_add_reloc(s, segment, addr, R_X86_64_64);
break;
default:
@@ -822,7 +832,7 @@ static void elf_out(int32_t segto, const void *data,
nasm_error(ERR_NONFATAL, "ELFX32 doesn't support "
"R_X86_64_GOTOFF64");
} else if (wrt == elf_got_sect + 1) {
- switch ((int)size) {
+ switch (asize) {
case 4:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_GOT32, true);
@@ -833,13 +843,15 @@ static void elf_out(int32_t segto, const void *data,
break;
}
} else if (wrt == elf_sym_sect + 1) {
- switch ((int)size) {
+ switch (isize) {
case 1:
+ case -1:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_8, false);
addr = 0;
break;
case 2:
+ case -2:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_16, false);
addr = 0;
@@ -849,7 +861,13 @@ static void elf_out(int32_t segto, const void *data,
R_X86_64_32, false);
addr = 0;
break;
+ case -4:
+ elf_add_gsym_reloc(s, segment, addr, 0,
+ R_X86_64_32S, false);
+ addr = 0;
+ break;
case 8:
+ case -8:
elf_add_gsym_reloc(s, segment, addr, 0,
R_X86_64_64, false);
addr = 0;
@@ -866,8 +884,9 @@ static void elf_out(int32_t segto, const void *data,
" use of WRT");
}
}
- elf_sect_writeaddr(s, addr, size);
+ elf_sect_writeaddr(s, addr, asize);
break;
+ }
case OUT_REL1ADR:
reltype = R_X86_64_PC8;
diff --git a/output/outieee.c b/output/outieee.c
index 94d5e598..5377ec61 100644
--- a/output/outieee.c
+++ b/output/outieee.c
@@ -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
* the specific copyright holders.
*
@@ -437,7 +437,9 @@ static void ieee_out(int32_t segto, const void *data,
ieee_write_byte(seg, *ucdata++);
} else if (type == OUT_ADDRESS || type == OUT_REL2ADR ||
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"
" supported by IEEE format");
ldata = *(int64_t *)data;
diff --git a/output/outmac32.c b/output/outmac32.c
index a13e0d9b..c2c91b48 100644
--- a/output/outmac32.c
+++ b/output/outmac32.c
@@ -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
* the specific copyright holders.
*
@@ -431,20 +431,24 @@ static void macho_output(int32_t secto, const void *data,
break;
case OUT_ADDRESS:
- addr = *(int64_t *)data;
-
- if (section != NO_SEG) {
- if (section % 2) {
- nasm_error(ERR_NONFATAL, "Mach-O format does not support"
- " section base references");
- } else
- add_reloc(s, section, 0, size);
- }
-
- p = mydata;
- WRITEADDR(p, addr, size);
- sect_write(s, mydata, size);
- break;
+ {
+ int asize = abs(size);
+
+ addr = *(int64_t *)data;
+
+ if (section != NO_SEG) {
+ if (section % 2) {
+ nasm_error(ERR_NONFATAL, "Mach-O format does not support"
+ " section base references");
+ } else
+ add_reloc(s, section, 0, asize);
+ }
+
+ p = mydata;
+ WRITEADDR(p, addr, asize);
+ sect_write(s, mydata, asize);
+ break;
+ }
case OUT_REL2ADR:
if (section == secto)
diff --git a/output/outmac64.c b/output/outmac64.c
index 358ae6e4..abad84aa 100644
--- a/output/outmac64.c
+++ b/output/outmac64.c
@@ -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
* the specific copyright holders.
*
@@ -528,6 +528,9 @@ static void macho_output(int32_t secto, const void *data,
break;
case OUT_ADDRESS:
+ {
+ int asize = abs(size);
+
addr = *(int64_t *)data;
if (section != NO_SEG) {
if (section % 2) {
@@ -535,7 +538,7 @@ static void macho_output(int32_t secto, const void *data,
" section base references");
} else {
if (wrt == NO_SEG) {
- if (size < 8) {
+ if (asize < 8) {
nasm_error(ERR_NONFATAL, "Mach-O 64-bit format does not support"
" 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
*/
} 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 {
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;
- WRITEADDR(p, addr, size);
- sect_write(s, mydata, size);
+ WRITEADDR(p, addr, asize);
+ sect_write(s, mydata, asize);
break;
+ }
case OUT_REL2ADR:
p = mydata;
diff --git a/output/outobj.c b/output/outobj.c
index 6fa54190..7fa29b27 100644
--- a/output/outobj.c
+++ b/output/outobj.c
@@ -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
* the specific copyright holders.
*
@@ -1086,6 +1086,9 @@ static void obj_out(int32_t segto, const void *data,
{
int rsize;
+ if (type == OUT_ADDRESS)
+ size = abs(size);
+
if (segment == NO_SEG && type != OUT_ADDRESS)
nasm_error(ERR_NONFATAL, "relative call to absolute address not"
" supported by OBJ format");
diff --git a/output/outrdf2.c b/output/outrdf2.c
index 02518a1a..c7aeb28b 100644
--- a/output/outrdf2.c
+++ b/output/outrdf2.c
@@ -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
* the specific copyright holders.
*
@@ -583,6 +583,7 @@ static void rdf2_out(int32_t segto, const void *data,
membufwrite(segto, data, size);
} else if (type == OUT_ADDRESS) {
+ int asize = abs(size);
/* if segment == NO_SEG then we are writing an address of an
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.segment = segto; /* segment we're currently in */
rr.offset = getsegmentlength(segto); /* current offset */
- rr.length = size; /* length of reference */
+ rr.length = asize; /* length of reference */
rr.refseg = segment; /* segment referred to */
write_reloc_rec(&rr);
}
pd = databuf; /* convert address to little-endian */
- WRITEADDR(pd, *(int64_t *)data, size);
- membufwrite(segto, databuf, size);
+ WRITEADDR(pd, *(int64_t *)data, asize);
+ membufwrite(segto, databuf, asize);
} else if (type == OUT_REL2ADR) {
if (segment == segto)
nasm_error(ERR_PANIC, "intra-segment OUT_REL2ADR");