summaryrefslogtreecommitdiff
path: root/llvm/lib/ObjectYAML/ELFYAML.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ObjectYAML/ELFYAML.cpp')
-rw-r--r--llvm/lib/ObjectYAML/ELFYAML.cpp157
1 files changed, 135 insertions, 22 deletions
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index efa7ecb4728b2..2353b34f188b1 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -221,6 +221,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(
ECase(EM_RISCV);
ECase(EM_LANAI);
ECase(EM_BPF);
+ ECase(EM_VE);
#undef ECase
IO.enumFallback<Hex16>(Value);
}
@@ -349,6 +350,9 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
BCase(EF_HEXAGON_MACH_V60);
BCase(EF_HEXAGON_MACH_V62);
BCase(EF_HEXAGON_MACH_V65);
+ BCase(EF_HEXAGON_MACH_V66);
+ BCase(EF_HEXAGON_MACH_V67);
+ BCase(EF_HEXAGON_MACH_V67T);
BCase(EF_HEXAGON_ISA_V2);
BCase(EF_HEXAGON_ISA_V3);
BCase(EF_HEXAGON_ISA_V4);
@@ -357,6 +361,8 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
BCase(EF_HEXAGON_ISA_V60);
BCase(EF_HEXAGON_ISA_V62);
BCase(EF_HEXAGON_ISA_V65);
+ BCase(EF_HEXAGON_ISA_V66);
+ BCase(EF_HEXAGON_ISA_V67);
break;
case ELF::EM_AVR:
BCase(EF_AVR_ARCH_AVR1);
@@ -423,6 +429,7 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1010, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1011, EF_AMDGPU_MACH);
BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1012, EF_AMDGPU_MACH);
+ BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1030, EF_AMDGPU_MACH);
BCase(EF_AMDGPU_XNACK);
BCase(EF_AMDGPU_SRAM_ECC);
break;
@@ -495,6 +502,9 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
ECase(SHT_MIPS_DWARF);
ECase(SHT_MIPS_ABIFLAGS);
break;
+ case ELF::EM_RISCV:
+ ECase(SHT_RISCV_ATTRIBUTES);
+ break;
default:
// Nothing to do.
break;
@@ -654,6 +664,9 @@ void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
case ELF::EM_BPF:
#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
break;
+ case ELF::EM_VE:
+#include "llvm/BinaryFormat/ELFRelocs/VE.def"
+ break;
case ELF::EM_PPC64:
#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
break;
@@ -820,6 +833,28 @@ void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset(
#undef BCase
}
+void MappingTraits<ELFYAML::SectionHeader>::mapping(
+ IO &IO, ELFYAML::SectionHeader &SHdr) {
+ IO.mapRequired("Name", SHdr.Name);
+}
+
+void MappingTraits<ELFYAML::SectionHeaderTable>::mapping(
+ IO &IO, ELFYAML::SectionHeaderTable &SectionHeader) {
+ IO.mapOptional("Sections", SectionHeader.Sections);
+ IO.mapOptional("Excluded", SectionHeader.Excluded);
+ IO.mapOptional("NoHeaders", SectionHeader.NoHeaders);
+}
+
+StringRef MappingTraits<ELFYAML::SectionHeaderTable>::validate(
+ IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable) {
+ if (SecHdrTable.NoHeaders && (SecHdrTable.Sections || SecHdrTable.Excluded))
+ return "NoHeaders can't be used together with Sections/Excluded";
+ if (!SecHdrTable.NoHeaders && !SecHdrTable.Sections && !SecHdrTable.Excluded)
+ return "SectionHeaderTable can't be empty. Use 'NoHeaders' key to drop the "
+ "section header table";
+ return StringRef();
+}
+
void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
ELFYAML::FileHeader &FileHdr) {
IO.mapRequired("Class", FileHdr.Class);
@@ -831,10 +866,16 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
- IO.mapOptional("SHEntSize", FileHdr.SHEntSize);
- IO.mapOptional("SHOff", FileHdr.SHOff);
- IO.mapOptional("SHNum", FileHdr.SHNum);
- IO.mapOptional("SHStrNdx", FileHdr.SHStrNdx);
+ // obj2yaml does not dump these fields.
+ assert(!IO.outputting() ||
+ (!FileHdr.EPhOff && !FileHdr.EPhEntSize && !FileHdr.EPhNum));
+ IO.mapOptional("EPhOff", FileHdr.EPhOff);
+ IO.mapOptional("EPhEntSize", FileHdr.EPhEntSize);
+ IO.mapOptional("EPhNum", FileHdr.EPhNum);
+ IO.mapOptional("EShEntSize", FileHdr.EShEntSize);
+ IO.mapOptional("EShOff", FileHdr.EShOff);
+ IO.mapOptional("EShNum", FileHdr.EShNum);
+ IO.mapOptional("EShStrNdx", FileHdr.EShStrNdx);
}
void MappingTraits<ELFYAML::ProgramHeader>::mapping(
@@ -843,7 +884,7 @@ void MappingTraits<ELFYAML::ProgramHeader>::mapping(
IO.mapOptional("Flags", Phdr.Flags, ELFYAML::ELF_PF(0));
IO.mapOptional("Sections", Phdr.Sections);
IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
- IO.mapOptional("PAddr", Phdr.PAddr, Hex64(0));
+ IO.mapOptional("PAddr", Phdr.PAddr, Phdr.VAddr);
IO.mapOptional("Align", Phdr.Align);
IO.mapOptional("FileSize", Phdr.FileSize);
IO.mapOptional("MemSize", Phdr.MemSize);
@@ -977,9 +1018,41 @@ 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("NameIndex", Symbol.NameIndex);
+ IO.mapOptional("StName", Symbol.StName);
IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
IO.mapOptional("Section", Symbol.Section, StringRef());
IO.mapOptional("Index", Symbol.Index);
@@ -1001,8 +1074,6 @@ StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
ELFYAML::Symbol &Symbol) {
if (Symbol.Index && Symbol.Section.data())
return "Index and Section cannot both be specified for Symbol";
- if (Symbol.NameIndex && !Symbol.Name.empty())
- return "Name and NameIndex cannot both be specified for Symbol";
return StringRef();
}
@@ -1010,10 +1081,11 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
IO.mapOptional("Name", Section.Name, StringRef());
IO.mapRequired("Type", Section.Type);
IO.mapOptional("Flags", Section.Flags);
- IO.mapOptional("Address", Section.Address, Hex64(0));
+ IO.mapOptional("Address", Section.Address);
IO.mapOptional("Link", Section.Link, StringRef());
IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
IO.mapOptional("EntSize", Section.EntSize);
+ IO.mapOptional("Offset", Section.Offset);
// obj2yaml does not dump these fields. They are expected to be empty when we
// are producing YAML, because yaml2obj sets appropriate values for them
@@ -1036,6 +1108,17 @@ static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
commonSectionMapping(IO, Section);
IO.mapOptional("Content", Section.Content);
+
+ // We also support reading a content as array of bytes using the ContentArray
+ // key. obj2yaml never prints this field.
+ assert(!IO.outputting() || !Section.ContentBuf.hasValue());
+ IO.mapOptional("ContentArray", Section.ContentBuf);
+ if (Section.ContentBuf) {
+ if (Section.Content)
+ IO.setError("Content and ContentArray can't be used together");
+ Section.Content = yaml::BinaryRef(*Section.ContentBuf);
+ }
+
IO.mapOptional("Size", Section.Size);
IO.mapOptional("Info", Section.Info);
}
@@ -1053,6 +1136,13 @@ static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) {
IO.mapOptional("Bucket", Section.Bucket);
IO.mapOptional("Chain", Section.Chain);
IO.mapOptional("Size", Section.Size);
+
+ // obj2yaml does not dump these fields. They can be used to override nchain
+ // and nbucket values for creating broken sections.
+ assert(!IO.outputting() ||
+ (!Section.NBucket.hasValue() && !Section.NChain.hasValue()));
+ IO.mapOptional("NChain", Section.NChain);
+ IO.mapOptional("NBucket", Section.NBucket);
}
static void sectionMapping(IO &IO, ELFYAML::NoteSection &Section) {
@@ -1128,6 +1218,7 @@ static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) {
static void fillMapping(IO &IO, ELFYAML::Fill &Fill) {
IO.mapOptional("Name", Fill.Name, StringRef());
IO.mapOptional("Pattern", Fill.Pattern);
+ IO.mapOptional("Offset", Fill.Offset);
IO.mapRequired("Size", Fill.Size);
}
@@ -1144,6 +1235,12 @@ static void sectionMapping(IO &IO,
IO.mapOptional("Content", Section.Content);
}
+static void sectionMapping(IO &IO, ELFYAML::CallGraphProfileSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Entries", Section.Entries);
+ IO.mapOptional("Content", Section.Content);
+}
+
void MappingTraits<ELFYAML::SectionOrType>::mapping(
IO &IO, ELFYAML::SectionOrType &sectionOrType) {
IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
@@ -1277,6 +1374,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
sectionMapping(IO,
*cast<ELFYAML::DependentLibrariesSection>(Section.get()));
break;
+ case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::CallGraphProfileSection());
+ sectionMapping(IO, *cast<ELFYAML::CallGraphProfileSection>(Section.get()));
+ break;
default:
if (!IO.outputting()) {
StringRef Name;
@@ -1367,11 +1469,6 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
if (!Sec->Symbols)
return {};
-
- for (const ELFYAML::AddrsigSymbol &AS : *Sec->Symbols)
- if (AS.Index && AS.Name)
- return "\"Index\" and \"Name\" cannot be used together when defining a "
- "symbol";
return {};
}
@@ -1458,6 +1555,12 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
return {};
}
+ if (const auto *CGP = dyn_cast<ELFYAML::CallGraphProfileSection>(C.get())) {
+ if (CGP->Entries && CGP->Content)
+ return "\"Entries\" and \"Content\" can't be used together";
+ return {};
+ }
+
return {};
}
@@ -1553,7 +1656,7 @@ void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
assert(Object && "The IO context is not initialized");
- IO.mapRequired("Offset", Rel.Offset);
+ IO.mapOptional("Offset", Rel.Offset, (Hex64)0);
IO.mapOptional("Symbol", Rel.Symbol);
if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
@@ -1567,7 +1670,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) {
@@ -1575,19 +1678,21 @@ void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
IO.setContext(&Object);
IO.mapTag("!ELF", true);
IO.mapRequired("FileHeader", Object.Header);
+ IO.mapOptional("SectionHeaderTable", Object.SectionHeaders);
IO.mapOptional("ProgramHeaders", Object.ProgramHeaders);
IO.mapOptional("Sections", Object.Chunks);
IO.mapOptional("Symbols", Object.Symbols);
IO.mapOptional("DynamicSymbols", Object.DynamicSymbols);
+ IO.mapOptional("DWARF", Object.DWARF);
+ if (Object.DWARF) {
+ Object.DWARF->IsLittleEndian =
+ Object.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
+ Object.DWARF->Is64BitAddrSize =
+ Object.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
+ }
IO.setContext(nullptr);
}
-void MappingTraits<ELFYAML::AddrsigSymbol>::mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym) {
- assert(IO.getContext() && "The IO context is not initialized");
- IO.mapOptional("Name", Sym.Name);
- IO.mapOptional("Index", Sym.Index);
-}
-
void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO,
ELFYAML::LinkerOption &Opt) {
assert(IO.getContext() && "The IO context is not initialized");
@@ -1595,6 +1700,14 @@ void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO,
IO.mapRequired("Value", Opt.Value);
}
+void MappingTraits<ELFYAML::CallGraphEntry>::mapping(
+ IO &IO, ELFYAML::CallGraphEntry &E) {
+ assert(IO.getContext() && "The IO context is not initialized");
+ IO.mapRequired("From", E.From);
+ IO.mapRequired("To", E.To);
+ IO.mapRequired("Weight", E.Weight);
+}
+
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)