LLVM API Documentation

ELFYAML.h
Go to the documentation of this file.
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