mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[yaml2obj] - Add ELFYAML::YAMLIntUInt
to fix how we parse a relocation Addend
key.
This patch makes `Relocation::Addend` to be `ELFYAML::YAMLIntUInt` and not `int64_t`. `ELFYAML::YAMLIntUInt` it is a new type and it has the following benefits/features: 1) For an 64-bit object any hex/decimal addends in the range [INT64_MIN, UINT64_MAX] is accepted. 2) For an 32-bit object any hex/decimal addends in range [INT32_MIN, UINT32_MAX] is accepted. 3) Negative hex numbers like -0xffffffff are not accepted. 4) It is printed as decimal. I.e. obj2yaml will print something like "Addend: 125", this matches the current behavior. This fixes all FIXMEs in `relocation-addend.yaml`. Differential revision: https://reviews.llvm.org/D75527
This commit is contained in:
parent
630424ca3a
commit
c586fc306f
@ -65,6 +65,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
|
||||
|
||||
LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
|
||||
LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
|
||||
|
||||
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
|
||||
// since 64-bit can hold 32-bit values too.
|
||||
@ -439,7 +440,7 @@ struct Group : Section {
|
||||
|
||||
struct Relocation {
|
||||
llvm::yaml::Hex64 Offset;
|
||||
int64_t Addend;
|
||||
YAMLIntUInt Addend;
|
||||
ELF_REL Type;
|
||||
Optional<StringRef> Symbol;
|
||||
};
|
||||
@ -542,6 +543,14 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName)
|
||||
namespace llvm {
|
||||
namespace yaml {
|
||||
|
||||
template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
|
||||
static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
|
||||
raw_ostream &Out);
|
||||
static StringRef input(StringRef Scalar, void *Ctx,
|
||||
ELFYAML::YAMLIntUInt &Val);
|
||||
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
|
||||
static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
|
||||
|
@ -982,6 +982,38 @@ struct NormalizedOther {
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
void ScalarTraits<ELFYAML::YAMLIntUInt>::output(const ELFYAML::YAMLIntUInt &Val,
|
||||
void *Ctx, raw_ostream &Out) {
|
||||
Out << Val;
|
||||
}
|
||||
|
||||
StringRef ScalarTraits<ELFYAML::YAMLIntUInt>::input(StringRef Scalar, void *Ctx,
|
||||
ELFYAML::YAMLIntUInt &Val) {
|
||||
const bool Is64 = static_cast<ELFYAML::Object *>(Ctx)->Header.Class ==
|
||||
ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
|
||||
StringRef ErrMsg = "invalid number";
|
||||
// We do not accept negative hex numbers because their meaning is ambiguous.
|
||||
// For example, would -0xfffffffff mean 1 or INT32_MIN?
|
||||
if (Scalar.empty() || Scalar.startswith("-0x"))
|
||||
return ErrMsg;
|
||||
|
||||
if (Scalar.startswith("-")) {
|
||||
const int64_t MinVal = Is64 ? INT64_MIN : INT32_MIN;
|
||||
long long Int;
|
||||
if (getAsSignedInteger(Scalar, /*Radix=*/0, Int) || (Int < MinVal))
|
||||
return ErrMsg;
|
||||
Val = Int;
|
||||
return "";
|
||||
}
|
||||
|
||||
const uint64_t MaxVal = Is64 ? UINT64_MAX : UINT32_MAX;
|
||||
unsigned long long UInt;
|
||||
if (getAsUnsignedInteger(Scalar, /*Radix=*/0, UInt) || (UInt > MaxVal))
|
||||
return ErrMsg;
|
||||
Val = UInt;
|
||||
return "";
|
||||
}
|
||||
|
||||
void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
|
||||
IO.mapOptional("Name", Symbol.Name, StringRef());
|
||||
IO.mapOptional("StName", Symbol.StName);
|
||||
@ -1582,7 +1614,7 @@ void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
|
||||
} else
|
||||
IO.mapRequired("Type", Rel.Type);
|
||||
|
||||
IO.mapOptional("Addend", Rel.Addend, (int64_t)0);
|
||||
IO.mapOptional("Addend", Rel.Addend, (ELFYAML::YAMLIntUInt)0);
|
||||
}
|
||||
|
||||
void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
|
||||
|
@ -2,36 +2,50 @@
|
||||
|
||||
## Case 1: Check a 64-bit object.
|
||||
|
||||
## Case 1.1: Document we accept an addend with the
|
||||
## value INT64_MAX = 2^63-1 = 0x7FFFFFFFFFFFFFFF = 9223372036854775807.
|
||||
## Case 1.1: Document we accept any hex/decimal addends in [INT64_MIN, UINT64_MAX].
|
||||
|
||||
# RUN: yaml2obj %s -o %t1 -D ADDEND=9223372036854775807
|
||||
# RUN: llvm-readobj -r %t1 | FileCheck %s --check-prefix=MAX64
|
||||
# RUN: yaml2obj %s -o %t2 -D ADDEND=0x7FFFFFFFFFFFFFFF
|
||||
# RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=MAX64
|
||||
## INT64_MIN == -9223372036854775808
|
||||
## UINT64_MAX == 0xffffffffffffffff
|
||||
|
||||
# MAX64: 0x0 R_X86_64_PC32 foo 0x7FFFFFFFFFFFFFFF
|
||||
## Addend == UINT64_MAX.
|
||||
# RUN: yaml2obj %s -o %t64.decimal.max -DADDEND=18446744073709551615
|
||||
# RUN: llvm-readobj -r %t64.decimal.max | FileCheck %s --check-prefix=TEST -DADDEND=0xFFFFFFFFFFFFFFFF
|
||||
# RUN: yaml2obj %s -o %t64.hex.max -DADDEND=0xFFFFFFFFFFFFFFFF
|
||||
# RUN: llvm-readobj -r %t64.hex.max | FileCheck %s --check-prefix=TEST -DADDEND=0xFFFFFFFFFFFFFFFF
|
||||
|
||||
## Case 1.2: Check we report an error when an addend is greater than INT64_MAX and
|
||||
## it is in decimal form. We use (INT64_MAX + 1).
|
||||
# RUN: not yaml2obj %s -o %t3 -D ADDEND=9223372036854775808 2>&1 | FileCheck %s --check-prefix=OVERFLOW64
|
||||
## Addend == first positive integer.
|
||||
# RUN: yaml2obj %s -o %t64.decimal.first.pos -DADDEND=1
|
||||
# RUN: llvm-readobj -r %t64.decimal.first.pos | FileCheck %s --check-prefix=TEST -DADDEND=0x1
|
||||
# RUN: yaml2obj %s -o %t64.hex.first.pos -DADDEND=0x1
|
||||
# RUN: llvm-readobj -r %t64.hex.first.pos | FileCheck %s --check-prefix=TEST -DADDEND=0x1
|
||||
|
||||
# OVERFLOW64: error: invalid number
|
||||
## Addend == 0.
|
||||
# RUN: yaml2obj %s -o %t64.decimal.null -DADDEND=0
|
||||
# RUN: llvm-readobj -r %t64.decimal.null | FileCheck %s --check-prefix=TEST -DADDEND=0x0
|
||||
# RUN: yaml2obj %s -o %t64.hex.null -DADDEND=0x0
|
||||
# RUN: llvm-readobj -r %t64.hex.null | FileCheck %s --check-prefix=TEST -DADDEND=0x0
|
||||
|
||||
## Case 1.3: Document we accept an addend with the
|
||||
## value INT64_MIN = -2^63 = 0x8000000000000000 = -9223372036854775808.
|
||||
## Addend == first negative integer.
|
||||
# RUN: yaml2obj %s -o %t64.decimal.first.neg -DADDEND=-1
|
||||
# RUN: llvm-readobj -r %t64.decimal.first.neg | FileCheck %s --check-prefix=TEST -DADDEND=0xFFFFFFFFFFFFFFFF
|
||||
## We do not accept negative hex addends.
|
||||
# RUN: not yaml2obj %s -o /dev/null -DADDEND=-0x1 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
|
||||
# RUN: yaml2obj %s -o %t3 -D ADDEND=-9223372036854775808
|
||||
# RUN: llvm-readobj -r %t3 | FileCheck %s --check-prefix=MIN64
|
||||
## Addend == INT64_MIN.
|
||||
# RUN: yaml2obj %s -o %t64.decimal.min -DADDEND=-9223372036854775808
|
||||
# RUN: llvm-readobj -r %t64.decimal.min | FileCheck %s --check-prefix=TEST -DADDEND=0x8000000000000000
|
||||
# TEST: 0x0 R_{{.*}}_PC32 foo [[ADDEND]]
|
||||
|
||||
# MIN64: 0x0 R_X86_64_PC32 foo 0x8000000000000000
|
||||
# Case 1.2: Document we do not accept any hex/decimal addends outside of the range specified.
|
||||
|
||||
## FIXME: We should support the following case instead.
|
||||
# RUN: not yaml2obj %s -o /dev/null -D ADDEND=0x8000000000000000 2>&1 | FileCheck %s --check-prefix=OVERFLOW64
|
||||
## Addend == 2^64.
|
||||
# RUN: not yaml2obj %s -o /dev/null -DADDEND=18446744073709551616 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# RUN: not yaml2obj %s -o /dev/null -DADDEND=0x10000000000000000 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
|
||||
## Case 1.4: Check we report an error when an addend is less than INT64_MIN and
|
||||
## it is in decimal form. We use (INT64_MIN - 1).
|
||||
# RUN: not yaml2obj %s -o /dev/null -D ADDEND=-9223372036854775809 2>&1 | FileCheck %s --check-prefix=OVERFLOW64
|
||||
## Addend == INT64_MIN - 1.
|
||||
# RUN: not yaml2obj %s -o /dev/null -DADDEND=-9223372036854775809 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
|
||||
# ERR: invalid number
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
@ -55,43 +69,47 @@ Symbols:
|
||||
|
||||
## Case 2: Check a 32-bit object.
|
||||
|
||||
## Case 2.1: Document we accept an addend with the
|
||||
## value INT32_MAX = 2^31-1 = 0x7FFFFFFF = 2,147,483,647.
|
||||
## INT32_MIN == -2147483648
|
||||
## UINT32_MAX == 0xffffffff
|
||||
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t4 -D ADDEND=2147483647
|
||||
# RUN: llvm-readobj -r %t4 | FileCheck %s --check-prefix=MAX32
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t5 -D ADDEND=0x7FFFFFFF
|
||||
# RUN: cmp %t4 %t5
|
||||
## Case 2.1: Document we accept any hex/decimal addends in [INT32_MIN, UINT32_MAX].
|
||||
|
||||
# MAX32: 0x0 R_386_PC32 foo 0x7FFFFFFF{{$}}
|
||||
## Addend == UINT32_MAX.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t32.decimal.max -DADDEND=4294967295
|
||||
# RUN: llvm-readobj -r %t32.decimal.max | FileCheck %s --check-prefix=TEST -DADDEND=0xFFFFFFFF
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t32.hex.max -DADDEND=0xFFFFFFFF
|
||||
# RUN: llvm-readobj -r %t32.hex.max | FileCheck %s --check-prefix=TEST -DADDEND=0xFFFFFFFF
|
||||
|
||||
## Case 2.2: Check we report an error when an addend is greater than INT32_MAX and
|
||||
## it is specified in decimal form. We use (INT32_MAX + 1).
|
||||
## Addend == first positive integer.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t32.decimal.first.pos -DADDEND=1
|
||||
# RUN: llvm-readobj -r %t32.decimal.first.pos | FileCheck %s --check-prefix=TEST -DADDEND=0x1
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t32.hex.first.pos -DADDEND=0x1
|
||||
# RUN: llvm-readobj -r %t32.hex.first.pos | FileCheck %s --check-prefix=TEST -DADDEND=0x1
|
||||
|
||||
## FIXME: The following case should fail, see OVERFLOW64.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t6 -D ADDEND=2147483648
|
||||
# RUN: llvm-readobj -r %t6 | FileCheck %s --check-prefix=OVERFLOW32-1
|
||||
## Addend == 0.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t32.decimal.null -DADDEND=0
|
||||
# RUN: llvm-readobj -r %t32.decimal.null | FileCheck %s --check-prefix=TEST -DADDEND=0x0
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t32.hex.null -DADDEND=0x0
|
||||
# RUN: llvm-readobj -r %t32.hex.null | FileCheck %s --check-prefix=TEST -DADDEND=0x0
|
||||
|
||||
# OVERFLOW32-1: 0x0 R_386_PC32 foo 0x80000000{{$}}
|
||||
## Addend == first negative integer.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t32.decimal.first.neg -DADDEND=-1
|
||||
# RUN: llvm-readobj -r %t32.decimal.first.neg | FileCheck %s --check-prefix=TEST -DADDEND=0xFFFFFFFF
|
||||
## We do not accept negative hex addends.
|
||||
# RUN: not yaml2obj --docnum=2 %s -o /dev/null -DADDEND=-0x1 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
|
||||
## Case 2.3: Document we accept an addend with the
|
||||
## value INT32_MIN = -2^31 = 0x80000000 = -2,147,483,648.
|
||||
## Addend == INT32_MIN
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t32.decimal.min -DADDEND=-2147483648
|
||||
# RUN: llvm-readobj -r %t32.decimal.min | FileCheck %s --check-prefix=TEST -DADDEND=0x80000000
|
||||
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t7 -D ADDEND=-2147483648
|
||||
# RUN: llvm-readobj -r %t7 | FileCheck %s --check-prefix=MIN32
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t8 -D ADDEND=0x80000000
|
||||
# RUN: cmp %t7 %t8
|
||||
# Case 2.2: Document we do not accept any hex/decimal addends outside of the range specified.
|
||||
|
||||
# MIN32: 0x0 R_386_PC32 foo 0x80000000{{$}}
|
||||
## Addend == 2^32.
|
||||
# RUN: not yaml2obj --docnum=2 %s -o /dev/null -DADDEND=4294967296 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# RUN: not yaml2obj --docnum=2 %s -o /dev/null -DADDEND=0x100000000 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
|
||||
## Case 2.4: Check we report an error when an addend is less than INT32_MIN and
|
||||
## it is in decimal form. We use (INT32_MIN - 1).
|
||||
|
||||
## FIXME: The following case should fail, see OVERFLOW64.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t9 -D ADDEND=-2147483649
|
||||
# RUN: llvm-readobj -r %t9 | FileCheck %s --check-prefix=OVERFLOW32-2
|
||||
|
||||
# OVERFLOW32-2: 0x0 R_386_PC32 foo 0x7FFFFFFF{{$}}
|
||||
## Addend == INT32_MIN - 1.
|
||||
# RUN: not yaml2obj --docnum=2 %s -o /dev/null -DADDEND=-2147483649 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
@ -112,3 +130,12 @@ Sections:
|
||||
Addend: [[ADDEND]]
|
||||
Symbols:
|
||||
- Name: foo
|
||||
|
||||
## Case 3: Check we do not allow invalid values.
|
||||
# RUN: not yaml2obj %s -D ADDEND=0x1122GGEE 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# RUN: not yaml2obj %s -D ADDEND=-0x1122GGEE 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# RUN: not yaml2obj %s -D ADDEND=1234G5 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# RUN: not yaml2obj %s -D ADDEND=-1234G5 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# RUN: not yaml2obj %s -D ADDEND=foo 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# RUN: not yaml2obj %s -D ADDEND=- 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# RUN: not yaml2obj %s -D ADDEND=--1234 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
|
Loading…
Reference in New Issue
Block a user