mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +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(uint32_t, MIPS_ISA)
|
||||||
|
|
||||||
LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
|
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
|
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
|
||||||
// since 64-bit can hold 32-bit values too.
|
// since 64-bit can hold 32-bit values too.
|
||||||
@ -439,7 +440,7 @@ struct Group : Section {
|
|||||||
|
|
||||||
struct Relocation {
|
struct Relocation {
|
||||||
llvm::yaml::Hex64 Offset;
|
llvm::yaml::Hex64 Offset;
|
||||||
int64_t Addend;
|
YAMLIntUInt Addend;
|
||||||
ELF_REL Type;
|
ELF_REL Type;
|
||||||
Optional<StringRef> Symbol;
|
Optional<StringRef> Symbol;
|
||||||
};
|
};
|
||||||
@ -542,6 +543,14 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName)
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace yaml {
|
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 <>
|
template <>
|
||||||
struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
|
struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
|
||||||
static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
|
static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
|
||||||
|
@ -982,6 +982,38 @@ struct NormalizedOther {
|
|||||||
|
|
||||||
} // end anonymous namespace
|
} // 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) {
|
void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
|
||||||
IO.mapOptional("Name", Symbol.Name, StringRef());
|
IO.mapOptional("Name", Symbol.Name, StringRef());
|
||||||
IO.mapOptional("StName", Symbol.StName);
|
IO.mapOptional("StName", Symbol.StName);
|
||||||
@ -1582,7 +1614,7 @@ void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
|
|||||||
} else
|
} else
|
||||||
IO.mapRequired("Type", Rel.Type);
|
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) {
|
void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
|
||||||
|
@ -2,36 +2,50 @@
|
|||||||
|
|
||||||
## Case 1: Check a 64-bit object.
|
## Case 1: Check a 64-bit object.
|
||||||
|
|
||||||
## Case 1.1: Document we accept an addend with the
|
## Case 1.1: Document we accept any hex/decimal addends in [INT64_MIN, UINT64_MAX].
|
||||||
## value INT64_MAX = 2^63-1 = 0x7FFFFFFFFFFFFFFF = 9223372036854775807.
|
|
||||||
|
|
||||||
# RUN: yaml2obj %s -o %t1 -D ADDEND=9223372036854775807
|
## INT64_MIN == -9223372036854775808
|
||||||
# RUN: llvm-readobj -r %t1 | FileCheck %s --check-prefix=MAX64
|
## UINT64_MAX == 0xffffffffffffffff
|
||||||
# RUN: yaml2obj %s -o %t2 -D ADDEND=0x7FFFFFFFFFFFFFFF
|
|
||||||
# RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=MAX64
|
|
||||||
|
|
||||||
# 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
|
## Addend == first positive integer.
|
||||||
## it is in decimal form. We use (INT64_MAX + 1).
|
# RUN: yaml2obj %s -o %t64.decimal.first.pos -DADDEND=1
|
||||||
# RUN: not yaml2obj %s -o %t3 -D ADDEND=9223372036854775808 2>&1 | FileCheck %s --check-prefix=OVERFLOW64
|
# 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
|
## Addend == first negative integer.
|
||||||
## value INT64_MIN = -2^63 = 0x8000000000000000 = -9223372036854775808.
|
# 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
|
## Addend == INT64_MIN.
|
||||||
# RUN: llvm-readobj -r %t3 | FileCheck %s --check-prefix=MIN64
|
# 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.
|
## Addend == 2^64.
|
||||||
# RUN: not yaml2obj %s -o /dev/null -D ADDEND=0x8000000000000000 2>&1 | FileCheck %s --check-prefix=OVERFLOW64
|
# 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
|
## Addend == INT64_MIN - 1.
|
||||||
## it is in decimal form. We use (INT64_MIN - 1).
|
# RUN: not yaml2obj %s -o /dev/null -DADDEND=-9223372036854775809 2>&1 | FileCheck %s --check-prefix=ERR
|
||||||
# RUN: not yaml2obj %s -o /dev/null -D ADDEND=-9223372036854775809 2>&1 | FileCheck %s --check-prefix=OVERFLOW64
|
|
||||||
|
# ERR: invalid number
|
||||||
|
|
||||||
--- !ELF
|
--- !ELF
|
||||||
FileHeader:
|
FileHeader:
|
||||||
@ -55,43 +69,47 @@ Symbols:
|
|||||||
|
|
||||||
## Case 2: Check a 32-bit object.
|
## Case 2: Check a 32-bit object.
|
||||||
|
|
||||||
## Case 2.1: Document we accept an addend with the
|
## INT32_MIN == -2147483648
|
||||||
## value INT32_MAX = 2^31-1 = 0x7FFFFFFF = 2,147,483,647.
|
## UINT32_MAX == 0xffffffff
|
||||||
|
|
||||||
# RUN: yaml2obj --docnum=2 %s -o %t4 -D ADDEND=2147483647
|
## Case 2.1: Document we accept any hex/decimal addends in [INT32_MIN, UINT32_MAX].
|
||||||
# RUN: llvm-readobj -r %t4 | FileCheck %s --check-prefix=MAX32
|
|
||||||
# RUN: yaml2obj --docnum=2 %s -o %t5 -D ADDEND=0x7FFFFFFF
|
|
||||||
# RUN: cmp %t4 %t5
|
|
||||||
|
|
||||||
# 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
|
## Addend == first positive integer.
|
||||||
## it is specified in decimal form. We use (INT32_MAX + 1).
|
# 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.
|
## Addend == 0.
|
||||||
# RUN: yaml2obj --docnum=2 %s -o %t6 -D ADDEND=2147483648
|
# RUN: yaml2obj --docnum=2 %s -o %t32.decimal.null -DADDEND=0
|
||||||
# RUN: llvm-readobj -r %t6 | FileCheck %s --check-prefix=OVERFLOW32-1
|
# 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
|
## Addend == INT32_MIN
|
||||||
## value INT32_MIN = -2^31 = 0x80000000 = -2,147,483,648.
|
# 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
|
# Case 2.2: Document we do not accept any hex/decimal addends outside of the range specified.
|
||||||
# RUN: llvm-readobj -r %t7 | FileCheck %s --check-prefix=MIN32
|
|
||||||
# RUN: yaml2obj --docnum=2 %s -o %t8 -D ADDEND=0x80000000
|
|
||||||
# RUN: cmp %t7 %t8
|
|
||||||
|
|
||||||
# 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
|
## Addend == INT32_MIN - 1.
|
||||||
## it is in decimal form. We use (INT32_MIN - 1).
|
# RUN: not yaml2obj --docnum=2 %s -o /dev/null -DADDEND=-2147483649 2>&1 | FileCheck %s --check-prefix=ERR
|
||||||
|
|
||||||
## 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{{$}}
|
|
||||||
|
|
||||||
--- !ELF
|
--- !ELF
|
||||||
FileHeader:
|
FileHeader:
|
||||||
@ -112,3 +130,12 @@ Sections:
|
|||||||
Addend: [[ADDEND]]
|
Addend: [[ADDEND]]
|
||||||
Symbols:
|
Symbols:
|
||||||
- Name: foo
|
- 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