From: H. Peter Anvin Date: Tue, 7 Oct 2008 02:11:07 +0000 (-0700) Subject: BR 2148448: Fix RIP-relative addressing with an immediate X-Git-Tag: nasm-2.11.05~1226 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9f8171317d27fbee3326ed2ffc917de2c7f1dd42;p=platform%2Fupstream%2Fnasm.git BR 2148448: Fix RIP-relative addressing with an immediate When there is an immediate in the instruction, a RIP-relative offset may not be relative to the end of the offset itself, since it is relative to the end of the *instruction*, not the end of the *offset*. Signed-off-by: H. Peter Anvin --- diff --git a/assemble.c b/assemble.c index d6abeac..d7e9eae 100644 --- a/assemble.c +++ b/assemble.c @@ -796,7 +796,7 @@ static bool is_sbyte64(operand *o) return v >= -128 && v <= 127; } static int64_t calcsize(int32_t segment, int64_t offset, int bits, - insn * ins, const uint8_t *codes) + insn * ins, const uint8_t *codes) { int64_t length = 0; uint8_t c; @@ -1777,6 +1777,7 @@ static void gencode(int32_t segment, int64_t offset, int bits, int32_t rflags; uint8_t *p; int32_t s; + enum out_type type; if (c <= 0177) { /* pick rfield from operand b */ @@ -1840,12 +1841,16 @@ static void gencode(int32_t segment, int64_t offset, int bits, case 4: data = ins->oprs[(c >> 3) & 7].offset; warn_overflow(ea_data.bytes, opx); - out(offset, segment, &data, - ea_data.rip ? OUT_REL4ADR : OUT_ADDRESS, - ea_data.bytes, - ins->oprs[(c >> 3) & 7].segment, - ins->oprs[(c >> 3) & 7].wrt); s += ea_data.bytes; + if (ea_data.rip) { + data -= insn_end - (offset+ea_data.bytes); + type = OUT_REL4ADR; + } else { + type = OUT_ADDRESS; + } + out(offset, segment, &data, type, ea_data.bytes, + ins->oprs[(c >> 3) & 7].segment, + ins->oprs[(c >> 3) & 7].wrt); break; } offset += s; diff --git a/test/riprel2.asm b/test/riprel2.asm new file mode 100644 index 0000000..2d13d3e --- /dev/null +++ b/test/riprel2.asm @@ -0,0 +1,11 @@ +;Testname=unoptimized; Arguments=-fbin -oriprel2.bin -O0; Files=stdout stderr riprel.bin +;Testname=optimized; Arguments=-fbin -oriprel2.bin -Ox; Files=stdout stderr riprel.bin + + bits 64 + + default rel + mov dword [foo],12345678h + mov qword [foo],12345678h + mov [foo],rax + mov dword [foo],12345678h +foo: