ELFYAML.h revision ebe69fe11e48d322045d5949c83283927a0d790b
1//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9/// 10/// \file 11/// \brief This file declares classes for handling the YAML representation 12/// of ELF. 13/// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_OBJECT_ELFYAML_H 17#define LLVM_OBJECT_ELFYAML_H 18 19#include "llvm/MC/YAML.h" 20#include "llvm/Support/ELF.h" 21 22namespace llvm { 23namespace ELFYAML { 24 25// These types are invariant across 32/64-bit ELF, so for simplicity just 26// directly give them their exact sizes. We don't need to worry about 27// endianness because these are just the types in the YAMLIO structures, 28// and are appropriately converted to the necessary endianness when 29// reading/generating binary object files. 30// The naming of these types is intended to be ELF_PREFIX, where PREFIX is 31// the common prefix of the respective constants. E.g. ELF_EM corresponds 32// to the `e_machine` constants, like `EM_X86_64`. 33// In the future, these would probably be better suited by C++11 enum 34// class's with appropriate fixed underlying type. 35LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET) 36LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM) 37LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS) 38LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA) 39LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI) 40// Just use 64, since it can hold 32-bit values too. 41LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF) 42LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT) 43LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL) 44LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS) 45// Just use 64, since it can hold 32-bit values too. 46LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF) 47LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT) 48LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV) 49LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO) 50 51// For now, hardcode 64 bits everywhere that 32 or 64 would be needed 52// since 64-bit can hold 32-bit values too. 53struct FileHeader { 54 ELF_ELFCLASS Class; 55 ELF_ELFDATA Data; 56 ELF_ELFOSABI OSABI; 57 ELF_ET Type; 58 ELF_EM Machine; 59 ELF_EF Flags; 60 llvm::yaml::Hex64 Entry; 61}; 62struct Symbol { 63 StringRef Name; 64 ELF_STT Type; 65 StringRef Section; 66 llvm::yaml::Hex64 Value; 67 llvm::yaml::Hex64 Size; 68 uint8_t Other; 69}; 70struct LocalGlobalWeakSymbols { 71 std::vector<Symbol> Local; 72 std::vector<Symbol> Global; 73 std::vector<Symbol> Weak; 74}; 75 76struct SectionOrType { 77 StringRef sectionNameOrType; 78}; 79 80struct Section { 81 enum class SectionKind { Group, RawContent, Relocation }; 82 SectionKind Kind; 83 StringRef Name; 84 ELF_SHT Type; 85 ELF_SHF Flags; 86 llvm::yaml::Hex64 Address; 87 StringRef Link; 88 StringRef Info; 89 llvm::yaml::Hex64 AddressAlign; 90 Section(SectionKind Kind) : Kind(Kind) {} 91 virtual ~Section(); 92}; 93struct RawContentSection : Section { 94 yaml::BinaryRef Content; 95 llvm::yaml::Hex64 Size; 96 RawContentSection() : Section(SectionKind::RawContent) {} 97 static bool classof(const Section *S) { 98 return S->Kind == SectionKind::RawContent; 99 } 100}; 101 102struct Group : Section { 103 // Members of a group contain a flag and a list of section indices 104 // that are part of the group. 105 std::vector<SectionOrType> Members; 106 Group() : Section(SectionKind::Group) {} 107 static bool classof(const Section *S) { 108 return S->Kind == SectionKind::Group; 109 } 110}; 111 112struct Relocation { 113 llvm::yaml::Hex64 Offset; 114 int64_t Addend; 115 ELF_REL Type; 116 StringRef Symbol; 117}; 118struct RelocationSection : Section { 119 std::vector<Relocation> Relocations; 120 RelocationSection() : Section(SectionKind::Relocation) {} 121 static bool classof(const Section *S) { 122 return S->Kind == SectionKind::Relocation; 123 } 124}; 125struct Object { 126 FileHeader Header; 127 std::vector<std::unique_ptr<Section>> Sections; 128 // Although in reality the symbols reside in a section, it is a lot 129 // cleaner and nicer if we read them from the YAML as a separate 130 // top-level key, which automatically ensures that invariants like there 131 // being a single SHT_SYMTAB section are upheld. 132 LocalGlobalWeakSymbols Symbols; 133}; 134 135} // end namespace ELFYAML 136} // end namespace llvm 137 138LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>) 139LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol) 140LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation) 141LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType) 142 143namespace llvm { 144namespace yaml { 145 146template <> 147struct ScalarEnumerationTraits<ELFYAML::ELF_ET> { 148 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value); 149}; 150 151template <> 152struct ScalarEnumerationTraits<ELFYAML::ELF_EM> { 153 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value); 154}; 155 156template <> 157struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> { 158 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value); 159}; 160 161template <> 162struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> { 163 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value); 164}; 165 166template <> 167struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> { 168 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value); 169}; 170 171template <> 172struct ScalarBitSetTraits<ELFYAML::ELF_EF> { 173 static void bitset(IO &IO, ELFYAML::ELF_EF &Value); 174}; 175 176template <> 177struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> { 178 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value); 179}; 180 181template <> 182struct ScalarBitSetTraits<ELFYAML::ELF_SHF> { 183 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value); 184}; 185 186template <> 187struct ScalarEnumerationTraits<ELFYAML::ELF_STT> { 188 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value); 189}; 190 191template <> 192struct ScalarEnumerationTraits<ELFYAML::ELF_STV> { 193 static void enumeration(IO &IO, ELFYAML::ELF_STV &Value); 194}; 195 196template <> 197struct ScalarBitSetTraits<ELFYAML::ELF_STO> { 198 static void bitset(IO &IO, ELFYAML::ELF_STO &Value); 199}; 200 201template <> 202struct ScalarEnumerationTraits<ELFYAML::ELF_REL> { 203 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value); 204}; 205 206template <> 207struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> { 208 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value); 209}; 210 211template <> 212struct MappingTraits<ELFYAML::FileHeader> { 213 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); 214}; 215 216template <> 217struct MappingTraits<ELFYAML::Symbol> { 218 static void mapping(IO &IO, ELFYAML::Symbol &Symbol); 219}; 220 221template <> 222struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> { 223 static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols); 224}; 225 226template <> struct MappingTraits<ELFYAML::Relocation> { 227 static void mapping(IO &IO, ELFYAML::Relocation &Rel); 228}; 229 230template <> 231struct MappingTraits<std::unique_ptr<ELFYAML::Section>> { 232 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section); 233 static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section); 234}; 235 236template <> 237struct MappingTraits<ELFYAML::Object> { 238 static void mapping(IO &IO, ELFYAML::Object &Object); 239}; 240 241template <> struct MappingTraits<ELFYAML::SectionOrType> { 242 static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType); 243}; 244 245} // end namespace yaml 246} // end namespace llvm 247 248#endif 249