120
|
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_OBJECTYAML_ELFYAML_H
|
|
17 #define LLVM_OBJECTYAML_ELFYAML_H
|
|
18
|
121
|
19 #include "llvm/ADT/StringRef.h"
|
120
|
20 #include "llvm/ObjectYAML/YAML.h"
|
121
|
21 #include "llvm/Support/YAMLTraits.h"
|
|
22 #include <cstdint>
|
|
23 #include <memory>
|
|
24 #include <vector>
|
120
|
25
|
|
26 namespace llvm {
|
|
27 namespace ELFYAML {
|
|
28
|
|
29 // These types are invariant across 32/64-bit ELF, so for simplicity just
|
|
30 // directly give them their exact sizes. We don't need to worry about
|
|
31 // endianness because these are just the types in the YAMLIO structures,
|
|
32 // and are appropriately converted to the necessary endianness when
|
|
33 // reading/generating binary object files.
|
|
34 // The naming of these types is intended to be ELF_PREFIX, where PREFIX is
|
|
35 // the common prefix of the respective constants. E.g. ELF_EM corresponds
|
|
36 // to the `e_machine` constants, like `EM_X86_64`.
|
|
37 // In the future, these would probably be better suited by C++11 enum
|
|
38 // class's with appropriate fixed underlying type.
|
|
39 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
|
121
|
40 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
|
120
|
41 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
|
|
42 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
|
|
43 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
|
|
44 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
|
|
45 // Just use 64, since it can hold 32-bit values too.
|
|
46 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
|
121
|
47 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
|
120
|
48 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
|
|
49 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
|
|
50 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
|
|
51 // Just use 64, since it can hold 32-bit values too.
|
|
52 LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
|
121
|
53 LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
|
120
|
54 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
|
|
55 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
|
|
56 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO)
|
|
57
|
|
58 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
|
|
59 LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
|
|
60 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
|
|
61 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
|
|
62 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
|
|
63 LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
|
|
64
|
|
65 // For now, hardcode 64 bits everywhere that 32 or 64 would be needed
|
|
66 // since 64-bit can hold 32-bit values too.
|
|
67 struct FileHeader {
|
|
68 ELF_ELFCLASS Class;
|
|
69 ELF_ELFDATA Data;
|
|
70 ELF_ELFOSABI OSABI;
|
|
71 ELF_ET Type;
|
|
72 ELF_EM Machine;
|
|
73 ELF_EF Flags;
|
|
74 llvm::yaml::Hex64 Entry;
|
|
75 };
|
121
|
76
|
|
77 struct SectionName {
|
|
78 StringRef Section;
|
|
79 };
|
|
80
|
|
81 struct ProgramHeader {
|
|
82 ELF_PT Type;
|
|
83 ELF_PF Flags;
|
|
84 llvm::yaml::Hex64 VAddr;
|
|
85 llvm::yaml::Hex64 PAddr;
|
134
|
86 Optional<llvm::yaml::Hex64> Align;
|
121
|
87 std::vector<SectionName> Sections;
|
|
88 };
|
|
89
|
120
|
90 struct Symbol {
|
|
91 StringRef Name;
|
|
92 ELF_STT Type;
|
|
93 StringRef Section;
|
121
|
94 Optional<ELF_SHN> Index;
|
120
|
95 llvm::yaml::Hex64 Value;
|
|
96 llvm::yaml::Hex64 Size;
|
|
97 uint8_t Other;
|
|
98 };
|
121
|
99
|
120
|
100 struct LocalGlobalWeakSymbols {
|
|
101 std::vector<Symbol> Local;
|
|
102 std::vector<Symbol> Global;
|
|
103 std::vector<Symbol> Weak;
|
|
104 };
|
|
105
|
|
106 struct SectionOrType {
|
|
107 StringRef sectionNameOrType;
|
|
108 };
|
|
109
|
|
110 struct Section {
|
|
111 enum class SectionKind {
|
|
112 Group,
|
|
113 RawContent,
|
|
114 Relocation,
|
|
115 NoBits,
|
|
116 MipsABIFlags
|
|
117 };
|
|
118 SectionKind Kind;
|
|
119 StringRef Name;
|
|
120 ELF_SHT Type;
|
|
121 ELF_SHF Flags;
|
|
122 llvm::yaml::Hex64 Address;
|
|
123 StringRef Link;
|
|
124 StringRef Info;
|
|
125 llvm::yaml::Hex64 AddressAlign;
|
121
|
126
|
120
|
127 Section(SectionKind Kind) : Kind(Kind) {}
|
|
128 virtual ~Section();
|
|
129 };
|
|
130 struct RawContentSection : Section {
|
|
131 yaml::BinaryRef Content;
|
|
132 llvm::yaml::Hex64 Size;
|
121
|
133
|
120
|
134 RawContentSection() : Section(SectionKind::RawContent) {}
|
121
|
135
|
120
|
136 static bool classof(const Section *S) {
|
|
137 return S->Kind == SectionKind::RawContent;
|
|
138 }
|
|
139 };
|
|
140
|
|
141 struct NoBitsSection : Section {
|
|
142 llvm::yaml::Hex64 Size;
|
121
|
143
|
120
|
144 NoBitsSection() : Section(SectionKind::NoBits) {}
|
121
|
145
|
120
|
146 static bool classof(const Section *S) {
|
|
147 return S->Kind == SectionKind::NoBits;
|
|
148 }
|
|
149 };
|
|
150
|
|
151 struct Group : Section {
|
|
152 // Members of a group contain a flag and a list of section indices
|
|
153 // that are part of the group.
|
|
154 std::vector<SectionOrType> Members;
|
121
|
155
|
120
|
156 Group() : Section(SectionKind::Group) {}
|
121
|
157
|
120
|
158 static bool classof(const Section *S) {
|
|
159 return S->Kind == SectionKind::Group;
|
|
160 }
|
|
161 };
|
|
162
|
|
163 struct Relocation {
|
|
164 llvm::yaml::Hex64 Offset;
|
|
165 int64_t Addend;
|
|
166 ELF_REL Type;
|
121
|
167 Optional<StringRef> Symbol;
|
120
|
168 };
|
121
|
169
|
120
|
170 struct RelocationSection : Section {
|
|
171 std::vector<Relocation> Relocations;
|
121
|
172
|
120
|
173 RelocationSection() : Section(SectionKind::Relocation) {}
|
121
|
174
|
120
|
175 static bool classof(const Section *S) {
|
|
176 return S->Kind == SectionKind::Relocation;
|
|
177 }
|
|
178 };
|
|
179
|
|
180 // Represents .MIPS.abiflags section
|
|
181 struct MipsABIFlags : Section {
|
|
182 llvm::yaml::Hex16 Version;
|
|
183 MIPS_ISA ISALevel;
|
|
184 llvm::yaml::Hex8 ISARevision;
|
|
185 MIPS_AFL_REG GPRSize;
|
|
186 MIPS_AFL_REG CPR1Size;
|
|
187 MIPS_AFL_REG CPR2Size;
|
|
188 MIPS_ABI_FP FpABI;
|
|
189 MIPS_AFL_EXT ISAExtension;
|
|
190 MIPS_AFL_ASE ASEs;
|
|
191 MIPS_AFL_FLAGS1 Flags1;
|
|
192 llvm::yaml::Hex32 Flags2;
|
121
|
193
|
120
|
194 MipsABIFlags() : Section(SectionKind::MipsABIFlags) {}
|
121
|
195
|
120
|
196 static bool classof(const Section *S) {
|
|
197 return S->Kind == SectionKind::MipsABIFlags;
|
|
198 }
|
|
199 };
|
|
200
|
|
201 struct Object {
|
|
202 FileHeader Header;
|
121
|
203 std::vector<ProgramHeader> ProgramHeaders;
|
120
|
204 std::vector<std::unique_ptr<Section>> Sections;
|
|
205 // Although in reality the symbols reside in a section, it is a lot
|
|
206 // cleaner and nicer if we read them from the YAML as a separate
|
|
207 // top-level key, which automatically ensures that invariants like there
|
|
208 // being a single SHT_SYMTAB section are upheld.
|
|
209 LocalGlobalWeakSymbols Symbols;
|
134
|
210 LocalGlobalWeakSymbols DynamicSymbols;
|
120
|
211 };
|
|
212
|
|
213 } // end namespace ELFYAML
|
|
214 } // end namespace llvm
|
|
215
|
121
|
216 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
|
120
|
217 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
|
|
218 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
|
|
219 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
|
|
220 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
|
121
|
221 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName)
|
120
|
222
|
|
223 namespace llvm {
|
|
224 namespace yaml {
|
|
225
|
|
226 template <>
|
|
227 struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
|
|
228 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
|
|
229 };
|
|
230
|
121
|
231 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
|
|
232 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
|
|
233 };
|
|
234
|
120
|
235 template <>
|
|
236 struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
|
|
237 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
|
|
238 };
|
|
239
|
|
240 template <>
|
|
241 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
|
|
242 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
|
|
243 };
|
|
244
|
|
245 template <>
|
|
246 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
|
|
247 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
|
|
248 };
|
|
249
|
|
250 template <>
|
|
251 struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
|
|
252 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
|
|
253 };
|
|
254
|
|
255 template <>
|
|
256 struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
|
|
257 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
|
|
258 };
|
|
259
|
121
|
260 template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
|
|
261 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
|
|
262 };
|
|
263
|
120
|
264 template <>
|
|
265 struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
|
|
266 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
|
|
267 };
|
|
268
|
|
269 template <>
|
|
270 struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
|
|
271 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
|
|
272 };
|
|
273
|
121
|
274 template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
|
|
275 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
|
|
276 };
|
|
277
|
120
|
278 template <>
|
|
279 struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
|
|
280 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
|
|
281 };
|
|
282
|
|
283 template <>
|
|
284 struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
|
|
285 static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
|
|
286 };
|
|
287
|
|
288 template <>
|
|
289 struct ScalarBitSetTraits<ELFYAML::ELF_STO> {
|
|
290 static void bitset(IO &IO, ELFYAML::ELF_STO &Value);
|
|
291 };
|
|
292
|
|
293 template <>
|
|
294 struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
|
|
295 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
|
|
296 };
|
|
297
|
|
298 template <>
|
|
299 struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
|
|
300 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
|
|
301 };
|
|
302
|
|
303 template <>
|
|
304 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
|
|
305 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
|
|
306 };
|
|
307
|
|
308 template <>
|
|
309 struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
|
|
310 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
|
|
311 };
|
|
312
|
|
313 template <>
|
|
314 struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
|
|
315 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
|
|
316 };
|
|
317
|
|
318 template <>
|
|
319 struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
|
|
320 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
|
|
321 };
|
|
322
|
|
323 template <>
|
|
324 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
|
|
325 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
|
|
326 };
|
|
327
|
|
328 template <>
|
|
329 struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
|
|
330 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
|
|
331 };
|
|
332
|
|
333 template <>
|
|
334 struct MappingTraits<ELFYAML::FileHeader> {
|
|
335 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
|
|
336 };
|
|
337
|
121
|
338 template <> struct MappingTraits<ELFYAML::ProgramHeader> {
|
|
339 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
|
|
340 };
|
|
341
|
120
|
342 template <>
|
|
343 struct MappingTraits<ELFYAML::Symbol> {
|
|
344 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
|
121
|
345 static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol);
|
120
|
346 };
|
|
347
|
|
348 template <>
|
|
349 struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
|
|
350 static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
|
|
351 };
|
|
352
|
|
353 template <> struct MappingTraits<ELFYAML::Relocation> {
|
|
354 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
|
|
355 };
|
|
356
|
|
357 template <>
|
|
358 struct MappingTraits<std::unique_ptr<ELFYAML::Section>> {
|
|
359 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section);
|
|
360 static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section);
|
|
361 };
|
|
362
|
|
363 template <>
|
|
364 struct MappingTraits<ELFYAML::Object> {
|
|
365 static void mapping(IO &IO, ELFYAML::Object &Object);
|
|
366 };
|
|
367
|
|
368 template <> struct MappingTraits<ELFYAML::SectionOrType> {
|
|
369 static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType);
|
|
370 };
|
|
371
|
121
|
372 template <> struct MappingTraits<ELFYAML::SectionName> {
|
|
373 static void mapping(IO &IO, ELFYAML::SectionName §ionName);
|
|
374 };
|
|
375
|
120
|
376 } // end namespace yaml
|
|
377 } // end namespace llvm
|
|
378
|
121
|
379 #endif // LLVM_OBJECTYAML_ELFYAML_H
|