forked from OSchip/llvm-project
[ELF] - Relax checks for R_386_8/R_386_16 relocations.
This fixes PR36927. The issue is next. Imagine we have -Ttext 0x7c and code below. .code16 .global _start _start: movb $_start+0x83,%ah So we have R_386_8 relocation and _start at 0x7C. Addend is 0x83 == 131. We will sign extend it to 0xffffffffffffff83. Now, 0xffffffffffffff83 + 0x7c gives us 0xFFFFFFFFFFFFFFFF. Techically 0x83 + 0x7c == 0xFF, we do not exceed 1 byte value, but currently LLD errors out, because we use checkUInt<8>. Let's try to use checkInt<8> now and the following code to see if it can help (no): main.s: .byte foo input.s: .globl foo .hidden foo foo = 0xff Here, foo is 0xFF. And addend is 0x0. Final value is 0x00000000000000FF. Again, it fits one byte well, but with checkInt<8>, we would error out it, so we can't use it. What we want to do is to check that the result fits 1 byte well. Patch changes the check to checkIntUInt to fix the issue. Differential revision: https://reviews.llvm.org/D45051 llvm-svn: 329061
This commit is contained in:
parent
bfbeecdc5d
commit
bc1d58a6b1
|
@ -255,7 +255,7 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
|||
// R_386_{PC,}{8,16} are not part of the i386 psABI, but they are
|
||||
// being used for some 16-bit programs such as boot loaders, so
|
||||
// we want to support them.
|
||||
checkUInt(Loc, Val, 8, Type);
|
||||
checkIntUInt(Loc, Val, 8, Type);
|
||||
*Loc = Val;
|
||||
break;
|
||||
case R_386_PC8:
|
||||
|
@ -263,7 +263,7 @@ void X86::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
|||
*Loc = Val;
|
||||
break;
|
||||
case R_386_16:
|
||||
checkUInt(Loc, Val, 16, Type);
|
||||
checkIntUInt(Loc, Val, 16, Type);
|
||||
write16le(Loc, Val);
|
||||
break;
|
||||
case R_386_PC16:
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
|
||||
# RUN: ld.lld -Ttext 0x7c00 %t -o %t2
|
||||
# RUN: llvm-objdump -s %t2 | FileCheck %s
|
||||
|
||||
# CHECK: Contents of section .text:
|
||||
# CHECK-NEXT: 7c00 b800ff
|
||||
|
||||
.code16
|
||||
.global _start
|
||||
_start:
|
||||
movw $_start+0x8300,%ax
|
|
@ -10,6 +10,6 @@
|
|||
// CHECK-NEXT: 1000 42
|
||||
|
||||
// RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s
|
||||
// ERROR: relocation R_386_16 out of range: 65536 is not in [0, 65535]
|
||||
// ERROR: relocation R_386_16 out of range: 65536 is not in [-32768, 32767]
|
||||
|
||||
.short foo
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
|
||||
# RUN: ld.lld -Ttext 0x7c %t -o %t2
|
||||
# RUN: llvm-objdump -s %t2 | FileCheck %s
|
||||
|
||||
# CHECK: Contents of section .text:
|
||||
# CHECK-NEXT: 007c b4ff
|
||||
|
||||
.code16
|
||||
.global _start
|
||||
_start:
|
||||
movb $_start+0x83,%ah
|
|
@ -10,6 +10,6 @@
|
|||
// CHECK-NEXT: 1000 ff
|
||||
|
||||
// RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s
|
||||
// ERROR: relocation R_386_8 out of range: 256 is not in [0, 255]
|
||||
// ERROR: relocation R_386_8 out of range: 256 is not in [-128, 127]
|
||||
|
||||
.byte foo
|
||||
|
|
Loading…
Reference in New Issue