diff options
Diffstat (limited to 'llvm/lib/ObjectYAML/ELFYAML.cpp')
| -rw-r--r-- | llvm/lib/ObjectYAML/ELFYAML.cpp | 157 | 
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 §ionOrType) {    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) | 
