1259698Sdim//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
2259698Sdim//
3259698Sdim//                     The LLVM Compiler Infrastructure
4259698Sdim//
5259698Sdim// This file is distributed under the University of Illinois Open Source
6259698Sdim// License. See LICENSE.TXT for details.
7259698Sdim//
8259698Sdim//===----------------------------------------------------------------------===//
9259698Sdim///
10259698Sdim/// \file
11259698Sdim/// \brief This file declares classes for handling the YAML representation
12259698Sdim/// of ELF.
13259698Sdim///
14259698Sdim//===----------------------------------------------------------------------===//
15259698Sdim
16259698Sdim#ifndef LLVM_OBJECT_ELFYAML_H
17259698Sdim#define LLVM_OBJECT_ELFYAML_H
18259698Sdim
19259698Sdim#include "llvm/Object/YAML.h"
20259698Sdim#include "llvm/Support/ELF.h"
21259698Sdim
22259698Sdimnamespace llvm {
23259698Sdimnamespace ELFYAML {
24259698Sdim
25259698Sdim// These types are invariant across 32/64-bit ELF, so for simplicity just
26259698Sdim// directly give them their exact sizes. We don't need to worry about
27259698Sdim// endianness because these are just the types in the YAMLIO structures,
28259698Sdim// and are appropriately converted to the necessary endianness when
29259698Sdim// reading/generating binary object files.
30259698Sdim// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
31259698Sdim// the common prefix of the respective constants. E.g. ELF_EM corresponds
32259698Sdim// to the `e_machine` constants, like `EM_X86_64`.
33259698Sdim// In the future, these would probably be better suited by C++11 enum
34259698Sdim// class's with appropriate fixed underlying type.
35259698SdimLLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
36259698SdimLLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
37259698SdimLLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
38259698SdimLLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
39259698SdimLLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
40259698SdimLLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
41259698Sdim// Just use 64, since it can hold 32-bit values too.
42259698SdimLLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
43259698SdimLLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
44259698Sdim
45259698Sdim// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
46259698Sdim// since 64-bit can hold 32-bit values too.
47259698Sdimstruct FileHeader {
48259698Sdim  ELF_ELFCLASS Class;
49259698Sdim  ELF_ELFDATA Data;
50259698Sdim  ELF_ELFOSABI OSABI;
51259698Sdim  ELF_ET Type;
52259698Sdim  ELF_EM Machine;
53259698Sdim  llvm::yaml::Hex64 Entry;
54259698Sdim};
55259698Sdimstruct Symbol {
56259698Sdim  StringRef Name;
57259698Sdim  ELF_STT Type;
58259698Sdim  StringRef Section;
59259698Sdim  llvm::yaml::Hex64 Value;
60259698Sdim  llvm::yaml::Hex64 Size;
61259698Sdim};
62259698Sdimstruct LocalGlobalWeakSymbols {
63259698Sdim  std::vector<Symbol> Local;
64259698Sdim  std::vector<Symbol> Global;
65259698Sdim  std::vector<Symbol> Weak;
66259698Sdim};
67259698Sdimstruct Section {
68259698Sdim  StringRef Name;
69259698Sdim  ELF_SHT Type;
70259698Sdim  ELF_SHF Flags;
71259698Sdim  llvm::yaml::Hex64 Address;
72259698Sdim  object::yaml::BinaryRef Content;
73259698Sdim  StringRef Link;
74259698Sdim  llvm::yaml::Hex64 AddressAlign;
75259698Sdim};
76259698Sdimstruct Object {
77259698Sdim  FileHeader Header;
78259698Sdim  std::vector<Section> Sections;
79259698Sdim  // Although in reality the symbols reside in a section, it is a lot
80259698Sdim  // cleaner and nicer if we read them from the YAML as a separate
81259698Sdim  // top-level key, which automatically ensures that invariants like there
82259698Sdim  // being a single SHT_SYMTAB section are upheld.
83259698Sdim  LocalGlobalWeakSymbols Symbols;
84259698Sdim};
85259698Sdim
86259698Sdim} // end namespace ELFYAML
87259698Sdim} // end namespace llvm
88259698Sdim
89259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Section)
90259698SdimLLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
91259698Sdim
92259698Sdimnamespace llvm {
93259698Sdimnamespace yaml {
94259698Sdim
95259698Sdimtemplate <>
96259698Sdimstruct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
97259698Sdim  static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
98259698Sdim};
99259698Sdim
100259698Sdimtemplate <>
101259698Sdimstruct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
102259698Sdim  static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
103259698Sdim};
104259698Sdim
105259698Sdimtemplate <>
106259698Sdimstruct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
107259698Sdim  static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
108259698Sdim};
109259698Sdim
110259698Sdimtemplate <>
111259698Sdimstruct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
112259698Sdim  static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
113259698Sdim};
114259698Sdim
115259698Sdimtemplate <>
116259698Sdimstruct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
117259698Sdim  static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
118259698Sdim};
119259698Sdim
120259698Sdimtemplate <>
121259698Sdimstruct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
122259698Sdim  static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
123259698Sdim};
124259698Sdim
125259698Sdimtemplate <>
126259698Sdimstruct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
127259698Sdim  static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
128259698Sdim};
129259698Sdim
130259698Sdimtemplate <>
131259698Sdimstruct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
132259698Sdim  static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
133259698Sdim};
134259698Sdim
135259698Sdimtemplate <>
136259698Sdimstruct MappingTraits<ELFYAML::FileHeader> {
137259698Sdim  static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
138259698Sdim};
139259698Sdim
140259698Sdimtemplate <>
141259698Sdimstruct MappingTraits<ELFYAML::Symbol> {
142259698Sdim  static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
143259698Sdim};
144259698Sdim
145259698Sdimtemplate <>
146259698Sdimstruct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
147259698Sdim  static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
148259698Sdim};
149259698Sdim
150259698Sdimtemplate <>
151259698Sdimstruct MappingTraits<ELFYAML::Section> {
152259698Sdim  static void mapping(IO &IO, ELFYAML::Section &Section);
153259698Sdim};
154259698Sdim
155259698Sdimtemplate <>
156259698Sdimstruct MappingTraits<ELFYAML::Object> {
157259698Sdim  static void mapping(IO &IO, ELFYAML::Object &Object);
158259698Sdim};
159259698Sdim
160259698Sdim} // end namespace yaml
161259698Sdim} // end namespace llvm
162259698Sdim
163259698Sdim#endif
164