LLVM API Documentation
00001 //===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief This file declares classes for handling the YAML representation 00012 /// of ELF. 00013 /// 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_OBJECT_ELFYAML_H 00017 #define LLVM_OBJECT_ELFYAML_H 00018 00019 #include "llvm/MC/YAML.h" 00020 #include "llvm/Support/ELF.h" 00021 00022 namespace llvm { 00023 namespace ELFYAML { 00024 00025 // These types are invariant across 32/64-bit ELF, so for simplicity just 00026 // directly give them their exact sizes. We don't need to worry about 00027 // endianness because these are just the types in the YAMLIO structures, 00028 // and are appropriately converted to the necessary endianness when 00029 // reading/generating binary object files. 00030 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is 00031 // the common prefix of the respective constants. E.g. ELF_EM corresponds 00032 // to the `e_machine` constants, like `EM_X86_64`. 00033 // In the future, these would probably be better suited by C++11 enum 00034 // class's with appropriate fixed underlying type. 00035 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET) 00036 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM) 00037 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS) 00038 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA) 00039 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI) 00040 // Just use 64, since it can hold 32-bit values too. 00041 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF) 00042 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT) 00043 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_REL) 00044 // Just use 64, since it can hold 32-bit values too. 00045 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF) 00046 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT) 00047 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV) 00048 00049 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed 00050 // since 64-bit can hold 32-bit values too. 00051 struct FileHeader { 00052 ELF_ELFCLASS Class; 00053 ELF_ELFDATA Data; 00054 ELF_ELFOSABI OSABI; 00055 ELF_ET Type; 00056 ELF_EM Machine; 00057 ELF_EF Flags; 00058 llvm::yaml::Hex64 Entry; 00059 }; 00060 struct Symbol { 00061 StringRef Name; 00062 ELF_STT Type; 00063 StringRef Section; 00064 llvm::yaml::Hex64 Value; 00065 llvm::yaml::Hex64 Size; 00066 ELF_STV Visibility; 00067 }; 00068 struct LocalGlobalWeakSymbols { 00069 std::vector<Symbol> Local; 00070 std::vector<Symbol> Global; 00071 std::vector<Symbol> Weak; 00072 }; 00073 struct Section { 00074 enum class SectionKind { RawContent, Relocation }; 00075 SectionKind Kind; 00076 StringRef Name; 00077 ELF_SHT Type; 00078 ELF_SHF Flags; 00079 llvm::yaml::Hex64 Address; 00080 StringRef Link; 00081 llvm::yaml::Hex64 AddressAlign; 00082 Section(SectionKind Kind) : Kind(Kind) {} 00083 virtual ~Section(); 00084 }; 00085 struct RawContentSection : Section { 00086 yaml::BinaryRef Content; 00087 llvm::yaml::Hex64 Size; 00088 RawContentSection() : Section(SectionKind::RawContent) {} 00089 static bool classof(const Section *S) { 00090 return S->Kind == SectionKind::RawContent; 00091 } 00092 }; 00093 struct Relocation { 00094 llvm::yaml::Hex64 Offset; 00095 int64_t Addend; 00096 ELF_REL Type; 00097 StringRef Symbol; 00098 }; 00099 struct RelocationSection : Section { 00100 StringRef Info; 00101 std::vector<Relocation> Relocations; 00102 RelocationSection() : Section(SectionKind::Relocation) {} 00103 static bool classof(const Section *S) { 00104 return S->Kind == SectionKind::Relocation; 00105 } 00106 }; 00107 struct Object { 00108 FileHeader Header; 00109 std::vector<std::unique_ptr<Section>> Sections; 00110 // Although in reality the symbols reside in a section, it is a lot 00111 // cleaner and nicer if we read them from the YAML as a separate 00112 // top-level key, which automatically ensures that invariants like there 00113 // being a single SHT_SYMTAB section are upheld. 00114 LocalGlobalWeakSymbols Symbols; 00115 }; 00116 00117 } // end namespace ELFYAML 00118 } // end namespace llvm 00119 00120 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>) 00121 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol) 00122 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation) 00123 00124 namespace llvm { 00125 namespace yaml { 00126 00127 template <> 00128 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> { 00129 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value); 00130 }; 00131 00132 template <> 00133 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> { 00134 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value); 00135 }; 00136 00137 template <> 00138 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> { 00139 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value); 00140 }; 00141 00142 template <> 00143 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> { 00144 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value); 00145 }; 00146 00147 template <> 00148 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> { 00149 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value); 00150 }; 00151 00152 template <> 00153 struct ScalarBitSetTraits<ELFYAML::ELF_EF> { 00154 static void bitset(IO &IO, ELFYAML::ELF_EF &Value); 00155 }; 00156 00157 template <> 00158 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> { 00159 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value); 00160 }; 00161 00162 template <> 00163 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> { 00164 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value); 00165 }; 00166 00167 template <> 00168 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> { 00169 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value); 00170 }; 00171 00172 template <> 00173 struct ScalarEnumerationTraits<ELFYAML::ELF_STV> { 00174 static void enumeration(IO &IO, ELFYAML::ELF_STV &Value); 00175 }; 00176 00177 template <> 00178 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> { 00179 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value); 00180 }; 00181 00182 template <> 00183 struct MappingTraits<ELFYAML::FileHeader> { 00184 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); 00185 }; 00186 00187 template <> 00188 struct MappingTraits<ELFYAML::Symbol> { 00189 static void mapping(IO &IO, ELFYAML::Symbol &Symbol); 00190 }; 00191 00192 template <> 00193 struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> { 00194 static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols); 00195 }; 00196 00197 template <> struct MappingTraits<ELFYAML::Relocation> { 00198 static void mapping(IO &IO, ELFYAML::Relocation &Rel); 00199 }; 00200 00201 template <> 00202 struct MappingTraits<std::unique_ptr<ELFYAML::Section>> { 00203 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section); 00204 static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section); 00205 }; 00206 00207 template <> 00208 struct MappingTraits<ELFYAML::Object> { 00209 static void mapping(IO &IO, ELFYAML::Object &Object); 00210 }; 00211 00212 } // end namespace yaml 00213 } // end namespace llvm 00214 00215 #endif