mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-09 05:02:19 +00:00
[ELF][PPC][X86] Use [-2**(n-1), 2**n) to check overflows for R_PPC_ADDR16, R_PPC64_ADDR{16,32}, R_X86_64_{8,16}
Similar to R_AARCH64_ABS32, R_PPC64_ADDR32 can represent either a signed value or unsigned value, thus we should use `[-2**(n-1), 2**n)` instead of `[-2**(n-1), 2**(n-1))` to check overflows. The issue manifests as a bogus linker error when linking the powerpc64le Linux kernel. The new behavior is compatible with ld.bfd's complain_overflow_bitfield. The upper bound of the error message is not correct. Fix it as well. The changes to R_PPC_ADDR16, R_PPC64_ADDR16, R_X86_64_8 and R_X86_64_16 are similar. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D63690 llvm-svn: 364164
This commit is contained in:
parent
e8da65c698
commit
2fb6b0f2ba
@ -260,6 +260,9 @@ void PPC::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
||||
std::tie(NewType, Val) = fromDTPREL(Type, Val);
|
||||
switch (NewType) {
|
||||
case R_PPC_ADDR16:
|
||||
checkIntUInt(Loc, Val, 16, Type);
|
||||
write16(Loc, Val);
|
||||
break;
|
||||
case R_PPC_GOT16:
|
||||
case R_PPC_GOT_TLSGD16:
|
||||
case R_PPC_GOT_TLSLD16:
|
||||
|
@ -756,10 +756,13 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
||||
break;
|
||||
}
|
||||
case R_PPC64_ADDR16:
|
||||
case R_PPC64_TPREL16:
|
||||
checkInt(Loc, Val, 16, OriginalType);
|
||||
checkIntUInt(Loc, Val, 16, OriginalType);
|
||||
write16(Loc, Val);
|
||||
break;
|
||||
case R_PPC64_ADDR32:
|
||||
checkIntUInt(Loc, Val, 32, OriginalType);
|
||||
write32(Loc, Val);
|
||||
break;
|
||||
case R_PPC64_ADDR16_DS:
|
||||
case R_PPC64_TPREL16_DS: {
|
||||
checkInt(Loc, Val, 16, OriginalType);
|
||||
@ -836,7 +839,10 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
||||
write16(Loc, (read16(Loc) & Mask) | lo(Val));
|
||||
}
|
||||
} break;
|
||||
case R_PPC64_ADDR32:
|
||||
case R_PPC64_TPREL16:
|
||||
checkInt(Loc, Val, 16, OriginalType);
|
||||
write16(Loc, Val);
|
||||
break;
|
||||
case R_PPC64_REL32:
|
||||
checkInt(Loc, Val, 32, Type);
|
||||
write32(Loc, Val);
|
||||
|
@ -349,7 +349,7 @@ void X86_64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
||||
void X86_64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
||||
switch (Type) {
|
||||
case R_X86_64_8:
|
||||
checkUInt(Loc, Val, 8, Type);
|
||||
checkIntUInt(Loc, Val, 8, Type);
|
||||
*Loc = Val;
|
||||
break;
|
||||
case R_X86_64_PC8:
|
||||
@ -357,7 +357,7 @@ void X86_64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
|
||||
*Loc = Val;
|
||||
break;
|
||||
case R_X86_64_16:
|
||||
checkUInt(Loc, Val, 16, Type);
|
||||
checkIntUInt(Loc, Val, 16, Type);
|
||||
write16le(Loc, Val);
|
||||
break;
|
||||
case R_X86_64_PC16:
|
||||
|
@ -221,7 +221,7 @@ inline void checkIntUInt(uint8_t *Loc, uint64_t V, int N, RelType Type) {
|
||||
// messages show a small negative value rather than an extremely large one
|
||||
if (V != (uint64_t)llvm::SignExtend64(V, N) && (V >> N) != 0)
|
||||
reportRangeError(Loc, Type, Twine((int64_t)V), llvm::minIntN(N),
|
||||
llvm::maxIntN(N));
|
||||
llvm::maxUIntN(N));
|
||||
}
|
||||
|
||||
inline void checkAlignment(uint8_t *Loc, uint64_t V, int N, RelType Type) {
|
||||
|
@ -1,3 +0,0 @@
|
||||
.globl foo
|
||||
.hidden foo
|
||||
foo = 65536
|
@ -1,3 +0,0 @@
|
||||
.globl foo
|
||||
.hidden foo
|
||||
foo = 0xffff
|
@ -1,3 +0,0 @@
|
||||
.globl foo
|
||||
.hidden foo
|
||||
foo = 256
|
@ -1,3 +0,0 @@
|
||||
.globl foo
|
||||
.hidden foo
|
||||
foo = 0xff
|
@ -1,3 +0,0 @@
|
||||
.globl foo
|
||||
.hidden foo
|
||||
foo = 65536
|
@ -1,3 +0,0 @@
|
||||
.globl foo
|
||||
.hidden foo
|
||||
foo = 0x42
|
@ -1,3 +0,0 @@
|
||||
.globl foo
|
||||
.hidden foo
|
||||
foo = 256
|
@ -1,3 +0,0 @@
|
||||
.globl foo
|
||||
.hidden foo
|
||||
foo = 0x42
|
@ -20,8 +20,8 @@ _start:
|
||||
// S + A = 0x8000
|
||||
// CHECK-NEXT: 210000 ffff0080
|
||||
|
||||
// RUN: not ld.lld %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
|
||||
// OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 32767]
|
||||
// RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
|
||||
// OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 65535]
|
||||
|
||||
// RUN: not ld.lld %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
|
||||
// OVERFLOW2: relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 32767]
|
||||
// RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
|
||||
// OVERFLOW2: relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535]
|
||||
|
@ -20,8 +20,8 @@ _start:
|
||||
// S + A = 0x80000000
|
||||
// CHECK-NEXT: 210000 ffffffff 00000080
|
||||
|
||||
// RUN: not ld.lld %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
|
||||
// OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 2147483647]
|
||||
// RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
|
||||
// OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 4294967295]
|
||||
|
||||
// RUN: not ld.lld %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
|
||||
// OVERFLOW2: relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 2147483647]
|
||||
// RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
|
||||
// OVERFLOW2: relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295]
|
||||
|
@ -25,7 +25,7 @@ _start:
|
||||
// CHECK-NEXT: 201000 ffff0080
|
||||
|
||||
// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
|
||||
// OVERFLOW1: relocation R_AARCH64_PREL16 out of range: -32769 is not in [-32768, 32767]
|
||||
// OVERFLOW1: relocation R_AARCH64_PREL16 out of range: -32769 is not in [-32768, 65535]
|
||||
|
||||
// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
|
||||
// OVERFLOW2: relocation R_AARCH64_PREL16 out of range: 65536 is not in [-32768, 32767]
|
||||
// OVERFLOW2: relocation R_AARCH64_PREL16 out of range: 65536 is not in [-32768, 65535]
|
||||
|
@ -25,7 +25,7 @@ _start:
|
||||
// CHECK-NEXT: 201000 ffffffff 00000080
|
||||
|
||||
// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
|
||||
// OVERFLOW1: relocation R_AARCH64_PREL32 out of range: -2147483649 is not in [-2147483648, 2147483647]
|
||||
// OVERFLOW1: relocation R_AARCH64_PREL32 out of range: -2147483649 is not in [-2147483648, 4294967295]
|
||||
|
||||
// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
|
||||
// OVERFLOW2: relocation R_AARCH64_PREL32 out of range: 4294967296 is not in [-2147483648, 2147483647]
|
||||
// OVERFLOW2: relocation R_AARCH64_PREL32 out of range: 4294967296 is not in [-2147483648, 4294967295]
|
||||
|
@ -1,15 +1,20 @@
|
||||
// REQUIRES: x86
|
||||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/x86-64-reloc-16.s -o %t1
|
||||
// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/x86-64-reloc-16-error.s -o %t2
|
||||
// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
|
||||
// RUN: ld.lld -shared %t %t1 -o %t3
|
||||
// RUN: llvm-objdump -s %t3 | FileCheck %s
|
||||
# RUN: ld.lld %t.o --defsym=a=0 --defsym=b=32768 -o %t
|
||||
# RUN: llvm-readelf -x .text %t | FileCheck %s
|
||||
# CHECK: b80080bb ffff
|
||||
|
||||
// CHECK: Contents of section .text:
|
||||
// CHECK-NEXT: 1000 42
|
||||
# RUN: not ld.lld %t.o --defsym=a=-1 --defsym=b=0 -o /dev/null 2>&1 | \
|
||||
# RUN: FileCheck --check-prefix=OVERFLOW1 %s
|
||||
# OVERFLOW1: relocation R_386_16 out of range: -32769 is not in [-32768, 65535]
|
||||
|
||||
// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
|
||||
// ERROR: relocation R_386_16 out of range: 65536 is not in [-32768, 32767]
|
||||
# RUN: not ld.lld %t.o --defsym=a=0 --defsym=b=32769 -o /dev/null 2>&1 | \
|
||||
# RUN: FileCheck --check-prefix=OVERFLOW2 %s
|
||||
# OVERFLOW2: relocation R_386_16 out of range: 65536 is not in [-32768, 65535]
|
||||
|
||||
.short foo
|
||||
.code16
|
||||
.global _start
|
||||
_start:
|
||||
movw $a-32768, %ax
|
||||
movw $b+32767, %bx
|
||||
|
@ -1,15 +1,20 @@
|
||||
// REQUIRES: x86
|
||||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-reloc-8.s -o %t1
|
||||
// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-reloc-8-error.s -o %t2
|
||||
// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
|
||||
// RUN: ld.lld -shared %t %t1 -o %t3
|
||||
// RUN: llvm-objdump -s %t3 | FileCheck %s
|
||||
# RUN: ld.lld %t.o --defsym=a=0 --defsym=b=128 -o %t
|
||||
# RUN: llvm-readelf -x .text %t | FileCheck %s
|
||||
# CHECK: b480b7ff
|
||||
|
||||
// CHECK: Contents of section .text:
|
||||
// CHECK-NEXT: 1000 ff
|
||||
# RUN: not ld.lld %t.o --defsym=a=-1 --defsym=b=0 -o /dev/null 2>&1 | \
|
||||
# RUN: FileCheck --check-prefix=OVERFLOW1 %s
|
||||
# OVERFLOW1: relocation R_386_8 out of range: -129 is not in [-128, 255]
|
||||
|
||||
// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
|
||||
// ERROR: relocation R_386_8 out of range: 256 is not in [-128, 127]
|
||||
# RUN: not ld.lld %t.o --defsym=a=0 --defsym=b=129 -o /dev/null 2>&1 | \
|
||||
# RUN: FileCheck --check-prefix=OVERFLOW2 %s
|
||||
# OVERFLOW2: relocation R_386_8 out of range: 256 is not in [-128, 255]
|
||||
|
||||
.byte foo
|
||||
.code16
|
||||
.globl _start
|
||||
_start:
|
||||
movb $a-128, %ah
|
||||
movb $b+127, %bh
|
||||
|
@ -1,17 +1,9 @@
|
||||
# REQUIRES: ppc
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
|
||||
# RUN: ld.lld --noinhibit-exec %t.o --defsym=a=0x1234 --defsym=b=0xbcdef -o %t 2>&1 | \
|
||||
# RUN: FileCheck --check-prefix=WARN %s
|
||||
# RUN: ld.lld %t.o --defsym=a=0x1234 --defsym=b=0xbcdef -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
# RUN: llvm-objdump -s --no-show-raw-insn %t | FileCheck --check-prefix=HEX %s
|
||||
|
||||
.section .R_PPC_ADDR16,"ax",@progbits
|
||||
lis 4, a
|
||||
lis 4, b
|
||||
# CHECK-LABEL: section .R_PPC_ADDR16:
|
||||
# CHECK: lis 4, 4660
|
||||
# WARN: warning: {{.*}}.o:(.R_PPC_ADDR16+0x6): relocation R_PPC_ADDR16 out of range: 773615 is not in [-32768, 32767]
|
||||
|
||||
.section .R_PPC_ADDR16_HA,"ax",@progbits
|
||||
lis 4, a@ha
|
||||
# CHECK-LABEL: section .R_PPC_ADDR16_HA:
|
||||
|
@ -1,13 +0,0 @@
|
||||
// REQUIRES: ppc
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
|
||||
// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
|
||||
// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
.short sym+65539
|
||||
|
||||
// CHECK: relocation R_PPC64_ADDR16 out of range: 65539 is not in [-32768, 32767]
|
25
lld/test/ELF/ppc64-reloc-addr.s
Normal file
25
lld/test/ELF/ppc64-reloc-addr.s
Normal file
@ -0,0 +1,25 @@
|
||||
# REQUIRES: ppc
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le %S/Inputs/abs255.s -o %t255.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le %S/Inputs/abs256.s -o %t256.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le %S/Inputs/abs257.s -o %t257.o
|
||||
|
||||
# RUN: ld.lld %t.o %t256.o -o %t
|
||||
# RUN: llvm-readelf -x .data %t | FileCheck %s
|
||||
# CHECK: 0x{{[0-9a-f]+}} ffff0080 ffffffff 00000080
|
||||
|
||||
# RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck --check-prefix=OVERFLOW1 %s
|
||||
# OVERFLOW1: relocation R_PPC64_ADDR16 out of range: -32769 is not in [-32768, 65535]
|
||||
# OVERFLOW1: relocation R_PPC64_ADDR32 out of range: -2147483649 is not in [-2147483648, 4294967295]
|
||||
|
||||
# RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck --check-prefix=OVERFLOW2 %s
|
||||
# OVERFLOW2: relocation R_PPC64_ADDR16 out of range: 65536 is not in [-32768, 65535]
|
||||
# OVERFLOW2: relocation R_PPC64_ADDR32 out of range: 4294967296 is not in [-2147483648, 4294967295]
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
.data
|
||||
.word foo + 0xfeff
|
||||
.word foo - 0x8100
|
||||
.long foo + 0xfffffeff
|
||||
.long foo - 0x80000100
|
@ -1,14 +0,0 @@
|
||||
// REQUIRES: x86
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-16.s -o %t1
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-16-error.s -o %t2
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
|
||||
// RUN: ld.lld -shared %t %t1 -o /dev/null
|
||||
|
||||
// CHECK: Contents of section .text:
|
||||
// CHECK-NEXT: 200000 42
|
||||
|
||||
// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
|
||||
// ERROR: relocation R_X86_64_16 out of range: 65536 is not in [0, 65535]
|
||||
|
||||
.short foo
|
25
lld/test/ELF/x86-64-reloc-8-16.s
Normal file
25
lld/test/ELF/x86-64-reloc-8-16.s
Normal file
@ -0,0 +1,25 @@
|
||||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/abs255.s -o %t255.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/abs256.s -o %t256.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64 %S/Inputs/abs257.s -o %t257.o
|
||||
|
||||
# RUN: ld.lld %t.o %t256.o -o %t
|
||||
# RUN: llvm-readelf -x .data %t | FileCheck %s
|
||||
# CHECK: 0x{{[0-9a-f]+}} ff80ffff 0080
|
||||
|
||||
# RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck --check-prefix=OVERFLOW1 %s
|
||||
# OVERFLOW1: relocation R_X86_64_8 out of range: -129 is not in [-128, 255]
|
||||
# OVERFLOW1: relocation R_X86_64_16 out of range: -32769 is not in [-32768, 65535]
|
||||
|
||||
# RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck --check-prefix=OVERFLOW2 %s
|
||||
# OVERFLOW2: relocation R_X86_64_8 out of range: 256 is not in [-128, 255]
|
||||
# OVERFLOW2: relocation R_X86_64_16 out of range: 65536 is not in [-32768, 65535]
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
.data
|
||||
.byte foo - 1
|
||||
.byte foo - 384
|
||||
.word foo + 0xfeff
|
||||
.word foo - 0x8100
|
@ -1,14 +0,0 @@
|
||||
// REQUIRES: x86
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-8.s -o %t1
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-8-error.s -o %t2
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
|
||||
// RUN: ld.lld -shared %t %t1 -o /dev/null
|
||||
|
||||
// CHECK: Contents of section .text:
|
||||
// CHECK-NEXT: 200000 42
|
||||
|
||||
// RUN: not ld.lld -shared %t %t2 -o /dev/null 2>&1 | FileCheck --check-prefix=ERROR %s
|
||||
// ERROR: relocation R_X86_64_8 out of range: 256 is not in [0, 255]
|
||||
|
||||
.byte foo
|
Loading…
x
Reference in New Issue
Block a user