Line data Source code
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 : /// 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 :
19 : #include "llvm/ADT/StringRef.h"
20 : #include "llvm/ObjectYAML/YAML.h"
21 : #include "llvm/Support/YAMLTraits.h"
22 : #include <cstdint>
23 : #include <memory>
24 : #include <vector>
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 345 : LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
40 55 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
41 346 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
42 288 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
43 288 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
44 454 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
45 : // Just use 64, since it can hold 32-bit values too.
46 477 : LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
47 56 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
48 1087 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
49 191 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
50 27 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
51 : // Just use 64, since it can hold 32-bit values too.
52 689 : LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
53 9 : LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
54 701 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
55 406 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
56 782 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO)
57 :
58 44 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
59 22 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
60 15 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
61 14 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
62 14 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
63 11 : 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 : };
76 :
77 : struct SectionName {
78 : StringRef Section;
79 : };
80 :
81 84 : struct ProgramHeader {
82 : ELF_PT Type;
83 : ELF_PF Flags;
84 : llvm::yaml::Hex64 VAddr;
85 : llvm::yaml::Hex64 PAddr;
86 : Optional<llvm::yaml::Hex64> Align;
87 : std::vector<SectionName> Sections;
88 : };
89 :
90 414 : struct Symbol {
91 : StringRef Name;
92 : ELF_STT Type;
93 : StringRef Section;
94 : Optional<ELF_SHN> Index;
95 : llvm::yaml::Hex64 Value;
96 : llvm::yaml::Hex64 Size;
97 : uint8_t Other;
98 : };
99 :
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 589 : 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;
126 : Optional<llvm::yaml::Hex64> EntSize;
127 :
128 592 : Section(SectionKind Kind) : Kind(Kind) {}
129 : virtual ~Section();
130 : };
131 : struct RawContentSection : Section {
132 : yaml::BinaryRef Content;
133 : llvm::yaml::Hex64 Size;
134 :
135 904 : RawContentSection() : Section(SectionKind::RawContent) {}
136 :
137 0 : static bool classof(const Section *S) {
138 0 : return S->Kind == SectionKind::RawContent;
139 : }
140 : };
141 :
142 : struct NoBitsSection : Section {
143 : llvm::yaml::Hex64 Size;
144 :
145 40 : NoBitsSection() : Section(SectionKind::NoBits) {}
146 :
147 0 : static bool classof(const Section *S) {
148 0 : return S->Kind == SectionKind::NoBits;
149 : }
150 : };
151 :
152 : struct Group : Section {
153 : // Members of a group contain a flag and a list of section indices
154 : // that are part of the group.
155 : std::vector<SectionOrType> Members;
156 :
157 40 : Group() : Section(SectionKind::Group) {}
158 :
159 0 : static bool classof(const Section *S) {
160 0 : return S->Kind == SectionKind::Group;
161 : }
162 : };
163 :
164 136 : struct Relocation {
165 : llvm::yaml::Hex64 Offset;
166 : int64_t Addend;
167 : ELF_REL Type;
168 : Optional<StringRef> Symbol;
169 : };
170 :
171 : struct RelocationSection : Section {
172 : std::vector<Relocation> Relocations;
173 :
174 178 : RelocationSection() : Section(SectionKind::Relocation) {}
175 :
176 0 : static bool classof(const Section *S) {
177 0 : return S->Kind == SectionKind::Relocation;
178 : }
179 : };
180 :
181 : // Represents .MIPS.abiflags section
182 : struct MipsABIFlags : Section {
183 : llvm::yaml::Hex16 Version;
184 : MIPS_ISA ISALevel;
185 : llvm::yaml::Hex8 ISARevision;
186 : MIPS_AFL_REG GPRSize;
187 : MIPS_AFL_REG CPR1Size;
188 : MIPS_AFL_REG CPR2Size;
189 : MIPS_ABI_FP FpABI;
190 : MIPS_AFL_EXT ISAExtension;
191 : MIPS_AFL_ASE ASEs;
192 : MIPS_AFL_FLAGS1 Flags1;
193 : llvm::yaml::Hex32 Flags2;
194 :
195 22 : MipsABIFlags() : Section(SectionKind::MipsABIFlags) {}
196 :
197 0 : static bool classof(const Section *S) {
198 0 : return S->Kind == SectionKind::MipsABIFlags;
199 : }
200 : };
201 :
202 : struct Object {
203 : FileHeader Header;
204 : std::vector<ProgramHeader> ProgramHeaders;
205 : std::vector<std::unique_ptr<Section>> Sections;
206 : // Although in reality the symbols reside in a section, it is a lot
207 : // cleaner and nicer if we read them from the YAML as a separate
208 : // top-level key, which automatically ensures that invariants like there
209 : // being a single SHT_SYMTAB section are upheld.
210 : LocalGlobalWeakSymbols Symbols;
211 : LocalGlobalWeakSymbols DynamicSymbols;
212 : };
213 :
214 : } // end namespace ELFYAML
215 : } // end namespace llvm
216 :
217 : LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
218 : LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>)
219 : LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
220 : LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
221 : LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
222 : LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName)
223 :
224 : namespace llvm {
225 : namespace yaml {
226 :
227 : template <>
228 : struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
229 : static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
230 : };
231 :
232 : template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
233 : static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
234 : };
235 :
236 : template <>
237 : struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
238 : static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
239 : };
240 :
241 : template <>
242 : struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
243 : static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
244 : };
245 :
246 : template <>
247 : struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
248 : static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
249 : };
250 :
251 : template <>
252 : struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
253 : static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
254 : };
255 :
256 : template <>
257 : struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
258 : static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
259 : };
260 :
261 : template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
262 : static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
263 : };
264 :
265 : template <>
266 : struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
267 : static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
268 : };
269 :
270 : template <>
271 : struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
272 : static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
273 : };
274 :
275 : template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
276 : static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
277 : };
278 :
279 : template <>
280 : struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
281 : static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
282 : };
283 :
284 : template <>
285 : struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
286 : static void enumeration(IO &IO, ELFYAML::ELF_STV &Value);
287 : };
288 :
289 : template <>
290 : struct ScalarBitSetTraits<ELFYAML::ELF_STO> {
291 : static void bitset(IO &IO, ELFYAML::ELF_STO &Value);
292 : };
293 :
294 : template <>
295 : struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
296 : static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
297 : };
298 :
299 : template <>
300 : struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
301 : static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
302 : };
303 :
304 : template <>
305 : struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
306 : static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
307 : };
308 :
309 : template <>
310 : struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
311 : static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
312 : };
313 :
314 : template <>
315 : struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
316 : static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
317 : };
318 :
319 : template <>
320 : struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
321 : static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
322 : };
323 :
324 : template <>
325 : struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
326 : static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
327 : };
328 :
329 : template <>
330 : struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
331 : static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
332 : };
333 :
334 : template <>
335 : struct MappingTraits<ELFYAML::FileHeader> {
336 : static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
337 : };
338 :
339 : template <> struct MappingTraits<ELFYAML::ProgramHeader> {
340 : static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
341 : };
342 :
343 : template <>
344 : struct MappingTraits<ELFYAML::Symbol> {
345 : static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
346 : static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol);
347 : };
348 :
349 : template <>
350 : struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
351 : static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
352 : };
353 :
354 : template <> struct MappingTraits<ELFYAML::Relocation> {
355 : static void mapping(IO &IO, ELFYAML::Relocation &Rel);
356 : };
357 :
358 : template <>
359 : struct MappingTraits<std::unique_ptr<ELFYAML::Section>> {
360 : static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section);
361 : static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section);
362 : };
363 :
364 : template <>
365 : struct MappingTraits<ELFYAML::Object> {
366 : static void mapping(IO &IO, ELFYAML::Object &Object);
367 : };
368 :
369 : template <> struct MappingTraits<ELFYAML::SectionOrType> {
370 : static void mapping(IO &IO, ELFYAML::SectionOrType §ionOrType);
371 : };
372 :
373 : template <> struct MappingTraits<ELFYAML::SectionName> {
374 : static void mapping(IO &IO, ELFYAML::SectionName §ionName);
375 : };
376 :
377 : } // end namespace yaml
378 : } // end namespace llvm
379 :
380 : #endif // LLVM_OBJECTYAML_ELFYAML_H
|