1 | //===- ELFYAML.cpp - ELF YAMLIO implementation ----------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines classes for handling the YAML representation of ELF. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/ObjectYAML/ELFYAML.h" |
14 | #include "llvm/ADT/APInt.h" |
15 | #include "llvm/ADT/MapVector.h" |
16 | #include "llvm/ADT/StringRef.h" |
17 | #include "llvm/BinaryFormat/ELF.h" |
18 | #include "llvm/Support/ARMEHABI.h" |
19 | #include "llvm/Support/Casting.h" |
20 | #include "llvm/Support/ErrorHandling.h" |
21 | #include "llvm/Support/MipsABIFlags.h" |
22 | #include "llvm/Support/YAMLTraits.h" |
23 | #include "llvm/Support/WithColor.h" |
24 | #include <cassert> |
25 | #include <cstdint> |
26 | #include <optional> |
27 | |
28 | namespace llvm { |
29 | |
30 | ELFYAML::Chunk::~Chunk() = default; |
31 | |
32 | namespace ELFYAML { |
33 | ELF_ELFOSABI Object::getOSAbi() const { return Header.OSABI; } |
34 | |
35 | unsigned Object::getMachine() const { |
36 | if (Header.Machine) |
37 | return *Header.Machine; |
38 | return llvm::ELF::EM_NONE; |
39 | } |
40 | |
41 | constexpr StringRef SectionHeaderTable::; |
42 | } // namespace ELFYAML |
43 | |
44 | namespace yaml { |
45 | |
46 | void ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration( |
47 | IO &IO, ELFYAML::ELF_ET &Value) { |
48 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
49 | ECase(ET_NONE); |
50 | ECase(ET_REL); |
51 | ECase(ET_EXEC); |
52 | ECase(ET_DYN); |
53 | ECase(ET_CORE); |
54 | #undef ECase |
55 | IO.enumFallback<Hex16>(Val&: Value); |
56 | } |
57 | |
58 | void ScalarEnumerationTraits<ELFYAML::ELF_PT>::enumeration( |
59 | IO &IO, ELFYAML::ELF_PT &Value) { |
60 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
61 | ECase(PT_NULL); |
62 | ECase(PT_LOAD); |
63 | ECase(PT_DYNAMIC); |
64 | ECase(PT_INTERP); |
65 | ECase(PT_NOTE); |
66 | ECase(PT_SHLIB); |
67 | ECase(PT_PHDR); |
68 | ECase(PT_TLS); |
69 | ECase(PT_GNU_EH_FRAME); |
70 | ECase(PT_GNU_STACK); |
71 | ECase(PT_GNU_RELRO); |
72 | ECase(PT_GNU_PROPERTY); |
73 | #undef ECase |
74 | IO.enumFallback<Hex32>(Val&: Value); |
75 | } |
76 | |
77 | void ScalarEnumerationTraits<ELFYAML::ELF_NT>::enumeration( |
78 | IO &IO, ELFYAML::ELF_NT &Value) { |
79 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
80 | // Generic note types. |
81 | ECase(NT_VERSION); |
82 | ECase(NT_ARCH); |
83 | ECase(NT_GNU_BUILD_ATTRIBUTE_OPEN); |
84 | ECase(NT_GNU_BUILD_ATTRIBUTE_FUNC); |
85 | // Core note types. |
86 | ECase(NT_PRSTATUS); |
87 | ECase(NT_FPREGSET); |
88 | ECase(NT_PRPSINFO); |
89 | ECase(NT_TASKSTRUCT); |
90 | ECase(NT_AUXV); |
91 | ECase(NT_PSTATUS); |
92 | ECase(NT_FPREGS); |
93 | ECase(NT_PSINFO); |
94 | ECase(NT_LWPSTATUS); |
95 | ECase(NT_LWPSINFO); |
96 | ECase(NT_WIN32PSTATUS); |
97 | ECase(NT_PPC_VMX); |
98 | ECase(NT_PPC_VSX); |
99 | ECase(NT_PPC_TAR); |
100 | ECase(NT_PPC_PPR); |
101 | ECase(NT_PPC_DSCR); |
102 | ECase(NT_PPC_EBB); |
103 | ECase(NT_PPC_PMU); |
104 | ECase(NT_PPC_TM_CGPR); |
105 | ECase(NT_PPC_TM_CFPR); |
106 | ECase(NT_PPC_TM_CVMX); |
107 | ECase(NT_PPC_TM_CVSX); |
108 | ECase(NT_PPC_TM_SPR); |
109 | ECase(NT_PPC_TM_CTAR); |
110 | ECase(NT_PPC_TM_CPPR); |
111 | ECase(NT_PPC_TM_CDSCR); |
112 | ECase(NT_386_TLS); |
113 | ECase(NT_386_IOPERM); |
114 | ECase(NT_X86_XSTATE); |
115 | ECase(NT_S390_HIGH_GPRS); |
116 | ECase(NT_S390_TIMER); |
117 | ECase(NT_S390_TODCMP); |
118 | ECase(NT_S390_TODPREG); |
119 | ECase(NT_S390_CTRS); |
120 | ECase(NT_S390_PREFIX); |
121 | ECase(NT_S390_LAST_BREAK); |
122 | ECase(NT_S390_SYSTEM_CALL); |
123 | ECase(NT_S390_TDB); |
124 | ECase(NT_S390_VXRS_LOW); |
125 | ECase(NT_S390_VXRS_HIGH); |
126 | ECase(NT_S390_GS_CB); |
127 | ECase(NT_S390_GS_BC); |
128 | ECase(NT_ARM_VFP); |
129 | ECase(NT_ARM_TLS); |
130 | ECase(NT_ARM_HW_BREAK); |
131 | ECase(NT_ARM_HW_WATCH); |
132 | ECase(NT_ARM_SVE); |
133 | ECase(NT_ARM_PAC_MASK); |
134 | ECase(NT_ARM_TAGGED_ADDR_CTRL); |
135 | ECase(NT_ARM_SSVE); |
136 | ECase(NT_ARM_ZA); |
137 | ECase(NT_ARM_ZT); |
138 | ECase(NT_FILE); |
139 | ECase(NT_PRXFPREG); |
140 | ECase(NT_SIGINFO); |
141 | // LLVM-specific notes. |
142 | ECase(NT_LLVM_HWASAN_GLOBALS); |
143 | // GNU note types |
144 | ECase(NT_GNU_ABI_TAG); |
145 | ECase(NT_GNU_HWCAP); |
146 | ECase(NT_GNU_BUILD_ID); |
147 | ECase(NT_GNU_GOLD_VERSION); |
148 | ECase(NT_GNU_PROPERTY_TYPE_0); |
149 | // FreeBSD note types. |
150 | ECase(NT_FREEBSD_ABI_TAG); |
151 | ECase(NT_FREEBSD_NOINIT_TAG); |
152 | ECase(NT_FREEBSD_ARCH_TAG); |
153 | ECase(NT_FREEBSD_FEATURE_CTL); |
154 | // FreeBSD core note types. |
155 | ECase(NT_FREEBSD_THRMISC); |
156 | ECase(NT_FREEBSD_PROCSTAT_PROC); |
157 | ECase(NT_FREEBSD_PROCSTAT_FILES); |
158 | ECase(NT_FREEBSD_PROCSTAT_VMMAP); |
159 | ECase(NT_FREEBSD_PROCSTAT_GROUPS); |
160 | ECase(NT_FREEBSD_PROCSTAT_UMASK); |
161 | ECase(NT_FREEBSD_PROCSTAT_RLIMIT); |
162 | ECase(NT_FREEBSD_PROCSTAT_OSREL); |
163 | ECase(NT_FREEBSD_PROCSTAT_PSSTRINGS); |
164 | ECase(NT_FREEBSD_PROCSTAT_AUXV); |
165 | // NetBSD core note types. |
166 | ECase(NT_NETBSDCORE_PROCINFO); |
167 | ECase(NT_NETBSDCORE_AUXV); |
168 | ECase(NT_NETBSDCORE_LWPSTATUS); |
169 | // OpenBSD core note types. |
170 | ECase(NT_OPENBSD_PROCINFO); |
171 | ECase(NT_OPENBSD_AUXV); |
172 | ECase(NT_OPENBSD_REGS); |
173 | ECase(NT_OPENBSD_FPREGS); |
174 | ECase(NT_OPENBSD_XFPREGS); |
175 | ECase(NT_OPENBSD_WCOOKIE); |
176 | // AMD specific notes. (Code Object V2) |
177 | ECase(NT_AMD_HSA_CODE_OBJECT_VERSION); |
178 | ECase(NT_AMD_HSA_HSAIL); |
179 | ECase(NT_AMD_HSA_ISA_VERSION); |
180 | ECase(NT_AMD_HSA_METADATA); |
181 | ECase(NT_AMD_HSA_ISA_NAME); |
182 | ECase(NT_AMD_PAL_METADATA); |
183 | // AMDGPU specific notes. (Code Object V3) |
184 | ECase(NT_AMDGPU_METADATA); |
185 | // Android specific notes. |
186 | ECase(NT_ANDROID_TYPE_IDENT); |
187 | ECase(NT_ANDROID_TYPE_KUSER); |
188 | ECase(NT_ANDROID_TYPE_MEMTAG); |
189 | #undef ECase |
190 | IO.enumFallback<Hex32>(Val&: Value); |
191 | } |
192 | |
193 | void ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration( |
194 | IO &IO, ELFYAML::ELF_EM &Value) { |
195 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
196 | ECase(EM_NONE); |
197 | ECase(EM_M32); |
198 | ECase(EM_SPARC); |
199 | ECase(EM_386); |
200 | ECase(EM_68K); |
201 | ECase(EM_88K); |
202 | ECase(EM_IAMCU); |
203 | ECase(EM_860); |
204 | ECase(EM_MIPS); |
205 | ECase(EM_S370); |
206 | ECase(EM_MIPS_RS3_LE); |
207 | ECase(EM_PARISC); |
208 | ECase(EM_VPP500); |
209 | ECase(EM_SPARC32PLUS); |
210 | ECase(EM_960); |
211 | ECase(EM_PPC); |
212 | ECase(EM_PPC64); |
213 | ECase(EM_S390); |
214 | ECase(EM_SPU); |
215 | ECase(EM_V800); |
216 | ECase(EM_FR20); |
217 | ECase(EM_RH32); |
218 | ECase(EM_RCE); |
219 | ECase(EM_ARM); |
220 | ECase(EM_ALPHA); |
221 | ECase(EM_SH); |
222 | ECase(EM_SPARCV9); |
223 | ECase(EM_TRICORE); |
224 | ECase(EM_ARC); |
225 | ECase(EM_H8_300); |
226 | ECase(EM_H8_300H); |
227 | ECase(EM_H8S); |
228 | ECase(EM_H8_500); |
229 | ECase(EM_IA_64); |
230 | ECase(EM_MIPS_X); |
231 | ECase(EM_COLDFIRE); |
232 | ECase(EM_68HC12); |
233 | ECase(EM_MMA); |
234 | ECase(EM_PCP); |
235 | ECase(EM_NCPU); |
236 | ECase(EM_NDR1); |
237 | ECase(EM_STARCORE); |
238 | ECase(EM_ME16); |
239 | ECase(EM_ST100); |
240 | ECase(EM_TINYJ); |
241 | ECase(EM_X86_64); |
242 | ECase(EM_PDSP); |
243 | ECase(EM_PDP10); |
244 | ECase(EM_PDP11); |
245 | ECase(EM_FX66); |
246 | ECase(EM_ST9PLUS); |
247 | ECase(EM_ST7); |
248 | ECase(EM_68HC16); |
249 | ECase(EM_68HC11); |
250 | ECase(EM_68HC08); |
251 | ECase(EM_68HC05); |
252 | ECase(EM_SVX); |
253 | ECase(EM_ST19); |
254 | ECase(EM_VAX); |
255 | ECase(EM_CRIS); |
256 | ECase(EM_JAVELIN); |
257 | ECase(EM_FIREPATH); |
258 | ECase(EM_ZSP); |
259 | ECase(EM_MMIX); |
260 | ECase(EM_HUANY); |
261 | ECase(EM_PRISM); |
262 | ECase(EM_AVR); |
263 | ECase(EM_FR30); |
264 | ECase(EM_D10V); |
265 | ECase(EM_D30V); |
266 | ECase(EM_V850); |
267 | ECase(EM_M32R); |
268 | ECase(EM_MN10300); |
269 | ECase(EM_MN10200); |
270 | ECase(EM_PJ); |
271 | ECase(EM_OPENRISC); |
272 | ECase(EM_ARC_COMPACT); |
273 | ECase(EM_XTENSA); |
274 | ECase(EM_VIDEOCORE); |
275 | ECase(EM_TMM_GPP); |
276 | ECase(EM_NS32K); |
277 | ECase(EM_TPC); |
278 | ECase(EM_SNP1K); |
279 | ECase(EM_ST200); |
280 | ECase(EM_IP2K); |
281 | ECase(EM_MAX); |
282 | ECase(EM_CR); |
283 | ECase(EM_F2MC16); |
284 | ECase(EM_MSP430); |
285 | ECase(EM_BLACKFIN); |
286 | ECase(EM_SE_C33); |
287 | ECase(EM_SEP); |
288 | ECase(EM_ARCA); |
289 | ECase(EM_UNICORE); |
290 | ECase(EM_EXCESS); |
291 | ECase(EM_DXP); |
292 | ECase(EM_ALTERA_NIOS2); |
293 | ECase(EM_CRX); |
294 | ECase(EM_XGATE); |
295 | ECase(EM_C166); |
296 | ECase(EM_M16C); |
297 | ECase(EM_DSPIC30F); |
298 | ECase(EM_CE); |
299 | ECase(EM_M32C); |
300 | ECase(EM_TSK3000); |
301 | ECase(EM_RS08); |
302 | ECase(EM_SHARC); |
303 | ECase(EM_ECOG2); |
304 | ECase(EM_SCORE7); |
305 | ECase(EM_DSP24); |
306 | ECase(EM_VIDEOCORE3); |
307 | ECase(EM_LATTICEMICO32); |
308 | ECase(EM_SE_C17); |
309 | ECase(EM_TI_C6000); |
310 | ECase(EM_TI_C2000); |
311 | ECase(EM_TI_C5500); |
312 | ECase(EM_MMDSP_PLUS); |
313 | ECase(EM_CYPRESS_M8C); |
314 | ECase(EM_R32C); |
315 | ECase(EM_TRIMEDIA); |
316 | ECase(EM_HEXAGON); |
317 | ECase(EM_8051); |
318 | ECase(EM_STXP7X); |
319 | ECase(EM_NDS32); |
320 | ECase(EM_ECOG1); |
321 | ECase(EM_ECOG1X); |
322 | ECase(EM_MAXQ30); |
323 | ECase(EM_XIMO16); |
324 | ECase(EM_MANIK); |
325 | ECase(EM_CRAYNV2); |
326 | ECase(EM_RX); |
327 | ECase(EM_METAG); |
328 | ECase(EM_MCST_ELBRUS); |
329 | ECase(EM_ECOG16); |
330 | ECase(EM_CR16); |
331 | ECase(EM_ETPU); |
332 | ECase(EM_SLE9X); |
333 | ECase(EM_L10M); |
334 | ECase(EM_K10M); |
335 | ECase(EM_AARCH64); |
336 | ECase(EM_AVR32); |
337 | ECase(EM_STM8); |
338 | ECase(EM_TILE64); |
339 | ECase(EM_TILEPRO); |
340 | ECase(EM_MICROBLAZE); |
341 | ECase(EM_CUDA); |
342 | ECase(EM_TILEGX); |
343 | ECase(EM_CLOUDSHIELD); |
344 | ECase(EM_COREA_1ST); |
345 | ECase(EM_COREA_2ND); |
346 | ECase(EM_ARC_COMPACT2); |
347 | ECase(EM_OPEN8); |
348 | ECase(EM_RL78); |
349 | ECase(EM_VIDEOCORE5); |
350 | ECase(EM_78KOR); |
351 | ECase(EM_56800EX); |
352 | ECase(EM_AMDGPU); |
353 | ECase(EM_RISCV); |
354 | ECase(EM_LANAI); |
355 | ECase(EM_BPF); |
356 | ECase(EM_VE); |
357 | ECase(EM_CSKY); |
358 | ECase(EM_LOONGARCH); |
359 | #undef ECase |
360 | IO.enumFallback<Hex16>(Val&: Value); |
361 | } |
362 | |
363 | void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration( |
364 | IO &IO, ELFYAML::ELF_ELFCLASS &Value) { |
365 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
366 | // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it |
367 | // here. |
368 | ECase(ELFCLASS32); |
369 | ECase(ELFCLASS64); |
370 | #undef ECase |
371 | } |
372 | |
373 | void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration( |
374 | IO &IO, ELFYAML::ELF_ELFDATA &Value) { |
375 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
376 | // ELFDATANONE is an invalid data encoding, but we accept it because |
377 | // we want to be able to produce invalid binaries for the tests. |
378 | ECase(ELFDATANONE); |
379 | ECase(ELFDATA2LSB); |
380 | ECase(ELFDATA2MSB); |
381 | #undef ECase |
382 | } |
383 | |
384 | void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration( |
385 | IO &IO, ELFYAML::ELF_ELFOSABI &Value) { |
386 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
387 | ECase(ELFOSABI_NONE); |
388 | ECase(ELFOSABI_HPUX); |
389 | ECase(ELFOSABI_NETBSD); |
390 | ECase(ELFOSABI_GNU); |
391 | ECase(ELFOSABI_LINUX); |
392 | ECase(ELFOSABI_HURD); |
393 | ECase(ELFOSABI_SOLARIS); |
394 | ECase(ELFOSABI_AIX); |
395 | ECase(ELFOSABI_IRIX); |
396 | ECase(ELFOSABI_FREEBSD); |
397 | ECase(ELFOSABI_TRU64); |
398 | ECase(ELFOSABI_MODESTO); |
399 | ECase(ELFOSABI_OPENBSD); |
400 | ECase(ELFOSABI_OPENVMS); |
401 | ECase(ELFOSABI_NSK); |
402 | ECase(ELFOSABI_AROS); |
403 | ECase(ELFOSABI_FENIXOS); |
404 | ECase(ELFOSABI_CLOUDABI); |
405 | ECase(ELFOSABI_AMDGPU_HSA); |
406 | ECase(ELFOSABI_AMDGPU_PAL); |
407 | ECase(ELFOSABI_AMDGPU_MESA3D); |
408 | ECase(ELFOSABI_ARM); |
409 | ECase(ELFOSABI_ARM_FDPIC); |
410 | ECase(ELFOSABI_C6000_ELFABI); |
411 | ECase(ELFOSABI_C6000_LINUX); |
412 | ECase(ELFOSABI_STANDALONE); |
413 | #undef ECase |
414 | IO.enumFallback<Hex8>(Val&: Value); |
415 | } |
416 | |
417 | void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO, |
418 | ELFYAML::ELF_EF &Value) { |
419 | const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); |
420 | assert(Object && "The IO context is not initialized" ); |
421 | #define BCase(X) IO.bitSetCase(Value, #X, ELF::X) |
422 | #define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M) |
423 | switch (Object->getMachine()) { |
424 | case ELF::EM_ARM: |
425 | BCase(EF_ARM_SOFT_FLOAT); |
426 | BCase(EF_ARM_VFP_FLOAT); |
427 | BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK); |
428 | BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK); |
429 | BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK); |
430 | BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK); |
431 | BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK); |
432 | BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK); |
433 | BCaseMask(EF_ARM_BE8, EF_ARM_BE8); |
434 | break; |
435 | case ELF::EM_MIPS: |
436 | BCase(EF_MIPS_NOREORDER); |
437 | BCase(EF_MIPS_PIC); |
438 | BCase(EF_MIPS_CPIC); |
439 | BCase(EF_MIPS_ABI2); |
440 | BCase(EF_MIPS_32BITMODE); |
441 | BCase(EF_MIPS_FP64); |
442 | BCase(EF_MIPS_NAN2008); |
443 | BCase(EF_MIPS_MICROMIPS); |
444 | BCase(EF_MIPS_ARCH_ASE_M16); |
445 | BCase(EF_MIPS_ARCH_ASE_MDMX); |
446 | BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI); |
447 | BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI); |
448 | BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI); |
449 | BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI); |
450 | BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH); |
451 | BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH); |
452 | BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH); |
453 | BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH); |
454 | BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH); |
455 | BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH); |
456 | BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH); |
457 | BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH); |
458 | BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH); |
459 | BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH); |
460 | BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH); |
461 | BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH); |
462 | BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH); |
463 | BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH); |
464 | BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH); |
465 | BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH); |
466 | BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH); |
467 | BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH); |
468 | BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH); |
469 | BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH); |
470 | BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH); |
471 | BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH); |
472 | BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH); |
473 | BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH); |
474 | BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH); |
475 | BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH); |
476 | BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH); |
477 | BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH); |
478 | BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH); |
479 | break; |
480 | case ELF::EM_HEXAGON: |
481 | BCaseMask(EF_HEXAGON_MACH_V2, EF_HEXAGON_MACH); |
482 | BCaseMask(EF_HEXAGON_MACH_V3, EF_HEXAGON_MACH); |
483 | BCaseMask(EF_HEXAGON_MACH_V4, EF_HEXAGON_MACH); |
484 | BCaseMask(EF_HEXAGON_MACH_V5, EF_HEXAGON_MACH); |
485 | BCaseMask(EF_HEXAGON_MACH_V55, EF_HEXAGON_MACH); |
486 | BCaseMask(EF_HEXAGON_MACH_V60, EF_HEXAGON_MACH); |
487 | BCaseMask(EF_HEXAGON_MACH_V62, EF_HEXAGON_MACH); |
488 | BCaseMask(EF_HEXAGON_MACH_V65, EF_HEXAGON_MACH); |
489 | BCaseMask(EF_HEXAGON_MACH_V66, EF_HEXAGON_MACH); |
490 | BCaseMask(EF_HEXAGON_MACH_V67, EF_HEXAGON_MACH); |
491 | BCaseMask(EF_HEXAGON_MACH_V67T, EF_HEXAGON_MACH); |
492 | BCaseMask(EF_HEXAGON_MACH_V68, EF_HEXAGON_MACH); |
493 | BCaseMask(EF_HEXAGON_MACH_V69, EF_HEXAGON_MACH); |
494 | BCaseMask(EF_HEXAGON_MACH_V71, EF_HEXAGON_MACH); |
495 | BCaseMask(EF_HEXAGON_MACH_V71T, EF_HEXAGON_MACH); |
496 | BCaseMask(EF_HEXAGON_MACH_V73, EF_HEXAGON_MACH); |
497 | BCaseMask(EF_HEXAGON_ISA_V2, EF_HEXAGON_ISA); |
498 | BCaseMask(EF_HEXAGON_ISA_V3, EF_HEXAGON_ISA); |
499 | BCaseMask(EF_HEXAGON_ISA_V4, EF_HEXAGON_ISA); |
500 | BCaseMask(EF_HEXAGON_ISA_V5, EF_HEXAGON_ISA); |
501 | BCaseMask(EF_HEXAGON_ISA_V55, EF_HEXAGON_ISA); |
502 | BCaseMask(EF_HEXAGON_ISA_V60, EF_HEXAGON_ISA); |
503 | BCaseMask(EF_HEXAGON_ISA_V62, EF_HEXAGON_ISA); |
504 | BCaseMask(EF_HEXAGON_ISA_V65, EF_HEXAGON_ISA); |
505 | BCaseMask(EF_HEXAGON_ISA_V66, EF_HEXAGON_ISA); |
506 | BCaseMask(EF_HEXAGON_ISA_V67, EF_HEXAGON_ISA); |
507 | BCaseMask(EF_HEXAGON_ISA_V68, EF_HEXAGON_ISA); |
508 | BCaseMask(EF_HEXAGON_ISA_V69, EF_HEXAGON_ISA); |
509 | BCaseMask(EF_HEXAGON_ISA_V71, EF_HEXAGON_ISA); |
510 | BCaseMask(EF_HEXAGON_ISA_V73, EF_HEXAGON_ISA); |
511 | break; |
512 | case ELF::EM_AVR: |
513 | BCaseMask(EF_AVR_ARCH_AVR1, EF_AVR_ARCH_MASK); |
514 | BCaseMask(EF_AVR_ARCH_AVR2, EF_AVR_ARCH_MASK); |
515 | BCaseMask(EF_AVR_ARCH_AVR25, EF_AVR_ARCH_MASK); |
516 | BCaseMask(EF_AVR_ARCH_AVR3, EF_AVR_ARCH_MASK); |
517 | BCaseMask(EF_AVR_ARCH_AVR31, EF_AVR_ARCH_MASK); |
518 | BCaseMask(EF_AVR_ARCH_AVR35, EF_AVR_ARCH_MASK); |
519 | BCaseMask(EF_AVR_ARCH_AVR4, EF_AVR_ARCH_MASK); |
520 | BCaseMask(EF_AVR_ARCH_AVR5, EF_AVR_ARCH_MASK); |
521 | BCaseMask(EF_AVR_ARCH_AVR51, EF_AVR_ARCH_MASK); |
522 | BCaseMask(EF_AVR_ARCH_AVR6, EF_AVR_ARCH_MASK); |
523 | BCaseMask(EF_AVR_ARCH_AVRTINY, EF_AVR_ARCH_MASK); |
524 | BCaseMask(EF_AVR_ARCH_XMEGA1, EF_AVR_ARCH_MASK); |
525 | BCaseMask(EF_AVR_ARCH_XMEGA2, EF_AVR_ARCH_MASK); |
526 | BCaseMask(EF_AVR_ARCH_XMEGA3, EF_AVR_ARCH_MASK); |
527 | BCaseMask(EF_AVR_ARCH_XMEGA4, EF_AVR_ARCH_MASK); |
528 | BCaseMask(EF_AVR_ARCH_XMEGA5, EF_AVR_ARCH_MASK); |
529 | BCaseMask(EF_AVR_ARCH_XMEGA6, EF_AVR_ARCH_MASK); |
530 | BCaseMask(EF_AVR_ARCH_XMEGA7, EF_AVR_ARCH_MASK); |
531 | BCase(EF_AVR_LINKRELAX_PREPARED); |
532 | break; |
533 | case ELF::EM_LOONGARCH: |
534 | BCaseMask(EF_LOONGARCH_ABI_SOFT_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK); |
535 | BCaseMask(EF_LOONGARCH_ABI_SINGLE_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK); |
536 | BCaseMask(EF_LOONGARCH_ABI_DOUBLE_FLOAT, EF_LOONGARCH_ABI_MODIFIER_MASK); |
537 | BCaseMask(EF_LOONGARCH_OBJABI_V0, EF_LOONGARCH_OBJABI_MASK); |
538 | BCaseMask(EF_LOONGARCH_OBJABI_V1, EF_LOONGARCH_OBJABI_MASK); |
539 | break; |
540 | case ELF::EM_RISCV: |
541 | BCase(EF_RISCV_RVC); |
542 | BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI); |
543 | BCaseMask(EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI); |
544 | BCaseMask(EF_RISCV_FLOAT_ABI_DOUBLE, EF_RISCV_FLOAT_ABI); |
545 | BCaseMask(EF_RISCV_FLOAT_ABI_QUAD, EF_RISCV_FLOAT_ABI); |
546 | BCase(EF_RISCV_RVE); |
547 | BCase(EF_RISCV_TSO); |
548 | break; |
549 | case ELF::EM_XTENSA: |
550 | BCase(EF_XTENSA_XT_INSN); |
551 | BCaseMask(EF_XTENSA_MACH_NONE, EF_XTENSA_MACH); |
552 | BCase(EF_XTENSA_XT_LIT); |
553 | break; |
554 | case ELF::EM_AMDGPU: |
555 | BCaseMask(EF_AMDGPU_MACH_NONE, EF_AMDGPU_MACH); |
556 | BCaseMask(EF_AMDGPU_MACH_R600_R600, EF_AMDGPU_MACH); |
557 | BCaseMask(EF_AMDGPU_MACH_R600_R630, EF_AMDGPU_MACH); |
558 | BCaseMask(EF_AMDGPU_MACH_R600_RS880, EF_AMDGPU_MACH); |
559 | BCaseMask(EF_AMDGPU_MACH_R600_RV670, EF_AMDGPU_MACH); |
560 | BCaseMask(EF_AMDGPU_MACH_R600_RV710, EF_AMDGPU_MACH); |
561 | BCaseMask(EF_AMDGPU_MACH_R600_RV730, EF_AMDGPU_MACH); |
562 | BCaseMask(EF_AMDGPU_MACH_R600_RV770, EF_AMDGPU_MACH); |
563 | BCaseMask(EF_AMDGPU_MACH_R600_CEDAR, EF_AMDGPU_MACH); |
564 | BCaseMask(EF_AMDGPU_MACH_R600_CYPRESS, EF_AMDGPU_MACH); |
565 | BCaseMask(EF_AMDGPU_MACH_R600_JUNIPER, EF_AMDGPU_MACH); |
566 | BCaseMask(EF_AMDGPU_MACH_R600_REDWOOD, EF_AMDGPU_MACH); |
567 | BCaseMask(EF_AMDGPU_MACH_R600_SUMO, EF_AMDGPU_MACH); |
568 | BCaseMask(EF_AMDGPU_MACH_R600_BARTS, EF_AMDGPU_MACH); |
569 | BCaseMask(EF_AMDGPU_MACH_R600_CAICOS, EF_AMDGPU_MACH); |
570 | BCaseMask(EF_AMDGPU_MACH_R600_CAYMAN, EF_AMDGPU_MACH); |
571 | BCaseMask(EF_AMDGPU_MACH_R600_TURKS, EF_AMDGPU_MACH); |
572 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX600, EF_AMDGPU_MACH); |
573 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX601, EF_AMDGPU_MACH); |
574 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX602, EF_AMDGPU_MACH); |
575 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX700, EF_AMDGPU_MACH); |
576 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX701, EF_AMDGPU_MACH); |
577 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX702, EF_AMDGPU_MACH); |
578 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX703, EF_AMDGPU_MACH); |
579 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX704, EF_AMDGPU_MACH); |
580 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX705, EF_AMDGPU_MACH); |
581 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX801, EF_AMDGPU_MACH); |
582 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX802, EF_AMDGPU_MACH); |
583 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX803, EF_AMDGPU_MACH); |
584 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX805, EF_AMDGPU_MACH); |
585 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX810, EF_AMDGPU_MACH); |
586 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX900, EF_AMDGPU_MACH); |
587 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX902, EF_AMDGPU_MACH); |
588 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX904, EF_AMDGPU_MACH); |
589 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX906, EF_AMDGPU_MACH); |
590 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX908, EF_AMDGPU_MACH); |
591 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX909, EF_AMDGPU_MACH); |
592 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX90A, EF_AMDGPU_MACH); |
593 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX90C, EF_AMDGPU_MACH); |
594 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX940, EF_AMDGPU_MACH); |
595 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX941, EF_AMDGPU_MACH); |
596 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX942, EF_AMDGPU_MACH); |
597 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1010, EF_AMDGPU_MACH); |
598 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1011, EF_AMDGPU_MACH); |
599 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1012, EF_AMDGPU_MACH); |
600 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1013, EF_AMDGPU_MACH); |
601 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1030, EF_AMDGPU_MACH); |
602 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1031, EF_AMDGPU_MACH); |
603 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1032, EF_AMDGPU_MACH); |
604 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1033, EF_AMDGPU_MACH); |
605 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1034, EF_AMDGPU_MACH); |
606 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1035, EF_AMDGPU_MACH); |
607 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1036, EF_AMDGPU_MACH); |
608 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1100, EF_AMDGPU_MACH); |
609 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1101, EF_AMDGPU_MACH); |
610 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1102, EF_AMDGPU_MACH); |
611 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1103, EF_AMDGPU_MACH); |
612 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1150, EF_AMDGPU_MACH); |
613 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1151, EF_AMDGPU_MACH); |
614 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1152, EF_AMDGPU_MACH); |
615 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1200, EF_AMDGPU_MACH); |
616 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX1201, EF_AMDGPU_MACH); |
617 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC, EF_AMDGPU_MACH); |
618 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC, EF_AMDGPU_MACH); |
619 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC, EF_AMDGPU_MACH); |
620 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC, EF_AMDGPU_MACH); |
621 | BCaseMask(EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC, EF_AMDGPU_MACH); |
622 | switch (Object->Header.ABIVersion) { |
623 | default: |
624 | // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags. |
625 | [[fallthrough]]; |
626 | case ELF::ELFABIVERSION_AMDGPU_HSA_V3: |
627 | BCase(EF_AMDGPU_FEATURE_XNACK_V3); |
628 | BCase(EF_AMDGPU_FEATURE_SRAMECC_V3); |
629 | break; |
630 | case ELF::ELFABIVERSION_AMDGPU_HSA_V6: |
631 | for (unsigned K = ELF::EF_AMDGPU_GENERIC_VERSION_MIN; |
632 | K <= ELF::EF_AMDGPU_GENERIC_VERSION_MAX; ++K) { |
633 | std::string Key = "EF_AMDGPU_GENERIC_VERSION_V" + std::to_string(val: K); |
634 | IO.maskedBitSetCase(Val&: Value, Str: Key.c_str(), |
635 | ConstVal: K << ELF::EF_AMDGPU_GENERIC_VERSION_OFFSET, |
636 | Mask: ELF::EF_AMDGPU_GENERIC_VERSION); |
637 | } |
638 | [[fallthrough]]; |
639 | case ELF::ELFABIVERSION_AMDGPU_HSA_V4: |
640 | case ELF::ELFABIVERSION_AMDGPU_HSA_V5: |
641 | BCaseMask(EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4, |
642 | EF_AMDGPU_FEATURE_XNACK_V4); |
643 | BCaseMask(EF_AMDGPU_FEATURE_XNACK_ANY_V4, |
644 | EF_AMDGPU_FEATURE_XNACK_V4); |
645 | BCaseMask(EF_AMDGPU_FEATURE_XNACK_OFF_V4, |
646 | EF_AMDGPU_FEATURE_XNACK_V4); |
647 | BCaseMask(EF_AMDGPU_FEATURE_XNACK_ON_V4, |
648 | EF_AMDGPU_FEATURE_XNACK_V4); |
649 | BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4, |
650 | EF_AMDGPU_FEATURE_SRAMECC_V4); |
651 | BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_ANY_V4, |
652 | EF_AMDGPU_FEATURE_SRAMECC_V4); |
653 | BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_OFF_V4, |
654 | EF_AMDGPU_FEATURE_SRAMECC_V4); |
655 | BCaseMask(EF_AMDGPU_FEATURE_SRAMECC_ON_V4, |
656 | EF_AMDGPU_FEATURE_SRAMECC_V4); |
657 | break; |
658 | } |
659 | break; |
660 | default: |
661 | break; |
662 | } |
663 | #undef BCase |
664 | #undef BCaseMask |
665 | } |
666 | |
667 | void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration( |
668 | IO &IO, ELFYAML::ELF_SHT &Value) { |
669 | const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); |
670 | assert(Object && "The IO context is not initialized" ); |
671 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
672 | ECase(SHT_NULL); |
673 | ECase(SHT_PROGBITS); |
674 | ECase(SHT_SYMTAB); |
675 | // FIXME: Issue a diagnostic with this information. |
676 | ECase(SHT_STRTAB); |
677 | ECase(SHT_RELA); |
678 | ECase(SHT_HASH); |
679 | ECase(SHT_DYNAMIC); |
680 | ECase(SHT_NOTE); |
681 | ECase(SHT_NOBITS); |
682 | ECase(SHT_REL); |
683 | ECase(SHT_SHLIB); |
684 | ECase(SHT_DYNSYM); |
685 | ECase(SHT_INIT_ARRAY); |
686 | ECase(SHT_FINI_ARRAY); |
687 | ECase(SHT_PREINIT_ARRAY); |
688 | ECase(SHT_GROUP); |
689 | ECase(SHT_SYMTAB_SHNDX); |
690 | ECase(SHT_RELR); |
691 | ECase(SHT_CREL); |
692 | ECase(SHT_ANDROID_REL); |
693 | ECase(SHT_ANDROID_RELA); |
694 | ECase(SHT_ANDROID_RELR); |
695 | ECase(SHT_LLVM_ODRTAB); |
696 | ECase(SHT_LLVM_LINKER_OPTIONS); |
697 | ECase(SHT_LLVM_CALL_GRAPH_PROFILE); |
698 | ECase(SHT_LLVM_ADDRSIG); |
699 | ECase(SHT_LLVM_DEPENDENT_LIBRARIES); |
700 | ECase(SHT_LLVM_SYMPART); |
701 | ECase(SHT_LLVM_PART_EHDR); |
702 | ECase(SHT_LLVM_PART_PHDR); |
703 | ECase(SHT_LLVM_BB_ADDR_MAP_V0); |
704 | ECase(SHT_LLVM_BB_ADDR_MAP); |
705 | ECase(SHT_LLVM_OFFLOADING); |
706 | ECase(SHT_LLVM_LTO); |
707 | ECase(SHT_GNU_ATTRIBUTES); |
708 | ECase(SHT_GNU_HASH); |
709 | ECase(SHT_GNU_verdef); |
710 | ECase(SHT_GNU_verneed); |
711 | ECase(SHT_GNU_versym); |
712 | switch (Object->getMachine()) { |
713 | case ELF::EM_ARM: |
714 | ECase(SHT_ARM_EXIDX); |
715 | ECase(SHT_ARM_PREEMPTMAP); |
716 | ECase(SHT_ARM_ATTRIBUTES); |
717 | ECase(SHT_ARM_DEBUGOVERLAY); |
718 | ECase(SHT_ARM_OVERLAYSECTION); |
719 | break; |
720 | case ELF::EM_HEXAGON: |
721 | ECase(SHT_HEX_ORDERED); |
722 | ECase(SHT_HEXAGON_ATTRIBUTES); |
723 | break; |
724 | case ELF::EM_X86_64: |
725 | ECase(SHT_X86_64_UNWIND); |
726 | break; |
727 | case ELF::EM_MIPS: |
728 | ECase(SHT_MIPS_REGINFO); |
729 | ECase(SHT_MIPS_OPTIONS); |
730 | ECase(SHT_MIPS_DWARF); |
731 | ECase(SHT_MIPS_ABIFLAGS); |
732 | break; |
733 | case ELF::EM_RISCV: |
734 | ECase(SHT_RISCV_ATTRIBUTES); |
735 | break; |
736 | case ELF::EM_MSP430: |
737 | ECase(SHT_MSP430_ATTRIBUTES); |
738 | break; |
739 | case ELF::EM_AARCH64: |
740 | ECase(SHT_AARCH64_AUTH_RELR); |
741 | ECase(SHT_AARCH64_MEMTAG_GLOBALS_STATIC); |
742 | ECase(SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC); |
743 | break; |
744 | default: |
745 | // Nothing to do. |
746 | break; |
747 | } |
748 | #undef ECase |
749 | IO.enumFallback<Hex32>(Val&: Value); |
750 | } |
751 | |
752 | void ScalarBitSetTraits<ELFYAML::ELF_PF>::bitset(IO &IO, |
753 | ELFYAML::ELF_PF &Value) { |
754 | #define BCase(X) IO.bitSetCase(Value, #X, ELF::X) |
755 | BCase(PF_X); |
756 | BCase(PF_W); |
757 | BCase(PF_R); |
758 | } |
759 | |
760 | void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO, |
761 | ELFYAML::ELF_SHF &Value) { |
762 | const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); |
763 | #define BCase(X) IO.bitSetCase(Value, #X, ELF::X) |
764 | BCase(SHF_WRITE); |
765 | BCase(SHF_ALLOC); |
766 | BCase(SHF_EXCLUDE); |
767 | BCase(SHF_EXECINSTR); |
768 | BCase(SHF_MERGE); |
769 | BCase(SHF_STRINGS); |
770 | BCase(SHF_INFO_LINK); |
771 | BCase(SHF_LINK_ORDER); |
772 | BCase(SHF_OS_NONCONFORMING); |
773 | BCase(SHF_GROUP); |
774 | BCase(SHF_TLS); |
775 | BCase(SHF_COMPRESSED); |
776 | switch (Object->getOSAbi()) { |
777 | case ELF::ELFOSABI_SOLARIS: |
778 | BCase(SHF_SUNW_NODISCARD); |
779 | break; |
780 | default: |
781 | BCase(SHF_GNU_RETAIN); |
782 | break; |
783 | } |
784 | switch (Object->getMachine()) { |
785 | case ELF::EM_ARM: |
786 | BCase(SHF_ARM_PURECODE); |
787 | break; |
788 | case ELF::EM_HEXAGON: |
789 | BCase(SHF_HEX_GPREL); |
790 | break; |
791 | case ELF::EM_MIPS: |
792 | BCase(SHF_MIPS_NODUPES); |
793 | BCase(SHF_MIPS_NAMES); |
794 | BCase(SHF_MIPS_LOCAL); |
795 | BCase(SHF_MIPS_NOSTRIP); |
796 | BCase(SHF_MIPS_GPREL); |
797 | BCase(SHF_MIPS_MERGE); |
798 | BCase(SHF_MIPS_ADDR); |
799 | BCase(SHF_MIPS_STRING); |
800 | break; |
801 | case ELF::EM_X86_64: |
802 | BCase(SHF_X86_64_LARGE); |
803 | break; |
804 | default: |
805 | // Nothing to do. |
806 | break; |
807 | } |
808 | #undef BCase |
809 | } |
810 | |
811 | void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration( |
812 | IO &IO, ELFYAML::ELF_SHN &Value) { |
813 | const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); |
814 | assert(Object && "The IO context is not initialized" ); |
815 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
816 | ECase(SHN_UNDEF); |
817 | ECase(SHN_LORESERVE); |
818 | ECase(SHN_LOPROC); |
819 | ECase(SHN_HIPROC); |
820 | ECase(SHN_LOOS); |
821 | ECase(SHN_HIOS); |
822 | ECase(SHN_ABS); |
823 | ECase(SHN_COMMON); |
824 | ECase(SHN_XINDEX); |
825 | ECase(SHN_HIRESERVE); |
826 | ECase(SHN_AMDGPU_LDS); |
827 | |
828 | if (!IO.outputting() || Object->getMachine() == ELF::EM_MIPS) { |
829 | ECase(SHN_MIPS_ACOMMON); |
830 | ECase(SHN_MIPS_TEXT); |
831 | ECase(SHN_MIPS_DATA); |
832 | ECase(SHN_MIPS_SCOMMON); |
833 | ECase(SHN_MIPS_SUNDEFINED); |
834 | } |
835 | |
836 | ECase(SHN_HEXAGON_SCOMMON); |
837 | ECase(SHN_HEXAGON_SCOMMON_1); |
838 | ECase(SHN_HEXAGON_SCOMMON_2); |
839 | ECase(SHN_HEXAGON_SCOMMON_4); |
840 | ECase(SHN_HEXAGON_SCOMMON_8); |
841 | #undef ECase |
842 | IO.enumFallback<Hex16>(Val&: Value); |
843 | } |
844 | |
845 | void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration( |
846 | IO &IO, ELFYAML::ELF_STB &Value) { |
847 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
848 | ECase(STB_LOCAL); |
849 | ECase(STB_GLOBAL); |
850 | ECase(STB_WEAK); |
851 | ECase(STB_GNU_UNIQUE); |
852 | #undef ECase |
853 | IO.enumFallback<Hex8>(Val&: Value); |
854 | } |
855 | |
856 | void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration( |
857 | IO &IO, ELFYAML::ELF_STT &Value) { |
858 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
859 | ECase(STT_NOTYPE); |
860 | ECase(STT_OBJECT); |
861 | ECase(STT_FUNC); |
862 | ECase(STT_SECTION); |
863 | ECase(STT_FILE); |
864 | ECase(STT_COMMON); |
865 | ECase(STT_TLS); |
866 | ECase(STT_GNU_IFUNC); |
867 | #undef ECase |
868 | IO.enumFallback<Hex8>(Val&: Value); |
869 | } |
870 | |
871 | |
872 | void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::( |
873 | IO &IO, ELFYAML::ELF_RSS &Value) { |
874 | #define ECase(X) IO.enumCase(Value, #X, ELF::X) |
875 | ECase(RSS_UNDEF); |
876 | ECase(RSS_GP); |
877 | ECase(RSS_GP0); |
878 | ECase(RSS_LOC); |
879 | #undef ECase |
880 | } |
881 | |
882 | void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration( |
883 | IO &IO, ELFYAML::ELF_REL &Value) { |
884 | const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); |
885 | assert(Object && "The IO context is not initialized" ); |
886 | #define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X); |
887 | switch (Object->getMachine()) { |
888 | case ELF::EM_X86_64: |
889 | #include "llvm/BinaryFormat/ELFRelocs/x86_64.def" |
890 | break; |
891 | case ELF::EM_MIPS: |
892 | #include "llvm/BinaryFormat/ELFRelocs/Mips.def" |
893 | break; |
894 | case ELF::EM_HEXAGON: |
895 | #include "llvm/BinaryFormat/ELFRelocs/Hexagon.def" |
896 | break; |
897 | case ELF::EM_386: |
898 | case ELF::EM_IAMCU: |
899 | #include "llvm/BinaryFormat/ELFRelocs/i386.def" |
900 | break; |
901 | case ELF::EM_AARCH64: |
902 | #include "llvm/BinaryFormat/ELFRelocs/AArch64.def" |
903 | break; |
904 | case ELF::EM_ARM: |
905 | #include "llvm/BinaryFormat/ELFRelocs/ARM.def" |
906 | break; |
907 | case ELF::EM_ARC: |
908 | #include "llvm/BinaryFormat/ELFRelocs/ARC.def" |
909 | break; |
910 | case ELF::EM_RISCV: |
911 | #include "llvm/BinaryFormat/ELFRelocs/RISCV.def" |
912 | break; |
913 | case ELF::EM_LANAI: |
914 | #include "llvm/BinaryFormat/ELFRelocs/Lanai.def" |
915 | break; |
916 | case ELF::EM_AMDGPU: |
917 | #include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" |
918 | break; |
919 | case ELF::EM_BPF: |
920 | #include "llvm/BinaryFormat/ELFRelocs/BPF.def" |
921 | break; |
922 | case ELF::EM_VE: |
923 | #include "llvm/BinaryFormat/ELFRelocs/VE.def" |
924 | break; |
925 | case ELF::EM_CSKY: |
926 | #include "llvm/BinaryFormat/ELFRelocs/CSKY.def" |
927 | break; |
928 | case ELF::EM_PPC: |
929 | #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def" |
930 | break; |
931 | case ELF::EM_PPC64: |
932 | #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def" |
933 | break; |
934 | case ELF::EM_68K: |
935 | #include "llvm/BinaryFormat/ELFRelocs/M68k.def" |
936 | break; |
937 | case ELF::EM_LOONGARCH: |
938 | #include "llvm/BinaryFormat/ELFRelocs/LoongArch.def" |
939 | break; |
940 | case ELF::EM_XTENSA: |
941 | #include "llvm/BinaryFormat/ELFRelocs/Xtensa.def" |
942 | break; |
943 | default: |
944 | // Nothing to do. |
945 | break; |
946 | } |
947 | #undef ELF_RELOC |
948 | IO.enumFallback<Hex32>(Val&: Value); |
949 | } |
950 | |
951 | void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration( |
952 | IO &IO, ELFYAML::ELF_DYNTAG &Value) { |
953 | const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); |
954 | assert(Object && "The IO context is not initialized" ); |
955 | |
956 | // Disable architecture specific tags by default. We might enable them below. |
957 | #define AARCH64_DYNAMIC_TAG(name, value) |
958 | #define MIPS_DYNAMIC_TAG(name, value) |
959 | #define HEXAGON_DYNAMIC_TAG(name, value) |
960 | #define PPC_DYNAMIC_TAG(name, value) |
961 | #define PPC64_DYNAMIC_TAG(name, value) |
962 | // Ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc. |
963 | #define DYNAMIC_TAG_MARKER(name, value) |
964 | |
965 | #define STRINGIFY(X) (#X) |
966 | #define DYNAMIC_TAG(X, Y) IO.enumCase(Value, STRINGIFY(DT_##X), ELF::DT_##X); |
967 | switch (Object->getMachine()) { |
968 | case ELF::EM_AARCH64: |
969 | #undef AARCH64_DYNAMIC_TAG |
970 | #define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) |
971 | #include "llvm/BinaryFormat/DynamicTags.def" |
972 | #undef AARCH64_DYNAMIC_TAG |
973 | #define AARCH64_DYNAMIC_TAG(name, value) |
974 | break; |
975 | case ELF::EM_MIPS: |
976 | #undef MIPS_DYNAMIC_TAG |
977 | #define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) |
978 | #include "llvm/BinaryFormat/DynamicTags.def" |
979 | #undef MIPS_DYNAMIC_TAG |
980 | #define MIPS_DYNAMIC_TAG(name, value) |
981 | break; |
982 | case ELF::EM_HEXAGON: |
983 | #undef HEXAGON_DYNAMIC_TAG |
984 | #define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) |
985 | #include "llvm/BinaryFormat/DynamicTags.def" |
986 | #undef HEXAGON_DYNAMIC_TAG |
987 | #define HEXAGON_DYNAMIC_TAG(name, value) |
988 | break; |
989 | case ELF::EM_PPC: |
990 | #undef PPC_DYNAMIC_TAG |
991 | #define PPC_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) |
992 | #include "llvm/BinaryFormat/DynamicTags.def" |
993 | #undef PPC_DYNAMIC_TAG |
994 | #define PPC_DYNAMIC_TAG(name, value) |
995 | break; |
996 | case ELF::EM_PPC64: |
997 | #undef PPC64_DYNAMIC_TAG |
998 | #define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) |
999 | #include "llvm/BinaryFormat/DynamicTags.def" |
1000 | #undef PPC64_DYNAMIC_TAG |
1001 | #define PPC64_DYNAMIC_TAG(name, value) |
1002 | break; |
1003 | case ELF::EM_RISCV: |
1004 | #undef RISCV_DYNAMIC_TAG |
1005 | #define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value) |
1006 | #include "llvm/BinaryFormat/DynamicTags.def" |
1007 | #undef RISCV_DYNAMIC_TAG |
1008 | #define RISCV_DYNAMIC_TAG(name, value) |
1009 | break; |
1010 | default: |
1011 | #include "llvm/BinaryFormat/DynamicTags.def" |
1012 | break; |
1013 | } |
1014 | #undef AARCH64_DYNAMIC_TAG |
1015 | #undef MIPS_DYNAMIC_TAG |
1016 | #undef HEXAGON_DYNAMIC_TAG |
1017 | #undef PPC_DYNAMIC_TAG |
1018 | #undef PPC64_DYNAMIC_TAG |
1019 | #undef DYNAMIC_TAG_MARKER |
1020 | #undef STRINGIFY |
1021 | #undef DYNAMIC_TAG |
1022 | |
1023 | IO.enumFallback<Hex64>(Val&: Value); |
1024 | } |
1025 | |
1026 | void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration( |
1027 | IO &IO, ELFYAML::MIPS_AFL_REG &Value) { |
1028 | #define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X) |
1029 | ECase(REG_NONE); |
1030 | ECase(REG_32); |
1031 | ECase(REG_64); |
1032 | ECase(REG_128); |
1033 | #undef ECase |
1034 | } |
1035 | |
1036 | void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration( |
1037 | IO &IO, ELFYAML::MIPS_ABI_FP &Value) { |
1038 | #define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X) |
1039 | ECase(FP_ANY); |
1040 | ECase(FP_DOUBLE); |
1041 | ECase(FP_SINGLE); |
1042 | ECase(FP_SOFT); |
1043 | ECase(FP_OLD_64); |
1044 | ECase(FP_XX); |
1045 | ECase(FP_64); |
1046 | ECase(FP_64A); |
1047 | #undef ECase |
1048 | } |
1049 | |
1050 | void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration( |
1051 | IO &IO, ELFYAML::MIPS_AFL_EXT &Value) { |
1052 | #define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X) |
1053 | ECase(EXT_NONE); |
1054 | ECase(EXT_XLR); |
1055 | ECase(EXT_OCTEON2); |
1056 | ECase(EXT_OCTEONP); |
1057 | ECase(EXT_LOONGSON_3A); |
1058 | ECase(EXT_OCTEON); |
1059 | ECase(EXT_5900); |
1060 | ECase(EXT_4650); |
1061 | ECase(EXT_4010); |
1062 | ECase(EXT_4100); |
1063 | ECase(EXT_3900); |
1064 | ECase(EXT_10000); |
1065 | ECase(EXT_SB1); |
1066 | ECase(EXT_4111); |
1067 | ECase(EXT_4120); |
1068 | ECase(EXT_5400); |
1069 | ECase(EXT_5500); |
1070 | ECase(EXT_LOONGSON_2E); |
1071 | ECase(EXT_LOONGSON_2F); |
1072 | ECase(EXT_OCTEON3); |
1073 | #undef ECase |
1074 | } |
1075 | |
1076 | void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration( |
1077 | IO &IO, ELFYAML::MIPS_ISA &Value) { |
1078 | IO.enumCase(Val&: Value, Str: "MIPS1" , ConstVal: 1); |
1079 | IO.enumCase(Val&: Value, Str: "MIPS2" , ConstVal: 2); |
1080 | IO.enumCase(Val&: Value, Str: "MIPS3" , ConstVal: 3); |
1081 | IO.enumCase(Val&: Value, Str: "MIPS4" , ConstVal: 4); |
1082 | IO.enumCase(Val&: Value, Str: "MIPS5" , ConstVal: 5); |
1083 | IO.enumCase(Val&: Value, Str: "MIPS32" , ConstVal: 32); |
1084 | IO.enumCase(Val&: Value, Str: "MIPS64" , ConstVal: 64); |
1085 | IO.enumFallback<Hex32>(Val&: Value); |
1086 | } |
1087 | |
1088 | void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset( |
1089 | IO &IO, ELFYAML::MIPS_AFL_ASE &Value) { |
1090 | #define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X) |
1091 | BCase(DSP); |
1092 | BCase(DSPR2); |
1093 | BCase(EVA); |
1094 | BCase(MCU); |
1095 | BCase(MDMX); |
1096 | BCase(MIPS3D); |
1097 | BCase(MT); |
1098 | BCase(SMARTMIPS); |
1099 | BCase(VIRT); |
1100 | BCase(MSA); |
1101 | BCase(MIPS16); |
1102 | BCase(MICROMIPS); |
1103 | BCase(XPA); |
1104 | BCase(CRC); |
1105 | BCase(GINV); |
1106 | #undef BCase |
1107 | } |
1108 | |
1109 | void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset( |
1110 | IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) { |
1111 | #define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X) |
1112 | BCase(ODDSPREG); |
1113 | #undef BCase |
1114 | } |
1115 | |
1116 | void MappingTraits<ELFYAML::SectionHeader>::( |
1117 | IO &IO, ELFYAML::SectionHeader &SHdr) { |
1118 | IO.mapRequired(Key: "Name" , Val&: SHdr.Name); |
1119 | } |
1120 | |
1121 | void MappingTraits<ELFYAML::FileHeader>::(IO &IO, |
1122 | ELFYAML::FileHeader &FileHdr) { |
1123 | IO.mapRequired(Key: "Class" , Val&: FileHdr.Class); |
1124 | IO.mapRequired(Key: "Data" , Val&: FileHdr.Data); |
1125 | IO.mapOptional(Key: "OSABI" , Val&: FileHdr.OSABI, Default: ELFYAML::ELF_ELFOSABI(0)); |
1126 | IO.mapOptional(Key: "ABIVersion" , Val&: FileHdr.ABIVersion, Default: Hex8(0)); |
1127 | IO.mapRequired(Key: "Type" , Val&: FileHdr.Type); |
1128 | IO.mapOptional(Key: "Machine" , Val&: FileHdr.Machine); |
1129 | IO.mapOptional(Key: "Flags" , Val&: FileHdr.Flags, Default: ELFYAML::ELF_EF(0)); |
1130 | IO.mapOptional(Key: "Entry" , Val&: FileHdr.Entry, Default: Hex64(0)); |
1131 | IO.mapOptional(Key: "SectionHeaderStringTable" , Val&: FileHdr.SectionHeaderStringTable); |
1132 | |
1133 | // obj2yaml does not dump these fields. |
1134 | assert(!IO.outputting() || |
1135 | (!FileHdr.EPhOff && !FileHdr.EPhEntSize && !FileHdr.EPhNum)); |
1136 | IO.mapOptional(Key: "EPhOff" , Val&: FileHdr.EPhOff); |
1137 | IO.mapOptional(Key: "EPhEntSize" , Val&: FileHdr.EPhEntSize); |
1138 | IO.mapOptional(Key: "EPhNum" , Val&: FileHdr.EPhNum); |
1139 | IO.mapOptional(Key: "EShEntSize" , Val&: FileHdr.EShEntSize); |
1140 | IO.mapOptional(Key: "EShOff" , Val&: FileHdr.EShOff); |
1141 | IO.mapOptional(Key: "EShNum" , Val&: FileHdr.EShNum); |
1142 | IO.mapOptional(Key: "EShStrNdx" , Val&: FileHdr.EShStrNdx); |
1143 | } |
1144 | |
1145 | void MappingTraits<ELFYAML::ProgramHeader>::( |
1146 | IO &IO, ELFYAML::ProgramHeader &Phdr) { |
1147 | IO.mapRequired(Key: "Type" , Val&: Phdr.Type); |
1148 | IO.mapOptional(Key: "Flags" , Val&: Phdr.Flags, Default: ELFYAML::ELF_PF(0)); |
1149 | IO.mapOptional(Key: "FirstSec" , Val&: Phdr.FirstSec); |
1150 | IO.mapOptional(Key: "LastSec" , Val&: Phdr.LastSec); |
1151 | IO.mapOptional(Key: "VAddr" , Val&: Phdr.VAddr, Default: Hex64(0)); |
1152 | IO.mapOptional(Key: "PAddr" , Val&: Phdr.PAddr, Default: Phdr.VAddr); |
1153 | IO.mapOptional(Key: "Align" , Val&: Phdr.Align); |
1154 | IO.mapOptional(Key: "FileSize" , Val&: Phdr.FileSize); |
1155 | IO.mapOptional(Key: "MemSize" , Val&: Phdr.MemSize); |
1156 | IO.mapOptional(Key: "Offset" , Val&: Phdr.Offset); |
1157 | } |
1158 | |
1159 | std::string MappingTraits<ELFYAML::ProgramHeader>::( |
1160 | IO &IO, ELFYAML::ProgramHeader &FileHdr) { |
1161 | if (!FileHdr.FirstSec && FileHdr.LastSec) |
1162 | return "the \"LastSec\" key can't be used without the \"FirstSec\" key" ; |
1163 | if (FileHdr.FirstSec && !FileHdr.LastSec) |
1164 | return "the \"FirstSec\" key can't be used without the \"LastSec\" key" ; |
1165 | return "" ; |
1166 | } |
1167 | |
1168 | LLVM_YAML_STRONG_TYPEDEF(StringRef, StOtherPiece) |
1169 | |
1170 | template <> struct ScalarTraits<StOtherPiece> { |
1171 | static void output(const StOtherPiece &Val, void *, raw_ostream &Out) { |
1172 | Out << Val; |
1173 | } |
1174 | static StringRef input(StringRef Scalar, void *, StOtherPiece &Val) { |
1175 | Val = Scalar; |
1176 | return {}; |
1177 | } |
1178 | static QuotingType mustQuote(StringRef) { return QuotingType::None; } |
1179 | }; |
1180 | template <> struct SequenceElementTraits<StOtherPiece> { |
1181 | static const bool flow = true; |
1182 | }; |
1183 | |
1184 | template <> struct ScalarTraits<ELFYAML::YAMLFlowString> { |
1185 | static void output(const ELFYAML::YAMLFlowString &Val, void *, |
1186 | raw_ostream &Out) { |
1187 | Out << Val; |
1188 | } |
1189 | static StringRef input(StringRef Scalar, void *, |
1190 | ELFYAML::YAMLFlowString &Val) { |
1191 | Val = Scalar; |
1192 | return {}; |
1193 | } |
1194 | static QuotingType mustQuote(StringRef S) { |
1195 | return ScalarTraits<StringRef>::mustQuote(S); |
1196 | } |
1197 | }; |
1198 | template <> struct SequenceElementTraits<ELFYAML::YAMLFlowString> { |
1199 | static const bool flow = true; |
1200 | }; |
1201 | |
1202 | namespace { |
1203 | |
1204 | struct NormalizedOther { |
1205 | NormalizedOther(IO &IO) : YamlIO(IO) {} |
1206 | NormalizedOther(IO &IO, std::optional<uint8_t> Original) : YamlIO(IO) { |
1207 | assert(Original && "This constructor is only used for outputting YAML and " |
1208 | "assumes a non-empty Original" ); |
1209 | std::vector<StOtherPiece> Ret; |
1210 | const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext()); |
1211 | for (std::pair<StringRef, uint8_t> &P : |
1212 | getFlags(EMachine: Object->getMachine()).takeVector()) { |
1213 | uint8_t FlagValue = P.second; |
1214 | if ((*Original & FlagValue) != FlagValue) |
1215 | continue; |
1216 | *Original &= ~FlagValue; |
1217 | Ret.push_back(x: {P.first}); |
1218 | } |
1219 | |
1220 | if (*Original != 0) { |
1221 | UnknownFlagsHolder = std::to_string(val: *Original); |
1222 | Ret.push_back(x: {UnknownFlagsHolder}); |
1223 | } |
1224 | |
1225 | if (!Ret.empty()) |
1226 | Other = std::move(Ret); |
1227 | } |
1228 | |
1229 | uint8_t toValue(StringRef Name) { |
1230 | const auto *Object = static_cast<ELFYAML::Object *>(YamlIO.getContext()); |
1231 | MapVector<StringRef, uint8_t> Flags = getFlags(EMachine: Object->getMachine()); |
1232 | |
1233 | auto It = Flags.find(Key: Name); |
1234 | if (It != Flags.end()) |
1235 | return It->second; |
1236 | |
1237 | uint8_t Val; |
1238 | if (to_integer(S: Name, Num&: Val)) |
1239 | return Val; |
1240 | |
1241 | YamlIO.setError("an unknown value is used for symbol's 'Other' field: " + |
1242 | Name); |
1243 | return 0; |
1244 | } |
1245 | |
1246 | std::optional<uint8_t> denormalize(IO &) { |
1247 | if (!Other) |
1248 | return std::nullopt; |
1249 | uint8_t Ret = 0; |
1250 | for (StOtherPiece &Val : *Other) |
1251 | Ret |= toValue(Name: Val); |
1252 | return Ret; |
1253 | } |
1254 | |
1255 | // st_other field is used to encode symbol visibility and platform-dependent |
1256 | // flags and values. This method returns a name to value map that is used for |
1257 | // parsing and encoding this field. |
1258 | MapVector<StringRef, uint8_t> getFlags(unsigned EMachine) { |
1259 | MapVector<StringRef, uint8_t> Map; |
1260 | // STV_* values are just enumeration values. We add them in a reversed order |
1261 | // because when we convert the st_other to named constants when printing |
1262 | // YAML we want to use a maximum number of bits on each step: |
1263 | // when we have st_other == 3, we want to print it as STV_PROTECTED (3), but |
1264 | // not as STV_HIDDEN (2) + STV_INTERNAL (1). |
1265 | Map["STV_PROTECTED" ] = ELF::STV_PROTECTED; |
1266 | Map["STV_HIDDEN" ] = ELF::STV_HIDDEN; |
1267 | Map["STV_INTERNAL" ] = ELF::STV_INTERNAL; |
1268 | // STV_DEFAULT is used to represent the default visibility and has a value |
1269 | // 0. We want to be able to read it from YAML documents, but there is no |
1270 | // reason to print it. |
1271 | if (!YamlIO.outputting()) |
1272 | Map["STV_DEFAULT" ] = ELF::STV_DEFAULT; |
1273 | |
1274 | // MIPS is not consistent. All of the STO_MIPS_* values are bit flags, |
1275 | // except STO_MIPS_MIPS16 which overlaps them. It should be checked and |
1276 | // consumed first when we print the output, because we do not want to print |
1277 | // any other flags that have the same bits instead. |
1278 | if (EMachine == ELF::EM_MIPS) { |
1279 | Map["STO_MIPS_MIPS16" ] = ELF::STO_MIPS_MIPS16; |
1280 | Map["STO_MIPS_MICROMIPS" ] = ELF::STO_MIPS_MICROMIPS; |
1281 | Map["STO_MIPS_PIC" ] = ELF::STO_MIPS_PIC; |
1282 | Map["STO_MIPS_PLT" ] = ELF::STO_MIPS_PLT; |
1283 | Map["STO_MIPS_OPTIONAL" ] = ELF::STO_MIPS_OPTIONAL; |
1284 | } |
1285 | |
1286 | if (EMachine == ELF::EM_AARCH64) |
1287 | Map["STO_AARCH64_VARIANT_PCS" ] = ELF::STO_AARCH64_VARIANT_PCS; |
1288 | if (EMachine == ELF::EM_RISCV) |
1289 | Map["STO_RISCV_VARIANT_CC" ] = ELF::STO_RISCV_VARIANT_CC; |
1290 | return Map; |
1291 | } |
1292 | |
1293 | IO &YamlIO; |
1294 | std::optional<std::vector<StOtherPiece>> Other; |
1295 | std::string UnknownFlagsHolder; |
1296 | }; |
1297 | |
1298 | } // end anonymous namespace |
1299 | |
1300 | void ScalarTraits<ELFYAML::YAMLIntUInt>::output(const ELFYAML::YAMLIntUInt &Val, |
1301 | void *Ctx, raw_ostream &Out) { |
1302 | Out << Val; |
1303 | } |
1304 | |
1305 | StringRef ScalarTraits<ELFYAML::YAMLIntUInt>::input(StringRef Scalar, void *Ctx, |
1306 | ELFYAML::YAMLIntUInt &Val) { |
1307 | const bool Is64 = static_cast<ELFYAML::Object *>(Ctx)->Header.Class == |
1308 | ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); |
1309 | StringRef ErrMsg = "invalid number" ; |
1310 | // We do not accept negative hex numbers because their meaning is ambiguous. |
1311 | // For example, would -0xfffffffff mean 1 or INT32_MIN? |
1312 | if (Scalar.empty() || Scalar.starts_with(Prefix: "-0x" )) |
1313 | return ErrMsg; |
1314 | |
1315 | if (Scalar.starts_with(Prefix: "-" )) { |
1316 | const int64_t MinVal = Is64 ? INT64_MIN : INT32_MIN; |
1317 | long long Int; |
1318 | if (getAsSignedInteger(Str: Scalar, /*Radix=*/0, Result&: Int) || (Int < MinVal)) |
1319 | return ErrMsg; |
1320 | Val = Int; |
1321 | return "" ; |
1322 | } |
1323 | |
1324 | const uint64_t MaxVal = Is64 ? UINT64_MAX : UINT32_MAX; |
1325 | unsigned long long UInt; |
1326 | if (getAsUnsignedInteger(Str: Scalar, /*Radix=*/0, Result&: UInt) || (UInt > MaxVal)) |
1327 | return ErrMsg; |
1328 | Val = UInt; |
1329 | return "" ; |
1330 | } |
1331 | |
1332 | void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) { |
1333 | IO.mapOptional(Key: "Name" , Val&: Symbol.Name, Default: StringRef()); |
1334 | IO.mapOptional(Key: "StName" , Val&: Symbol.StName); |
1335 | IO.mapOptional(Key: "Type" , Val&: Symbol.Type, Default: ELFYAML::ELF_STT(0)); |
1336 | IO.mapOptional(Key: "Section" , Val&: Symbol.Section); |
1337 | IO.mapOptional(Key: "Index" , Val&: Symbol.Index); |
1338 | IO.mapOptional(Key: "Binding" , Val&: Symbol.Binding, Default: ELFYAML::ELF_STB(0)); |
1339 | IO.mapOptional(Key: "Value" , Val&: Symbol.Value); |
1340 | IO.mapOptional(Key: "Size" , Val&: Symbol.Size); |
1341 | |
1342 | // Symbol's Other field is a bit special. It is usually a field that |
1343 | // represents st_other and holds the symbol visibility. However, on some |
1344 | // platforms, it can contain bit fields and regular values, or even sometimes |
1345 | // a crazy mix of them (see comments for NormalizedOther). Because of this, we |
1346 | // need special handling. |
1347 | MappingNormalization<NormalizedOther, std::optional<uint8_t>> Keys( |
1348 | IO, Symbol.Other); |
1349 | IO.mapOptional(Key: "Other" , Val&: Keys->Other); |
1350 | } |
1351 | |
1352 | std::string MappingTraits<ELFYAML::Symbol>::validate(IO &IO, |
1353 | ELFYAML::Symbol &Symbol) { |
1354 | if (Symbol.Index && Symbol.Section) |
1355 | return "Index and Section cannot both be specified for Symbol" ; |
1356 | return "" ; |
1357 | } |
1358 | |
1359 | static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) { |
1360 | IO.mapOptional(Key: "Name" , Val&: Section.Name, Default: StringRef()); |
1361 | IO.mapRequired(Key: "Type" , Val&: Section.Type); |
1362 | IO.mapOptional(Key: "Flags" , Val&: Section.Flags); |
1363 | IO.mapOptional(Key: "Address" , Val&: Section.Address); |
1364 | IO.mapOptional(Key: "Link" , Val&: Section.Link); |
1365 | IO.mapOptional(Key: "AddressAlign" , Val&: Section.AddressAlign, Default: Hex64(0)); |
1366 | IO.mapOptional(Key: "EntSize" , Val&: Section.EntSize); |
1367 | IO.mapOptional(Key: "Offset" , Val&: Section.Offset); |
1368 | |
1369 | IO.mapOptional(Key: "Content" , Val&: Section.Content); |
1370 | IO.mapOptional(Key: "Size" , Val&: Section.Size); |
1371 | |
1372 | // obj2yaml does not dump these fields. They are expected to be empty when we |
1373 | // are producing YAML, because yaml2obj sets appropriate values for them |
1374 | // automatically when they are not explicitly defined. |
1375 | assert(!IO.outputting() || |
1376 | (!Section.ShOffset && !Section.ShSize && !Section.ShName && |
1377 | !Section.ShFlags && !Section.ShType && !Section.ShAddrAlign)); |
1378 | IO.mapOptional(Key: "ShAddrAlign" , Val&: Section.ShAddrAlign); |
1379 | IO.mapOptional(Key: "ShName" , Val&: Section.ShName); |
1380 | IO.mapOptional(Key: "ShOffset" , Val&: Section.ShOffset); |
1381 | IO.mapOptional(Key: "ShSize" , Val&: Section.ShSize); |
1382 | IO.mapOptional(Key: "ShFlags" , Val&: Section.ShFlags); |
1383 | IO.mapOptional(Key: "ShType" , Val&: Section.ShType); |
1384 | } |
1385 | |
1386 | static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) { |
1387 | commonSectionMapping(IO, Section); |
1388 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1389 | } |
1390 | |
1391 | static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { |
1392 | commonSectionMapping(IO, Section); |
1393 | |
1394 | // We also support reading a content as array of bytes using the ContentArray |
1395 | // key. obj2yaml never prints this field. |
1396 | assert(!IO.outputting() || !Section.ContentBuf); |
1397 | IO.mapOptional(Key: "ContentArray" , Val&: Section.ContentBuf); |
1398 | if (Section.ContentBuf) { |
1399 | if (Section.Content) |
1400 | IO.setError("Content and ContentArray can't be used together" ); |
1401 | Section.Content = yaml::BinaryRef(*Section.ContentBuf); |
1402 | } |
1403 | |
1404 | IO.mapOptional(Key: "Info" , Val&: Section.Info); |
1405 | } |
1406 | |
1407 | static void sectionMapping(IO &IO, ELFYAML::BBAddrMapSection &Section) { |
1408 | commonSectionMapping(IO, Section); |
1409 | IO.mapOptional(Key: "Content" , Val&: Section.Content); |
1410 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1411 | IO.mapOptional(Key: "PGOAnalyses" , Val&: Section.PGOAnalyses); |
1412 | } |
1413 | |
1414 | static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) { |
1415 | commonSectionMapping(IO, Section); |
1416 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1417 | } |
1418 | |
1419 | static void sectionMapping(IO &IO, ELFYAML::HashSection &Section) { |
1420 | commonSectionMapping(IO, Section); |
1421 | IO.mapOptional(Key: "Bucket" , Val&: Section.Bucket); |
1422 | IO.mapOptional(Key: "Chain" , Val&: Section.Chain); |
1423 | |
1424 | // obj2yaml does not dump these fields. They can be used to override nchain |
1425 | // and nbucket values for creating broken sections. |
1426 | assert(!IO.outputting() || (!Section.NBucket && !Section.NChain)); |
1427 | IO.mapOptional(Key: "NChain" , Val&: Section.NChain); |
1428 | IO.mapOptional(Key: "NBucket" , Val&: Section.NBucket); |
1429 | } |
1430 | |
1431 | static void sectionMapping(IO &IO, ELFYAML::NoteSection &Section) { |
1432 | commonSectionMapping(IO, Section); |
1433 | IO.mapOptional(Key: "Notes" , Val&: Section.Notes); |
1434 | } |
1435 | |
1436 | |
1437 | static void sectionMapping(IO &IO, ELFYAML::GnuHashSection &Section) { |
1438 | commonSectionMapping(IO, Section); |
1439 | IO.mapOptional(Key: "Header" , Val&: Section.Header); |
1440 | IO.mapOptional(Key: "BloomFilter" , Val&: Section.BloomFilter); |
1441 | IO.mapOptional(Key: "HashBuckets" , Val&: Section.HashBuckets); |
1442 | IO.mapOptional(Key: "HashValues" , Val&: Section.HashValues); |
1443 | } |
1444 | static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) { |
1445 | commonSectionMapping(IO, Section); |
1446 | } |
1447 | |
1448 | static void sectionMapping(IO &IO, ELFYAML::VerdefSection &Section) { |
1449 | commonSectionMapping(IO, Section); |
1450 | IO.mapOptional(Key: "Info" , Val&: Section.Info); |
1451 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1452 | } |
1453 | |
1454 | static void sectionMapping(IO &IO, ELFYAML::SymverSection &Section) { |
1455 | commonSectionMapping(IO, Section); |
1456 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1457 | } |
1458 | |
1459 | static void sectionMapping(IO &IO, ELFYAML::VerneedSection &Section) { |
1460 | commonSectionMapping(IO, Section); |
1461 | IO.mapOptional(Key: "Info" , Val&: Section.Info); |
1462 | IO.mapOptional(Key: "Dependencies" , Val&: Section.VerneedV); |
1463 | } |
1464 | |
1465 | static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) { |
1466 | commonSectionMapping(IO, Section); |
1467 | IO.mapOptional(Key: "Info" , Val&: Section.RelocatableSec, Default: StringRef()); |
1468 | IO.mapOptional(Key: "Relocations" , Val&: Section.Relocations); |
1469 | } |
1470 | |
1471 | static void sectionMapping(IO &IO, ELFYAML::RelrSection &Section) { |
1472 | commonSectionMapping(IO, Section); |
1473 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1474 | } |
1475 | |
1476 | static void groupSectionMapping(IO &IO, ELFYAML::GroupSection &Group) { |
1477 | commonSectionMapping(IO, Section&: Group); |
1478 | IO.mapOptional(Key: "Info" , Val&: Group.Signature); |
1479 | IO.mapOptional(Key: "Members" , Val&: Group.Members); |
1480 | } |
1481 | |
1482 | static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) { |
1483 | commonSectionMapping(IO, Section); |
1484 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1485 | } |
1486 | |
1487 | static void sectionMapping(IO &IO, ELFYAML::AddrsigSection &Section) { |
1488 | commonSectionMapping(IO, Section); |
1489 | IO.mapOptional(Key: "Symbols" , Val&: Section.Symbols); |
1490 | } |
1491 | |
1492 | static void fillMapping(IO &IO, ELFYAML::Fill &Fill) { |
1493 | IO.mapOptional(Key: "Name" , Val&: Fill.Name, Default: StringRef()); |
1494 | IO.mapOptional(Key: "Pattern" , Val&: Fill.Pattern); |
1495 | IO.mapOptional(Key: "Offset" , Val&: Fill.Offset); |
1496 | IO.mapRequired(Key: "Size" , Val&: Fill.Size); |
1497 | } |
1498 | |
1499 | static void (IO &IO, |
1500 | ELFYAML::SectionHeaderTable &SHT) { |
1501 | IO.mapOptional(Key: "Offset" , Val&: SHT.Offset); |
1502 | IO.mapOptional(Key: "Sections" , Val&: SHT.Sections); |
1503 | IO.mapOptional(Key: "Excluded" , Val&: SHT.Excluded); |
1504 | IO.mapOptional(Key: "NoHeaders" , Val&: SHT.NoHeaders); |
1505 | } |
1506 | |
1507 | static void sectionMapping(IO &IO, ELFYAML::LinkerOptionsSection &Section) { |
1508 | commonSectionMapping(IO, Section); |
1509 | IO.mapOptional(Key: "Options" , Val&: Section.Options); |
1510 | } |
1511 | |
1512 | static void sectionMapping(IO &IO, |
1513 | ELFYAML::DependentLibrariesSection &Section) { |
1514 | commonSectionMapping(IO, Section); |
1515 | IO.mapOptional(Key: "Libraries" , Val&: Section.Libs); |
1516 | } |
1517 | |
1518 | static void sectionMapping(IO &IO, ELFYAML::CallGraphProfileSection &Section) { |
1519 | commonSectionMapping(IO, Section); |
1520 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1521 | } |
1522 | |
1523 | void MappingTraits<ELFYAML::SectionOrType>::mapping( |
1524 | IO &IO, ELFYAML::SectionOrType §ionOrType) { |
1525 | IO.mapRequired(Key: "SectionOrType" , Val&: sectionOrType.sectionNameOrType); |
1526 | } |
1527 | |
1528 | static void sectionMapping(IO &IO, ELFYAML::ARMIndexTableSection &Section) { |
1529 | commonSectionMapping(IO, Section); |
1530 | IO.mapOptional(Key: "Entries" , Val&: Section.Entries); |
1531 | } |
1532 | |
1533 | static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) { |
1534 | commonSectionMapping(IO, Section); |
1535 | IO.mapOptional(Key: "Version" , Val&: Section.Version, Default: Hex16(0)); |
1536 | IO.mapRequired(Key: "ISA" , Val&: Section.ISALevel); |
1537 | IO.mapOptional(Key: "ISARevision" , Val&: Section.ISARevision, Default: Hex8(0)); |
1538 | IO.mapOptional(Key: "ISAExtension" , Val&: Section.ISAExtension, |
1539 | Default: ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE)); |
1540 | IO.mapOptional(Key: "ASEs" , Val&: Section.ASEs, Default: ELFYAML::MIPS_AFL_ASE(0)); |
1541 | IO.mapOptional(Key: "FpABI" , Val&: Section.FpABI, |
1542 | Default: ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY)); |
1543 | IO.mapOptional(Key: "GPRSize" , Val&: Section.GPRSize, |
1544 | Default: ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE)); |
1545 | IO.mapOptional(Key: "CPR1Size" , Val&: Section.CPR1Size, |
1546 | Default: ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE)); |
1547 | IO.mapOptional(Key: "CPR2Size" , Val&: Section.CPR2Size, |
1548 | Default: ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE)); |
1549 | IO.mapOptional(Key: "Flags1" , Val&: Section.Flags1, Default: ELFYAML::MIPS_AFL_FLAGS1(0)); |
1550 | IO.mapOptional(Key: "Flags2" , Val&: Section.Flags2, Default: Hex32(0)); |
1551 | } |
1552 | |
1553 | static StringRef getStringValue(IO &IO, const char *Key) { |
1554 | StringRef Val; |
1555 | IO.mapRequired(Key, Val); |
1556 | return Val; |
1557 | } |
1558 | |
1559 | static void setStringValue(IO &IO, const char *Key, StringRef Val) { |
1560 | IO.mapRequired(Key, Val); |
1561 | } |
1562 | |
1563 | static bool isInteger(StringRef Val) { |
1564 | APInt Tmp; |
1565 | return !Val.getAsInteger(Radix: 0, Result&: Tmp); |
1566 | } |
1567 | |
1568 | void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping( |
1569 | IO &IO, std::unique_ptr<ELFYAML::Chunk> &Section) { |
1570 | ELFYAML::ELF_SHT Type; |
1571 | StringRef TypeStr; |
1572 | if (IO.outputting()) { |
1573 | if (auto *S = dyn_cast<ELFYAML::Section>(Val: Section.get())) |
1574 | Type = S->Type; |
1575 | else if (auto *SHT = dyn_cast<ELFYAML::SectionHeaderTable>(Val: Section.get())) |
1576 | TypeStr = SHT->TypeStr; |
1577 | } else { |
1578 | // When the Type string does not have a "SHT_" prefix, we know it is not a |
1579 | // description of a regular ELF output section. |
1580 | TypeStr = getStringValue(IO, Key: "Type" ); |
1581 | if (TypeStr.starts_with(Prefix: "SHT_" ) || isInteger(Val: TypeStr)) |
1582 | IO.mapRequired(Key: "Type" , Val&: Type); |
1583 | } |
1584 | |
1585 | if (TypeStr == "Fill" ) { |
1586 | assert(!IO.outputting()); // We don't dump fills currently. |
1587 | Section.reset(p: new ELFYAML::Fill()); |
1588 | fillMapping(IO, Fill&: *cast<ELFYAML::Fill>(Val: Section.get())); |
1589 | return; |
1590 | } |
1591 | |
1592 | if (TypeStr == ELFYAML::SectionHeaderTable::TypeStr) { |
1593 | if (IO.outputting()) |
1594 | setStringValue(IO, Key: "Type" , Val: TypeStr); |
1595 | else |
1596 | Section.reset(p: new ELFYAML::SectionHeaderTable(/*IsImplicit=*/false)); |
1597 | |
1598 | sectionHeaderTableMapping( |
1599 | IO, SHT&: *cast<ELFYAML::SectionHeaderTable>(Val: Section.get())); |
1600 | return; |
1601 | } |
1602 | |
1603 | const auto &Obj = *static_cast<ELFYAML::Object *>(IO.getContext()); |
1604 | if (Obj.getMachine() == ELF::EM_MIPS && Type == ELF::SHT_MIPS_ABIFLAGS) { |
1605 | if (!IO.outputting()) |
1606 | Section.reset(p: new ELFYAML::MipsABIFlags()); |
1607 | sectionMapping(IO, Section&: *cast<ELFYAML::MipsABIFlags>(Val: Section.get())); |
1608 | return; |
1609 | } |
1610 | |
1611 | if (Obj.getMachine() == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX) { |
1612 | if (!IO.outputting()) |
1613 | Section.reset(p: new ELFYAML::ARMIndexTableSection()); |
1614 | sectionMapping(IO, Section&: *cast<ELFYAML::ARMIndexTableSection>(Val: Section.get())); |
1615 | return; |
1616 | } |
1617 | |
1618 | switch (Type) { |
1619 | case ELF::SHT_DYNAMIC: |
1620 | if (!IO.outputting()) |
1621 | Section.reset(p: new ELFYAML::DynamicSection()); |
1622 | sectionMapping(IO, Section&: *cast<ELFYAML::DynamicSection>(Val: Section.get())); |
1623 | break; |
1624 | case ELF::SHT_REL: |
1625 | case ELF::SHT_RELA: |
1626 | case ELF::SHT_CREL: |
1627 | if (!IO.outputting()) |
1628 | Section.reset(p: new ELFYAML::RelocationSection()); |
1629 | sectionMapping(IO, Section&: *cast<ELFYAML::RelocationSection>(Val: Section.get())); |
1630 | break; |
1631 | case ELF::SHT_RELR: |
1632 | if (!IO.outputting()) |
1633 | Section.reset(p: new ELFYAML::RelrSection()); |
1634 | sectionMapping(IO, Section&: *cast<ELFYAML::RelrSection>(Val: Section.get())); |
1635 | break; |
1636 | case ELF::SHT_GROUP: |
1637 | if (!IO.outputting()) |
1638 | Section.reset(p: new ELFYAML::GroupSection()); |
1639 | groupSectionMapping(IO, Group&: *cast<ELFYAML::GroupSection>(Val: Section.get())); |
1640 | break; |
1641 | case ELF::SHT_NOBITS: |
1642 | if (!IO.outputting()) |
1643 | Section.reset(p: new ELFYAML::NoBitsSection()); |
1644 | sectionMapping(IO, Section&: *cast<ELFYAML::NoBitsSection>(Val: Section.get())); |
1645 | break; |
1646 | case ELF::SHT_HASH: |
1647 | if (!IO.outputting()) |
1648 | Section.reset(p: new ELFYAML::HashSection()); |
1649 | sectionMapping(IO, Section&: *cast<ELFYAML::HashSection>(Val: Section.get())); |
1650 | break; |
1651 | case ELF::SHT_NOTE: |
1652 | if (!IO.outputting()) |
1653 | Section.reset(p: new ELFYAML::NoteSection()); |
1654 | sectionMapping(IO, Section&: *cast<ELFYAML::NoteSection>(Val: Section.get())); |
1655 | break; |
1656 | case ELF::SHT_GNU_HASH: |
1657 | if (!IO.outputting()) |
1658 | Section.reset(p: new ELFYAML::GnuHashSection()); |
1659 | sectionMapping(IO, Section&: *cast<ELFYAML::GnuHashSection>(Val: Section.get())); |
1660 | break; |
1661 | case ELF::SHT_GNU_verdef: |
1662 | if (!IO.outputting()) |
1663 | Section.reset(p: new ELFYAML::VerdefSection()); |
1664 | sectionMapping(IO, Section&: *cast<ELFYAML::VerdefSection>(Val: Section.get())); |
1665 | break; |
1666 | case ELF::SHT_GNU_versym: |
1667 | if (!IO.outputting()) |
1668 | Section.reset(p: new ELFYAML::SymverSection()); |
1669 | sectionMapping(IO, Section&: *cast<ELFYAML::SymverSection>(Val: Section.get())); |
1670 | break; |
1671 | case ELF::SHT_GNU_verneed: |
1672 | if (!IO.outputting()) |
1673 | Section.reset(p: new ELFYAML::VerneedSection()); |
1674 | sectionMapping(IO, Section&: *cast<ELFYAML::VerneedSection>(Val: Section.get())); |
1675 | break; |
1676 | case ELF::SHT_SYMTAB_SHNDX: |
1677 | if (!IO.outputting()) |
1678 | Section.reset(p: new ELFYAML::SymtabShndxSection()); |
1679 | sectionMapping(IO, Section&: *cast<ELFYAML::SymtabShndxSection>(Val: Section.get())); |
1680 | break; |
1681 | case ELF::SHT_LLVM_ADDRSIG: |
1682 | if (!IO.outputting()) |
1683 | Section.reset(p: new ELFYAML::AddrsigSection()); |
1684 | sectionMapping(IO, Section&: *cast<ELFYAML::AddrsigSection>(Val: Section.get())); |
1685 | break; |
1686 | case ELF::SHT_LLVM_LINKER_OPTIONS: |
1687 | if (!IO.outputting()) |
1688 | Section.reset(p: new ELFYAML::LinkerOptionsSection()); |
1689 | sectionMapping(IO, Section&: *cast<ELFYAML::LinkerOptionsSection>(Val: Section.get())); |
1690 | break; |
1691 | case ELF::SHT_LLVM_DEPENDENT_LIBRARIES: |
1692 | if (!IO.outputting()) |
1693 | Section.reset(p: new ELFYAML::DependentLibrariesSection()); |
1694 | sectionMapping(IO, |
1695 | Section&: *cast<ELFYAML::DependentLibrariesSection>(Val: Section.get())); |
1696 | break; |
1697 | case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: |
1698 | if (!IO.outputting()) |
1699 | Section.reset(p: new ELFYAML::CallGraphProfileSection()); |
1700 | sectionMapping(IO, Section&: *cast<ELFYAML::CallGraphProfileSection>(Val: Section.get())); |
1701 | break; |
1702 | case ELF::SHT_LLVM_BB_ADDR_MAP: |
1703 | if (!IO.outputting()) |
1704 | Section.reset(p: new ELFYAML::BBAddrMapSection()); |
1705 | sectionMapping(IO, Section&: *cast<ELFYAML::BBAddrMapSection>(Val: Section.get())); |
1706 | break; |
1707 | default: |
1708 | if (!IO.outputting()) { |
1709 | StringRef Name; |
1710 | IO.mapOptional(Key: "Name" , Val&: Name, Default: StringRef()); |
1711 | Name = ELFYAML::dropUniqueSuffix(S: Name); |
1712 | |
1713 | if (ELFYAML::StackSizesSection::nameMatches(Name)) |
1714 | Section = std::make_unique<ELFYAML::StackSizesSection>(); |
1715 | else |
1716 | Section = std::make_unique<ELFYAML::RawContentSection>(); |
1717 | } |
1718 | |
1719 | if (auto S = dyn_cast<ELFYAML::RawContentSection>(Val: Section.get())) |
1720 | sectionMapping(IO, Section&: *S); |
1721 | else |
1722 | sectionMapping(IO, Section&: *cast<ELFYAML::StackSizesSection>(Val: Section.get())); |
1723 | } |
1724 | } |
1725 | |
1726 | std::string MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate( |
1727 | IO &io, std::unique_ptr<ELFYAML::Chunk> &C) { |
1728 | if (const auto *F = dyn_cast<ELFYAML::Fill>(Val: C.get())) { |
1729 | if (F->Pattern && F->Pattern->binary_size() != 0 && !F->Size) |
1730 | return "\"Size\" can't be 0 when \"Pattern\" is not empty" ; |
1731 | return "" ; |
1732 | } |
1733 | |
1734 | if (const auto *SHT = dyn_cast<ELFYAML::SectionHeaderTable>(Val: C.get())) { |
1735 | if (SHT->NoHeaders && (SHT->Sections || SHT->Excluded || SHT->Offset)) |
1736 | return "NoHeaders can't be used together with Offset/Sections/Excluded" ; |
1737 | return "" ; |
1738 | } |
1739 | |
1740 | const ELFYAML::Section &Sec = *cast<ELFYAML::Section>(Val: C.get()); |
1741 | if (Sec.Size && Sec.Content && |
1742 | (uint64_t)(*Sec.Size) < Sec.Content->binary_size()) |
1743 | return "Section size must be greater than or equal to the content size" ; |
1744 | |
1745 | auto BuildErrPrefix = [](ArrayRef<std::pair<StringRef, bool>> EntV) { |
1746 | std::string Msg; |
1747 | for (size_t I = 0, E = EntV.size(); I != E; ++I) { |
1748 | StringRef Name = EntV[I].first; |
1749 | if (I == 0) { |
1750 | Msg = "\"" + Name.str() + "\"" ; |
1751 | continue; |
1752 | } |
1753 | if (I != EntV.size() - 1) |
1754 | Msg += ", \"" + Name.str() + "\"" ; |
1755 | else |
1756 | Msg += " and \"" + Name.str() + "\"" ; |
1757 | } |
1758 | return Msg; |
1759 | }; |
1760 | |
1761 | std::vector<std::pair<StringRef, bool>> Entries = Sec.getEntries(); |
1762 | const size_t NumUsedEntries = llvm::count_if( |
1763 | Range&: Entries, P: [](const std::pair<StringRef, bool> &P) { return P.second; }); |
1764 | |
1765 | if ((Sec.Size || Sec.Content) && NumUsedEntries > 0) |
1766 | return BuildErrPrefix(Entries) + |
1767 | " cannot be used with \"Content\" or \"Size\"" ; |
1768 | |
1769 | if (NumUsedEntries > 0 && Entries.size() != NumUsedEntries) |
1770 | return BuildErrPrefix(Entries) + " must be used together" ; |
1771 | |
1772 | if (const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(Val: C.get())) { |
1773 | if (RawSection->Flags && RawSection->ShFlags) |
1774 | return "ShFlags and Flags cannot be used together" ; |
1775 | return "" ; |
1776 | } |
1777 | |
1778 | if (const auto *NB = dyn_cast<ELFYAML::NoBitsSection>(Val: C.get())) { |
1779 | if (NB->Content) |
1780 | return "SHT_NOBITS section cannot have \"Content\"" ; |
1781 | return "" ; |
1782 | } |
1783 | |
1784 | if (const auto *MF = dyn_cast<ELFYAML::MipsABIFlags>(Val: C.get())) { |
1785 | if (MF->Content) |
1786 | return "\"Content\" key is not implemented for SHT_MIPS_ABIFLAGS " |
1787 | "sections" ; |
1788 | if (MF->Size) |
1789 | return "\"Size\" key is not implemented for SHT_MIPS_ABIFLAGS sections" ; |
1790 | return "" ; |
1791 | } |
1792 | |
1793 | return "" ; |
1794 | } |
1795 | |
1796 | namespace { |
1797 | |
1798 | struct NormalizedMips64RelType { |
1799 | NormalizedMips64RelType(IO &) |
1800 | : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)), |
1801 | Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)), |
1802 | Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)), |
1803 | SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {} |
1804 | NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original) |
1805 | : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF), |
1806 | Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {} |
1807 | |
1808 | ELFYAML::ELF_REL denormalize(IO &) { |
1809 | ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24; |
1810 | return Res; |
1811 | } |
1812 | |
1813 | ELFYAML::ELF_REL Type; |
1814 | ELFYAML::ELF_REL Type2; |
1815 | ELFYAML::ELF_REL Type3; |
1816 | ELFYAML::ELF_RSS SpecSym; |
1817 | }; |
1818 | |
1819 | } // end anonymous namespace |
1820 | |
1821 | void MappingTraits<ELFYAML::StackSizeEntry>::mapping( |
1822 | IO &IO, ELFYAML::StackSizeEntry &E) { |
1823 | assert(IO.getContext() && "The IO context is not initialized" ); |
1824 | IO.mapOptional(Key: "Address" , Val&: E.Address, Default: Hex64(0)); |
1825 | IO.mapRequired(Key: "Size" , Val&: E.Size); |
1826 | } |
1827 | |
1828 | void MappingTraits<ELFYAML::BBAddrMapEntry>::mapping( |
1829 | IO &IO, ELFYAML::BBAddrMapEntry &E) { |
1830 | assert(IO.getContext() && "The IO context is not initialized" ); |
1831 | IO.mapRequired(Key: "Version" , Val&: E.Version); |
1832 | IO.mapOptional(Key: "Feature" , Val&: E.Feature, Default: Hex8(0)); |
1833 | IO.mapOptional(Key: "NumBBRanges" , Val&: E.NumBBRanges); |
1834 | IO.mapOptional(Key: "BBRanges" , Val&: E.BBRanges); |
1835 | } |
1836 | |
1837 | void MappingTraits<ELFYAML::BBAddrMapEntry::BBRangeEntry>::mapping( |
1838 | IO &IO, ELFYAML::BBAddrMapEntry::BBRangeEntry &E) { |
1839 | IO.mapOptional(Key: "BaseAddress" , Val&: E.BaseAddress, Default: Hex64(0)); |
1840 | IO.mapOptional(Key: "NumBlocks" , Val&: E.NumBlocks); |
1841 | IO.mapOptional(Key: "BBEntries" , Val&: E.BBEntries); |
1842 | } |
1843 | |
1844 | void MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry>::mapping( |
1845 | IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &E) { |
1846 | assert(IO.getContext() && "The IO context is not initialized" ); |
1847 | IO.mapOptional(Key: "ID" , Val&: E.ID); |
1848 | IO.mapRequired(Key: "AddressOffset" , Val&: E.AddressOffset); |
1849 | IO.mapRequired(Key: "Size" , Val&: E.Size); |
1850 | IO.mapRequired(Key: "Metadata" , Val&: E.Metadata); |
1851 | } |
1852 | |
1853 | void MappingTraits<ELFYAML::PGOAnalysisMapEntry>::mapping( |
1854 | IO &IO, ELFYAML::PGOAnalysisMapEntry &E) { |
1855 | assert(IO.getContext() && "The IO context is not initialized" ); |
1856 | IO.mapOptional(Key: "FuncEntryCount" , Val&: E.FuncEntryCount); |
1857 | IO.mapOptional(Key: "PGOBBEntries" , Val&: E.PGOBBEntries); |
1858 | } |
1859 | |
1860 | void MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry>::mapping( |
1861 | IO &IO, ELFYAML::PGOAnalysisMapEntry::PGOBBEntry &E) { |
1862 | assert(IO.getContext() && "The IO context is not initialized" ); |
1863 | IO.mapOptional(Key: "BBFreq" , Val&: E.BBFreq); |
1864 | IO.mapOptional(Key: "Successors" , Val&: E.Successors); |
1865 | } |
1866 | |
1867 | void MappingTraits<ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry>:: |
1868 | mapping(IO &IO, |
1869 | ELFYAML::PGOAnalysisMapEntry::PGOBBEntry::SuccessorEntry &E) { |
1870 | assert(IO.getContext() && "The IO context is not initialized" ); |
1871 | IO.mapRequired(Key: "ID" , Val&: E.ID); |
1872 | IO.mapRequired(Key: "BrProb" , Val&: E.BrProb); |
1873 | } |
1874 | |
1875 | void MappingTraits<ELFYAML::GnuHashHeader>::(IO &IO, |
1876 | ELFYAML::GnuHashHeader &E) { |
1877 | assert(IO.getContext() && "The IO context is not initialized" ); |
1878 | IO.mapOptional(Key: "NBuckets" , Val&: E.NBuckets); |
1879 | IO.mapRequired(Key: "SymNdx" , Val&: E.SymNdx); |
1880 | IO.mapOptional(Key: "MaskWords" , Val&: E.MaskWords); |
1881 | IO.mapRequired(Key: "Shift2" , Val&: E.Shift2); |
1882 | } |
1883 | |
1884 | void MappingTraits<ELFYAML::DynamicEntry>::mapping(IO &IO, |
1885 | ELFYAML::DynamicEntry &Rel) { |
1886 | assert(IO.getContext() && "The IO context is not initialized" ); |
1887 | |
1888 | IO.mapRequired(Key: "Tag" , Val&: Rel.Tag); |
1889 | IO.mapRequired(Key: "Value" , Val&: Rel.Val); |
1890 | } |
1891 | |
1892 | void MappingTraits<ELFYAML::NoteEntry>::mapping(IO &IO, ELFYAML::NoteEntry &N) { |
1893 | assert(IO.getContext() && "The IO context is not initialized" ); |
1894 | |
1895 | IO.mapOptional(Key: "Name" , Val&: N.Name); |
1896 | IO.mapOptional(Key: "Desc" , Val&: N.Desc); |
1897 | IO.mapRequired(Key: "Type" , Val&: N.Type); |
1898 | } |
1899 | |
1900 | void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO, |
1901 | ELFYAML::VerdefEntry &E) { |
1902 | assert(IO.getContext() && "The IO context is not initialized" ); |
1903 | |
1904 | IO.mapOptional(Key: "Version" , Val&: E.Version); |
1905 | IO.mapOptional(Key: "Flags" , Val&: E.Flags); |
1906 | IO.mapOptional(Key: "VersionNdx" , Val&: E.VersionNdx); |
1907 | IO.mapOptional(Key: "Hash" , Val&: E.Hash); |
1908 | IO.mapRequired(Key: "Names" , Val&: E.VerNames); |
1909 | } |
1910 | |
1911 | void MappingTraits<ELFYAML::VerneedEntry>::mapping(IO &IO, |
1912 | ELFYAML::VerneedEntry &E) { |
1913 | assert(IO.getContext() && "The IO context is not initialized" ); |
1914 | |
1915 | IO.mapRequired(Key: "Version" , Val&: E.Version); |
1916 | IO.mapRequired(Key: "File" , Val&: E.File); |
1917 | IO.mapRequired(Key: "Entries" , Val&: E.AuxV); |
1918 | } |
1919 | |
1920 | void MappingTraits<ELFYAML::VernauxEntry>::mapping(IO &IO, |
1921 | ELFYAML::VernauxEntry &E) { |
1922 | assert(IO.getContext() && "The IO context is not initialized" ); |
1923 | |
1924 | IO.mapRequired(Key: "Name" , Val&: E.Name); |
1925 | IO.mapRequired(Key: "Hash" , Val&: E.Hash); |
1926 | IO.mapRequired(Key: "Flags" , Val&: E.Flags); |
1927 | IO.mapRequired(Key: "Other" , Val&: E.Other); |
1928 | } |
1929 | |
1930 | void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO, |
1931 | ELFYAML::Relocation &Rel) { |
1932 | const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); |
1933 | assert(Object && "The IO context is not initialized" ); |
1934 | |
1935 | IO.mapOptional(Key: "Offset" , Val&: Rel.Offset, Default: (Hex64)0); |
1936 | IO.mapOptional(Key: "Symbol" , Val&: Rel.Symbol); |
1937 | |
1938 | if (Object->getMachine() == ELFYAML::ELF_EM(ELF::EM_MIPS) && |
1939 | Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) { |
1940 | MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key( |
1941 | IO, Rel.Type); |
1942 | IO.mapRequired(Key: "Type" , Val&: Key->Type); |
1943 | IO.mapOptional(Key: "Type2" , Val&: Key->Type2, Default: ELFYAML::ELF_REL(ELF::R_MIPS_NONE)); |
1944 | IO.mapOptional(Key: "Type3" , Val&: Key->Type3, Default: ELFYAML::ELF_REL(ELF::R_MIPS_NONE)); |
1945 | IO.mapOptional(Key: "SpecSym" , Val&: Key->SpecSym, Default: ELFYAML::ELF_RSS(ELF::RSS_UNDEF)); |
1946 | } else |
1947 | IO.mapRequired(Key: "Type" , Val&: Rel.Type); |
1948 | |
1949 | IO.mapOptional(Key: "Addend" , Val&: Rel.Addend, Default: (ELFYAML::YAMLIntUInt)0); |
1950 | } |
1951 | |
1952 | void MappingTraits<ELFYAML::ARMIndexTableEntry>::mapping( |
1953 | IO &IO, ELFYAML::ARMIndexTableEntry &E) { |
1954 | assert(IO.getContext() && "The IO context is not initialized" ); |
1955 | IO.mapRequired(Key: "Offset" , Val&: E.Offset); |
1956 | |
1957 | StringRef CantUnwind = "EXIDX_CANTUNWIND" ; |
1958 | if (IO.outputting() && (uint32_t)E.Value == ARM::EHABI::EXIDX_CANTUNWIND) |
1959 | IO.mapRequired(Key: "Value" , Val&: CantUnwind); |
1960 | else if (!IO.outputting() && getStringValue(IO, Key: "Value" ) == CantUnwind) |
1961 | E.Value = ARM::EHABI::EXIDX_CANTUNWIND; |
1962 | else |
1963 | IO.mapRequired(Key: "Value" , Val&: E.Value); |
1964 | } |
1965 | |
1966 | void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) { |
1967 | assert(!IO.getContext() && "The IO context is initialized already" ); |
1968 | IO.setContext(&Object); |
1969 | IO.mapTag(Tag: "!ELF" , Default: true); |
1970 | IO.mapRequired(Key: "FileHeader" , Val&: Object.Header); |
1971 | IO.mapOptional(Key: "ProgramHeaders" , Val&: Object.ProgramHeaders); |
1972 | IO.mapOptional(Key: "Sections" , Val&: Object.Chunks); |
1973 | IO.mapOptional(Key: "Symbols" , Val&: Object.Symbols); |
1974 | IO.mapOptional(Key: "DynamicSymbols" , Val&: Object.DynamicSymbols); |
1975 | IO.mapOptional(Key: "DWARF" , Val&: Object.DWARF); |
1976 | if (Object.DWARF) { |
1977 | Object.DWARF->IsLittleEndian = |
1978 | Object.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); |
1979 | Object.DWARF->Is64BitAddrSize = |
1980 | Object.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); |
1981 | } |
1982 | IO.setContext(nullptr); |
1983 | } |
1984 | |
1985 | void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO, |
1986 | ELFYAML::LinkerOption &Opt) { |
1987 | assert(IO.getContext() && "The IO context is not initialized" ); |
1988 | IO.mapRequired(Key: "Name" , Val&: Opt.Key); |
1989 | IO.mapRequired(Key: "Value" , Val&: Opt.Value); |
1990 | } |
1991 | |
1992 | void MappingTraits<ELFYAML::CallGraphEntryWeight>::mapping( |
1993 | IO &IO, ELFYAML::CallGraphEntryWeight &E) { |
1994 | assert(IO.getContext() && "The IO context is not initialized" ); |
1995 | IO.mapRequired(Key: "Weight" , Val&: E.Weight); |
1996 | } |
1997 | |
1998 | LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG) |
1999 | LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP) |
2000 | LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT) |
2001 | LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE) |
2002 | LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1) |
2003 | |
2004 | } // end namespace yaml |
2005 | |
2006 | } // end namespace llvm |
2007 | |