Bug Summary

File:build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/include/llvm/ObjectYAML/ELFYAML.h
Warning:line 55, column 1
The left operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ELFYAML.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-16/lib/clang/16.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/ObjectYAML -I /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/lib/ObjectYAML -I include -I /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-16/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-10-03-140002-15933-1 -x c++ /build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/lib/ObjectYAML/ELFYAML.cpp

/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/lib/ObjectYAML/ELFYAML.cpp

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

/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/include/llvm/ObjectYAML/ELFYAML.h

1//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
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/// \file
10/// This file declares classes for handling the YAML representation
11/// of ELF.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_OBJECTYAML_ELFYAML_H
16#define LLVM_OBJECTYAML_ELFYAML_H
17
18#include "llvm/ADT/StringRef.h"
19#include "llvm/BinaryFormat/ELF.h"
20#include "llvm/Object/ELFTypes.h"
21#include "llvm/ObjectYAML/DWARFYAML.h"
22#include "llvm/ObjectYAML/YAML.h"
23#include "llvm/Support/YAMLTraits.h"
24#include <cstdint>
25#include <memory>
26#include <vector>
27
28namespace llvm {
29namespace ELFYAML {
30
31StringRef dropUniqueSuffix(StringRef S);
32std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
33
34// These types are invariant across 32/64-bit ELF, so for simplicity just
35// directly give them their exact sizes. We don't need to worry about
36// endianness because these are just the types in the YAMLIO structures,
37// and are appropriately converted to the necessary endianness when
38// reading/generating binary object files.
39// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
40// the common prefix of the respective constants. E.g. ELF_EM corresponds
41// to the `e_machine` constants, like `EM_X86_64`.
42// In the future, these would probably be better suited by C++11 enum
43// class's with appropriate fixed underlying type.
44LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)struct ELF_ET { ELF_ET() = default; ELF_ET(const uint16_t v) :
value(v) {} ELF_ET(const ELF_ET &v) = default; ELF_ET &
operator=(const ELF_ET &rhs) = default; ELF_ET &operator
=(const uint16_t &rhs) { value = rhs; return *this; } operator
const uint16_t & () const { return value; } bool operator
==(const ELF_ET &rhs) const { return value == rhs.value; }
bool operator==(const uint16_t &rhs) const { return value
== rhs; } bool operator<(const ELF_ET &rhs) const { return
value < rhs.value; } uint16_t value; using BaseType = uint16_t
; };
45LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)struct ELF_PT { ELF_PT() = default; ELF_PT(const uint32_t v) :
value(v) {} ELF_PT(const ELF_PT &v) = default; ELF_PT &
operator=(const ELF_PT &rhs) = default; ELF_PT &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_PT &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_PT &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
46LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)struct ELF_EM { ELF_EM() = default; ELF_EM(const uint32_t v) :
value(v) {} ELF_EM(const ELF_EM &v) = default; ELF_EM &
operator=(const ELF_EM &rhs) = default; ELF_EM &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_EM &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_EM &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
47LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)struct ELF_ELFCLASS { ELF_ELFCLASS() = default; ELF_ELFCLASS(
const uint8_t v) : value(v) {} ELF_ELFCLASS(const ELF_ELFCLASS
&v) = default; ELF_ELFCLASS &operator=(const ELF_ELFCLASS
&rhs) = default; ELF_ELFCLASS &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const ELF_ELFCLASS
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFCLASS &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
48LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)struct ELF_ELFDATA { ELF_ELFDATA() = default; ELF_ELFDATA(const
uint8_t v) : value(v) {} ELF_ELFDATA(const ELF_ELFDATA &
v) = default; ELF_ELFDATA &operator=(const ELF_ELFDATA &
rhs) = default; ELF_ELFDATA &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const ELF_ELFDATA
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFDATA &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
49LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)struct ELF_ELFOSABI { ELF_ELFOSABI() = default; ELF_ELFOSABI(
const uint8_t v) : value(v) {} ELF_ELFOSABI(const ELF_ELFOSABI
&v) = default; ELF_ELFOSABI &operator=(const ELF_ELFOSABI
&rhs) = default; ELF_ELFOSABI &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const ELF_ELFOSABI
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const ELF_ELFOSABI &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
50// Just use 64, since it can hold 32-bit values too.
51LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)struct ELF_EF { ELF_EF() = default; ELF_EF(const uint64_t v) :
value(v) {} ELF_EF(const ELF_EF &v) = default; ELF_EF &
operator=(const ELF_EF &rhs) = default; ELF_EF &operator
=(const uint64_t &rhs) { value = rhs; return *this; } operator
const uint64_t & () const { return value; } bool operator
==(const ELF_EF &rhs) const { return value == rhs.value; }
bool operator==(const uint64_t &rhs) const { return value
== rhs; } bool operator<(const ELF_EF &rhs) const { return
value < rhs.value; } uint64_t value; using BaseType = uint64_t
; };
52// Just use 64, since it can hold 32-bit values too.
53LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)struct ELF_DYNTAG { ELF_DYNTAG() = default; ELF_DYNTAG(const uint64_t
v) : value(v) {} ELF_DYNTAG(const ELF_DYNTAG &v) = default
; ELF_DYNTAG &operator=(const ELF_DYNTAG &rhs) = default
; ELF_DYNTAG &operator=(const uint64_t &rhs) { value =
rhs; return *this; } operator const uint64_t & () const {
return value; } bool operator==(const ELF_DYNTAG &rhs) const
{ return value == rhs.value; } bool operator==(const uint64_t
&rhs) const { return value == rhs; } bool operator<(const
ELF_DYNTAG &rhs) const { return value < rhs.value; } uint64_t
value; using BaseType = uint64_t; };
54LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)struct ELF_PF { ELF_PF() = default; ELF_PF(const uint32_t v) :
value(v) {} ELF_PF(const ELF_PF &v) = default; ELF_PF &
operator=(const ELF_PF &rhs) = default; ELF_PF &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_PF &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_PF &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
55LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)struct ELF_SHT { ELF_SHT() = default; ELF_SHT(const uint32_t v
) : value(v) {} ELF_SHT(const ELF_SHT &v) = default; ELF_SHT
&operator=(const ELF_SHT &rhs) = default; ELF_SHT &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const ELF_SHT &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHT &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
2
Returning without writing to 'this->value'
21
The left operand of '==' is a garbage value
56LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)struct ELF_REL { ELF_REL() = default; ELF_REL(const uint32_t v
) : value(v) {} ELF_REL(const ELF_REL &v) = default; ELF_REL
&operator=(const ELF_REL &rhs) = default; ELF_REL &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const ELF_REL &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const ELF_REL &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
57LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)struct ELF_RSS { ELF_RSS() = default; ELF_RSS(const uint8_t v
) : value(v) {} ELF_RSS(const ELF_RSS &v) = default; ELF_RSS
&operator=(const ELF_RSS &rhs) = default; ELF_RSS &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_RSS &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_RSS &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
58// Just use 64, since it can hold 32-bit values too.
59LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)struct ELF_SHF { ELF_SHF() = default; ELF_SHF(const uint64_t v
) : value(v) {} ELF_SHF(const ELF_SHF &v) = default; ELF_SHF
&operator=(const ELF_SHF &rhs) = default; ELF_SHF &
operator=(const uint64_t &rhs) { value = rhs; return *this
; } operator const uint64_t & () const { return value; } bool
operator==(const ELF_SHF &rhs) const { return value == rhs
.value; } bool operator==(const uint64_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHF &rhs) const
{ return value < rhs.value; } uint64_t value; using BaseType
= uint64_t; };
60LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)struct ELF_SHN { ELF_SHN() = default; ELF_SHN(const uint16_t v
) : value(v) {} ELF_SHN(const ELF_SHN &v) = default; ELF_SHN
&operator=(const ELF_SHN &rhs) = default; ELF_SHN &
operator=(const uint16_t &rhs) { value = rhs; return *this
; } operator const uint16_t & () const { return value; } bool
operator==(const ELF_SHN &rhs) const { return value == rhs
.value; } bool operator==(const uint16_t &rhs) const { return
value == rhs; } bool operator<(const ELF_SHN &rhs) const
{ return value < rhs.value; } uint16_t value; using BaseType
= uint16_t; };
61LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)struct ELF_STB { ELF_STB() = default; ELF_STB(const uint8_t v
) : value(v) {} ELF_STB(const ELF_STB &v) = default; ELF_STB
&operator=(const ELF_STB &rhs) = default; ELF_STB &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_STB &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_STB &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
62LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)struct ELF_STT { ELF_STT() = default; ELF_STT(const uint8_t v
) : value(v) {} ELF_STT(const ELF_STT &v) = default; ELF_STT
&operator=(const ELF_STT &rhs) = default; ELF_STT &
operator=(const uint8_t &rhs) { value = rhs; return *this
; } operator const uint8_t & () const { return value; } bool
operator==(const ELF_STT &rhs) const { return value == rhs
.value; } bool operator==(const uint8_t &rhs) const { return
value == rhs; } bool operator<(const ELF_STT &rhs) const
{ return value < rhs.value; } uint8_t value; using BaseType
= uint8_t; };
63LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT)struct ELF_NT { ELF_NT() = default; ELF_NT(const uint32_t v) :
value(v) {} ELF_NT(const ELF_NT &v) = default; ELF_NT &
operator=(const ELF_NT &rhs) = default; ELF_NT &operator
=(const uint32_t &rhs) { value = rhs; return *this; } operator
const uint32_t & () const { return value; } bool operator
==(const ELF_NT &rhs) const { return value == rhs.value; }
bool operator==(const uint32_t &rhs) const { return value
== rhs; } bool operator<(const ELF_NT &rhs) const { return
value < rhs.value; } uint32_t value; using BaseType = uint32_t
; };
64
65LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)struct MIPS_AFL_REG { MIPS_AFL_REG() = default; MIPS_AFL_REG(
const uint8_t v) : value(v) {} MIPS_AFL_REG(const MIPS_AFL_REG
&v) = default; MIPS_AFL_REG &operator=(const MIPS_AFL_REG
&rhs) = default; MIPS_AFL_REG &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const MIPS_AFL_REG
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_REG &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
66LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)struct MIPS_ABI_FP { MIPS_ABI_FP() = default; MIPS_ABI_FP(const
uint8_t v) : value(v) {} MIPS_ABI_FP(const MIPS_ABI_FP &
v) = default; MIPS_ABI_FP &operator=(const MIPS_ABI_FP &
rhs) = default; MIPS_ABI_FP &operator=(const uint8_t &
rhs) { value = rhs; return *this; } operator const uint8_t &
() const { return value; } bool operator==(const MIPS_ABI_FP
&rhs) const { return value == rhs.value; } bool operator
==(const uint8_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_ABI_FP &rhs) const { return value
< rhs.value; } uint8_t value; using BaseType = uint8_t; }
;
67LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)struct MIPS_AFL_EXT { MIPS_AFL_EXT() = default; MIPS_AFL_EXT(
const uint32_t v) : value(v) {} MIPS_AFL_EXT(const MIPS_AFL_EXT
&v) = default; MIPS_AFL_EXT &operator=(const MIPS_AFL_EXT
&rhs) = default; MIPS_AFL_EXT &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_EXT
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_EXT &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
68LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)struct MIPS_AFL_ASE { MIPS_AFL_ASE() = default; MIPS_AFL_ASE(
const uint32_t v) : value(v) {} MIPS_AFL_ASE(const MIPS_AFL_ASE
&v) = default; MIPS_AFL_ASE &operator=(const MIPS_AFL_ASE
&rhs) = default; MIPS_AFL_ASE &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_ASE
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_ASE &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
69LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)struct MIPS_AFL_FLAGS1 { MIPS_AFL_FLAGS1() = default; MIPS_AFL_FLAGS1
(const uint32_t v) : value(v) {} MIPS_AFL_FLAGS1(const MIPS_AFL_FLAGS1
&v) = default; MIPS_AFL_FLAGS1 &operator=(const MIPS_AFL_FLAGS1
&rhs) = default; MIPS_AFL_FLAGS1 &operator=(const uint32_t
&rhs) { value = rhs; return *this; } operator const uint32_t
& () const { return value; } bool operator==(const MIPS_AFL_FLAGS1
&rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const MIPS_AFL_FLAGS1 &rhs) const { return value
< rhs.value; } uint32_t value; using BaseType = uint32_t;
};
70LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)struct MIPS_ISA { MIPS_ISA() = default; MIPS_ISA(const uint32_t
v) : value(v) {} MIPS_ISA(const MIPS_ISA &v) = default; MIPS_ISA
&operator=(const MIPS_ISA &rhs) = default; MIPS_ISA &
operator=(const uint32_t &rhs) { value = rhs; return *this
; } operator const uint32_t & () const { return value; } bool
operator==(const MIPS_ISA &rhs) const { return value == rhs
.value; } bool operator==(const uint32_t &rhs) const { return
value == rhs; } bool operator<(const MIPS_ISA &rhs) const
{ return value < rhs.value; } uint32_t value; using BaseType
= uint32_t; };
71
72LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)struct YAMLFlowString { YAMLFlowString() = default; YAMLFlowString
(const StringRef v) : value(v) {} YAMLFlowString(const YAMLFlowString
&v) = default; YAMLFlowString &operator=(const YAMLFlowString
&rhs) = default; YAMLFlowString &operator=(const StringRef
&rhs) { value = rhs; return *this; } operator const StringRef
& () const { return value; } bool operator==(const YAMLFlowString
&rhs) const { return value == rhs.value; } bool operator
==(const StringRef &rhs) const { return value == rhs; } bool
operator<(const YAMLFlowString &rhs) const { return value
< rhs.value; } StringRef value; using BaseType = StringRef
; };
73LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)struct YAMLIntUInt { YAMLIntUInt() = default; YAMLIntUInt(const
int64_t v) : value(v) {} YAMLIntUInt(const YAMLIntUInt &
v) = default; YAMLIntUInt &operator=(const YAMLIntUInt &
rhs) = default; YAMLIntUInt &operator=(const int64_t &
rhs) { value = rhs; return *this; } operator const int64_t &
() const { return value; } bool operator==(const YAMLIntUInt
&rhs) const { return value == rhs.value; } bool operator
==(const int64_t &rhs) const { return value == rhs; } bool
operator<(const YAMLIntUInt &rhs) const { return value
< rhs.value; } int64_t value; using BaseType = int64_t; }
;
74
75template <class ELFT>
76unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
77 StringRef SecName) {
78 if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
79 return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
80
81 switch (SecType) {
82 case ELF::SHT_SYMTAB:
83 case ELF::SHT_DYNSYM:
84 return sizeof(typename ELFT::Sym);
85 case ELF::SHT_GROUP:
86 return sizeof(typename ELFT::Word);
87 case ELF::SHT_REL:
88 return sizeof(typename ELFT::Rel);
89 case ELF::SHT_RELA:
90 return sizeof(typename ELFT::Rela);
91 case ELF::SHT_RELR:
92 return sizeof(typename ELFT::Relr);
93 case ELF::SHT_DYNAMIC:
94 return sizeof(typename ELFT::Dyn);
95 case ELF::SHT_HASH:
96 return sizeof(typename ELFT::Word);
97 case ELF::SHT_SYMTAB_SHNDX:
98 return sizeof(typename ELFT::Word);
99 case ELF::SHT_GNU_versym:
100 return sizeof(typename ELFT::Half);
101 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
102 return sizeof(object::Elf_CGProfile_Impl<ELFT>);
103 default:
104 if (SecName == ".debug_str")
105 return 1;
106 return 0;
107 }
108}
109
110// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
111// since 64-bit can hold 32-bit values too.
112struct FileHeader {
113 ELF_ELFCLASS Class;
114 ELF_ELFDATA Data;
115 ELF_ELFOSABI OSABI;
116 llvm::yaml::Hex8 ABIVersion;
117 ELF_ET Type;
118 Optional<ELF_EM> Machine;
119 ELF_EF Flags;
120 llvm::yaml::Hex64 Entry;
121 Optional<StringRef> SectionHeaderStringTable;
122
123 Optional<llvm::yaml::Hex64> EPhOff;
124 Optional<llvm::yaml::Hex16> EPhEntSize;
125 Optional<llvm::yaml::Hex16> EPhNum;
126 Optional<llvm::yaml::Hex16> EShEntSize;
127 Optional<llvm::yaml::Hex64> EShOff;
128 Optional<llvm::yaml::Hex16> EShNum;
129 Optional<llvm::yaml::Hex16> EShStrNdx;
130};
131
132struct SectionHeader {
133 StringRef Name;
134};
135
136struct Symbol {
137 StringRef Name;
138 ELF_STT Type;
139 Optional<StringRef> Section;
140 Optional<ELF_SHN> Index;
141 ELF_STB Binding;
142 Optional<llvm::yaml::Hex64> Value;
143 Optional<llvm::yaml::Hex64> Size;
144 Optional<uint8_t> Other;
145
146 Optional<uint32_t> StName;
147};
148
149struct SectionOrType {
150 StringRef sectionNameOrType;
151};
152
153struct DynamicEntry {
154 ELF_DYNTAG Tag;
155 llvm::yaml::Hex64 Val;
156};
157
158struct BBAddrMapEntry {
159 struct BBEntry {
160 llvm::yaml::Hex64 AddressOffset;
161 llvm::yaml::Hex64 Size;
162 llvm::yaml::Hex64 Metadata;
163 };
164 uint8_t Version;
165 llvm::yaml::Hex8 Feature;
166 llvm::yaml::Hex64 Address;
167 Optional<uint64_t> NumBlocks;
168 Optional<std::vector<BBEntry>> BBEntries;
169};
170
171struct StackSizeEntry {
172 llvm::yaml::Hex64 Address;
173 llvm::yaml::Hex64 Size;
174};
175
176struct NoteEntry {
177 StringRef Name;
178 yaml::BinaryRef Desc;
179 ELF_NT Type;
180};
181
182struct Chunk {
183 enum class ChunkKind {
184 Dynamic,
185 Group,
186 RawContent,
187 Relocation,
188 Relr,
189 NoBits,
190 Note,
191 Hash,
192 GnuHash,
193 Verdef,
194 Verneed,
195 StackSizes,
196 SymtabShndxSection,
197 Symver,
198 ARMIndexTable,
199 MipsABIFlags,
200 Addrsig,
201 LinkerOptions,
202 DependentLibraries,
203 CallGraphProfile,
204 BBAddrMap,
205
206 // Special chunks.
207 SpecialChunksStart,
208 Fill = SpecialChunksStart,
209 SectionHeaderTable,
210 };
211
212 ChunkKind Kind;
213 StringRef Name;
214 Optional<llvm::yaml::Hex64> Offset;
215
216 // Usually chunks are not created implicitly, but rather loaded from YAML.
217 // This flag is used to signal whether this is the case or not.
218 bool IsImplicit;
219
220 Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
221 virtual ~Chunk();
222};
223
224struct Section : public Chunk {
225 ELF_SHT Type;
226 Optional<ELF_SHF> Flags;
227 Optional<llvm::yaml::Hex64> Address;
228 Optional<StringRef> Link;
229 llvm::yaml::Hex64 AddressAlign;
230 Optional<llvm::yaml::Hex64> EntSize;
231
232 Optional<yaml::BinaryRef> Content;
233 Optional<llvm::yaml::Hex64> Size;
234
235 // Holds the original section index.
236 unsigned OriginalSecNdx;
237
238 Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
239
240 static bool classof(const Chunk *S) {
241 return S->Kind < ChunkKind::SpecialChunksStart;
242 }
243
244 // Some derived sections might have their own special entries. This method
245 // returns a vector of <entry name, is used> pairs. It is used for section
246 // validation.
247 virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
248 return {};
249 };
250
251 // The following members are used to override section fields which is
252 // useful for creating invalid objects.
253
254 // This can be used to override the sh_addralign field.
255 Optional<llvm::yaml::Hex64> ShAddrAlign;
256
257 // This can be used to override the offset stored in the sh_name field.
258 // It does not affect the name stored in the string table.
259 Optional<llvm::yaml::Hex64> ShName;
260
261 // This can be used to override the sh_offset field. It does not place the
262 // section data at the offset specified.
263 Optional<llvm::yaml::Hex64> ShOffset;
264
265 // This can be used to override the sh_size field. It does not affect the
266 // content written.
267 Optional<llvm::yaml::Hex64> ShSize;
268
269 // This can be used to override the sh_flags field.
270 Optional<llvm::yaml::Hex64> ShFlags;
271
272 // This can be used to override the sh_type field. It is useful when we
273 // want to use specific YAML keys for a section of a particular type to
274 // describe the content, but still want to have a different final type
275 // for the section.
276 Optional<ELF_SHT> ShType;
277};
278
279// Fill is a block of data which is placed outside of sections. It is
280// not present in the sections header table, but it might affect the output file
281// size and program headers produced.
282struct Fill : Chunk {
283 Optional<yaml::BinaryRef> Pattern;
284 llvm::yaml::Hex64 Size;
285
286 Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
287
288 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
289};
290
291struct SectionHeaderTable : Chunk {
292 SectionHeaderTable(bool IsImplicit)
293 : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
294
295 static bool classof(const Chunk *S) {
296 return S->Kind == ChunkKind::SectionHeaderTable;
297 }
298
299 Optional<std::vector<SectionHeader>> Sections;
300 Optional<std::vector<SectionHeader>> Excluded;
301 Optional<bool> NoHeaders;
302
303 size_t getNumHeaders(size_t SectionsNum) const {
304 if (IsImplicit || isDefault())
305 return SectionsNum;
306 if (NoHeaders)
307 return (*NoHeaders) ? 0 : SectionsNum;
308 return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
309 }
310
311 bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
312
313 static constexpr StringRef TypeStr = "SectionHeaderTable";
314};
315
316struct BBAddrMapSection : Section {
317 Optional<std::vector<BBAddrMapEntry>> Entries;
318
319 BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
320
321 std::vector<std::pair<StringRef, bool>> getEntries() const override {
322 return {{"Entries", Entries.has_value()}};
323 };
324
325 static bool classof(const Chunk *S) {
326 return S->Kind == ChunkKind::BBAddrMap;
327 }
328};
329
330struct StackSizesSection : Section {
331 Optional<std::vector<StackSizeEntry>> Entries;
332
333 StackSizesSection() : Section(ChunkKind::StackSizes) {}
334
335 std::vector<std::pair<StringRef, bool>> getEntries() const override {
336 return {{"Entries", Entries.has_value()}};
337 };
338
339 static bool classof(const Chunk *S) {
340 return S->Kind == ChunkKind::StackSizes;
341 }
342
343 static bool nameMatches(StringRef Name) {
344 return Name == ".stack_sizes";
345 }
346};
347
348struct DynamicSection : Section {
349 Optional<std::vector<DynamicEntry>> Entries;
350
351 DynamicSection() : Section(ChunkKind::Dynamic) {}
352
353 std::vector<std::pair<StringRef, bool>> getEntries() const override {
354 return {{"Entries", Entries.has_value()}};
355 };
356
357 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
358};
359
360struct RawContentSection : Section {
361 Optional<llvm::yaml::Hex64> Info;
362
363 RawContentSection() : Section(ChunkKind::RawContent) {}
364
365 static bool classof(const Chunk *S) {
366 return S->Kind == ChunkKind::RawContent;
367 }
368
369 // Is used when a content is read as an array of bytes.
370 Optional<std::vector<uint8_t>> ContentBuf;
371};
372
373struct NoBitsSection : Section {
374 NoBitsSection() : Section(ChunkKind::NoBits) {}
375
376 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
377};
378
379struct NoteSection : Section {
380 Optional<std::vector<ELFYAML::NoteEntry>> Notes;
381
382 NoteSection() : Section(ChunkKind::Note) {}
383
384 std::vector<std::pair<StringRef, bool>> getEntries() const override {
385 return {{"Notes", Notes.has_value()}};
386 };
387
388 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
389};
390
391struct HashSection : Section {
392 Optional<std::vector<uint32_t>> Bucket;
393 Optional<std::vector<uint32_t>> Chain;
394
395 std::vector<std::pair<StringRef, bool>> getEntries() const override {
396 return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
397 };
398
399 // The following members are used to override section fields.
400 // This is useful for creating invalid objects.
401 Optional<llvm::yaml::Hex64> NBucket;
402 Optional<llvm::yaml::Hex64> NChain;
403
404 HashSection() : Section(ChunkKind::Hash) {}
405
406 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
407};
408
409struct GnuHashHeader {
410 // The number of hash buckets.
411 // Not used when dumping the object, but can be used to override
412 // the real number of buckets when emiting an object from a YAML document.
413 Optional<llvm::yaml::Hex32> NBuckets;
414
415 // Index of the first symbol in the dynamic symbol table
416 // included in the hash table.
417 llvm::yaml::Hex32 SymNdx;
418
419 // The number of words in the Bloom filter.
420 // Not used when dumping the object, but can be used to override the real
421 // number of words in the Bloom filter when emiting an object from a YAML
422 // document.
423 Optional<llvm::yaml::Hex32> MaskWords;
424
425 // A shift constant used by the Bloom filter.
426 llvm::yaml::Hex32 Shift2;
427};
428
429struct GnuHashSection : Section {
430 Optional<GnuHashHeader> Header;
431 Optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
432 Optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
433 Optional<std::vector<llvm::yaml::Hex32>> HashValues;
434
435 GnuHashSection() : Section(ChunkKind::GnuHash) {}
436
437 std::vector<std::pair<StringRef, bool>> getEntries() const override {
438 return {{"Header", Header.has_value()},
439 {"BloomFilter", BloomFilter.has_value()},
440 {"HashBuckets", HashBuckets.has_value()},
441 {"HashValues", HashValues.has_value()}};
442 };
443
444 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
445};
446
447struct VernauxEntry {
448 uint32_t Hash;
449 uint16_t Flags;
450 uint16_t Other;
451 StringRef Name;
452};
453
454struct VerneedEntry {
455 uint16_t Version;
456 StringRef File;
457 std::vector<VernauxEntry> AuxV;
458};
459
460struct VerneedSection : Section {
461 Optional<std::vector<VerneedEntry>> VerneedV;
462 Optional<llvm::yaml::Hex64> Info;
463
464 VerneedSection() : Section(ChunkKind::Verneed) {}
465
466 std::vector<std::pair<StringRef, bool>> getEntries() const override {
467 return {{"Dependencies", VerneedV.has_value()}};
468 };
469
470 static bool classof(const Chunk *S) {
471 return S->Kind == ChunkKind::Verneed;
472 }
473};
474
475struct AddrsigSection : Section {
476 Optional<std::vector<YAMLFlowString>> Symbols;
477
478 AddrsigSection() : Section(ChunkKind::Addrsig) {}
479
480 std::vector<std::pair<StringRef, bool>> getEntries() const override {
481 return {{"Symbols", Symbols.has_value()}};
482 };
483
484 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
485};
486
487struct LinkerOption {
488 StringRef Key;
489 StringRef Value;
490};
491
492struct LinkerOptionsSection : Section {
493 Optional<std::vector<LinkerOption>> Options;
494
495 LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
496
497 std::vector<std::pair<StringRef, bool>> getEntries() const override {
498 return {{"Options", Options.has_value()}};
499 };
500
501 static bool classof(const Chunk *S) {
502 return S->Kind == ChunkKind::LinkerOptions;
503 }
504};
505
506struct DependentLibrariesSection : Section {
507 Optional<std::vector<YAMLFlowString>> Libs;
508
509 DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
510
511 std::vector<std::pair<StringRef, bool>> getEntries() const override {
512 return {{"Libraries", Libs.has_value()}};
513 };
514
515 static bool classof(const Chunk *S) {
516 return S->Kind == ChunkKind::DependentLibraries;
517 }
518};
519
520// Represents the call graph profile section entry.
521struct CallGraphEntryWeight {
522 // The weight of the edge.
523 uint64_t Weight;
524};
525
526struct CallGraphProfileSection : Section {
527 Optional<std::vector<CallGraphEntryWeight>> Entries;
528
529 CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
530
531 std::vector<std::pair<StringRef, bool>> getEntries() const override {
532 return {{"Entries", Entries.has_value()}};
533 };
534
535 static bool classof(const Chunk *S) {
536 return S->Kind == ChunkKind::CallGraphProfile;
537 }
538};
539
540struct SymverSection : Section {
541 Optional<std::vector<uint16_t>> Entries;
542
543 SymverSection() : Section(ChunkKind::Symver) {}
544
545 std::vector<std::pair<StringRef, bool>> getEntries() const override {
546 return {{"Entries", Entries.has_value()}};
547 };
548
549 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
550};
551
552struct VerdefEntry {
553 Optional<uint16_t> Version;
554 Optional<uint16_t> Flags;
555 Optional<uint16_t> VersionNdx;
556 Optional<uint32_t> Hash;
557 std::vector<StringRef> VerNames;
558};
559
560struct VerdefSection : Section {
561 Optional<std::vector<VerdefEntry>> Entries;
562 Optional<llvm::yaml::Hex64> Info;
563
564 VerdefSection() : Section(ChunkKind::Verdef) {}
565
566 std::vector<std::pair<StringRef, bool>> getEntries() const override {
567 return {{"Entries", Entries.has_value()}};
568 };
569
570 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
571};
572
573struct GroupSection : Section {
574 // Members of a group contain a flag and a list of section indices
575 // that are part of the group.
576 Optional<std::vector<SectionOrType>> Members;
577 Optional<StringRef> Signature; /* Info */
578
579 GroupSection() : Section(ChunkKind::Group) {}
580
581 std::vector<std::pair<StringRef, bool>> getEntries() const override {
582 return {{"Members", Members.has_value()}};
583 };
584
585 static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
586};
587
588struct Relocation {
589 llvm::yaml::Hex64 Offset;
590 YAMLIntUInt Addend;
591 ELF_REL Type;
592 Optional<StringRef> Symbol;
593};
594
595struct RelocationSection : Section {
596 Optional<std::vector<Relocation>> Relocations;
597 StringRef RelocatableSec; /* Info */
598
599 RelocationSection() : Section(ChunkKind::Relocation) {}
600
601 std::vector<std::pair<StringRef, bool>> getEntries() const override {
602 return {{"Relocations", Relocations.has_value()}};
603 };
604
605 static bool classof(const Chunk *S) {
606 return S->Kind == ChunkKind::Relocation;
607 }
608};
609
610struct RelrSection : Section {
611 Optional<std::vector<llvm::yaml::Hex64>> Entries;
612
613 RelrSection() : Section(ChunkKind::Relr) {}
614
615 std::vector<std::pair<StringRef, bool>> getEntries() const override {
616 return {{"Entries", Entries.has_value()}};
617 };
618
619 static bool classof(const Chunk *S) {
620 return S->Kind == ChunkKind::Relr;
621 }
622};
623
624struct SymtabShndxSection : Section {
625 Optional<std::vector<uint32_t>> Entries;
626
627 SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
628
629 std::vector<std::pair<StringRef, bool>> getEntries() const override {
630 return {{"Entries", Entries.has_value()}};
631 };
632
633 static bool classof(const Chunk *S) {
634 return S->Kind == ChunkKind::SymtabShndxSection;
635 }
636};
637
638struct ARMIndexTableEntry {
639 llvm::yaml::Hex32 Offset;
640 llvm::yaml::Hex32 Value;
641};
642
643struct ARMIndexTableSection : Section {
644 Optional<std::vector<ARMIndexTableEntry>> Entries;
645
646 ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
647
648 std::vector<std::pair<StringRef, bool>> getEntries() const override {
649 return {{"Entries", Entries.has_value()}};
650 };
651
652 static bool classof(const Chunk *S) {
653 return S->Kind == ChunkKind::ARMIndexTable;
654 }
655};
656
657// Represents .MIPS.abiflags section
658struct MipsABIFlags : Section {
659 llvm::yaml::Hex16 Version;
660 MIPS_ISA ISALevel;
661 llvm::yaml::Hex8 ISARevision;
662 MIPS_AFL_REG GPRSize;
663 MIPS_AFL_REG CPR1Size;
664 MIPS_AFL_REG CPR2Size;
665 MIPS_ABI_FP FpABI;
666 MIPS_AFL_EXT ISAExtension;
667 MIPS_AFL_ASE ASEs;
668 MIPS_AFL_FLAGS1 Flags1;
669 llvm::yaml::Hex32 Flags2;
670
671 MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
672
673 static bool classof(const Chunk *S) {
674 return S->Kind == ChunkKind::MipsABIFlags;
675 }
676};
677
678struct ProgramHeader {
679 ELF_PT Type;
680 ELF_PF Flags;
681 llvm::yaml::Hex64 VAddr;
682 llvm::yaml::Hex64 PAddr;
683 Optional<llvm::yaml::Hex64> Align;
684 Optional<llvm::yaml::Hex64> FileSize;
685 Optional<llvm::yaml::Hex64> MemSize;
686 Optional<llvm::yaml::Hex64> Offset;
687 Optional<StringRef> FirstSec;
688 Optional<StringRef> LastSec;
689
690 // This vector contains all chunks from [FirstSec, LastSec].
691 std::vector<Chunk *> Chunks;
692};
693
694struct Object {
695 FileHeader Header;
696 std::vector<ProgramHeader> ProgramHeaders;
697
698 // An object might contain output section descriptions as well as
699 // custom data that does not belong to any section.
700 std::vector<std::unique_ptr<Chunk>> Chunks;
701
702 // Although in reality the symbols reside in a section, it is a lot
703 // cleaner and nicer if we read them from the YAML as a separate
704 // top-level key, which automatically ensures that invariants like there
705 // being a single SHT_SYMTAB section are upheld.
706 Optional<std::vector<Symbol>> Symbols;
707 Optional<std::vector<Symbol>> DynamicSymbols;
708 Optional<DWARFYAML::Data> DWARF;
709
710 std::vector<Section *> getSections() {
711 std::vector<Section *> Ret;
712 for (const std::unique_ptr<Chunk> &Sec : Chunks)
713 if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
714 Ret.push_back(S);
715 return Ret;
716 }
717
718 const SectionHeaderTable &getSectionHeaderTable() const {
719 for (const std::unique_ptr<Chunk> &C : Chunks)
720 if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
721 return *S;
722 llvm_unreachable("the section header table chunk must always be present")::llvm::llvm_unreachable_internal("the section header table chunk must always be present"
, "llvm/include/llvm/ObjectYAML/ELFYAML.h", 722)
;
723 }
724
725 ELF_ELFOSABI getOSAbi() const;
726 unsigned getMachine() const;
727};
728
729bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
730 const NoBitsSection &S);
731
732} // end namespace ELFYAML
733} // end namespace llvm
734
735LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::StackSizeEntry>::value && !std::
is_same<llvm::ELFYAML::StackSizeEntry, std::string>::value
&& !std::is_same<llvm::ELFYAML::StackSizeEntry, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::StackSizeEntry> { static const bool flow = false; }; } }
736LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::BBAddrMapEntry>::value && !std::
is_same<llvm::ELFYAML::BBAddrMapEntry, std::string>::value
&& !std::is_same<llvm::ELFYAML::BBAddrMapEntry, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::BBAddrMapEntry> { static const bool flow = false; }; } }
737LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::BBAddrMapEntry::BBEntry>::value &&
!std::is_same<llvm::ELFYAML::BBAddrMapEntry::BBEntry, std
::string>::value && !std::is_same<llvm::ELFYAML
::BBAddrMapEntry::BBEntry, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::BBAddrMapEntry::BBEntry> { static const bool flow = false
; }; } }
738LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::DynamicEntry>::value && !std::is_same
<llvm::ELFYAML::DynamicEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::DynamicEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::DynamicEntry> { static const bool flow = false; }; } }
739LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::LinkerOption>::value && !std::is_same
<llvm::ELFYAML::LinkerOption, std::string>::value &&
!std::is_same<llvm::ELFYAML::LinkerOption, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::LinkerOption> { static const bool flow = false; }; } }
740LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::CallGraphEntryWeight>::value &&
!std::is_same<llvm::ELFYAML::CallGraphEntryWeight, std::string
>::value && !std::is_same<llvm::ELFYAML::CallGraphEntryWeight
, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::CallGraphEntryWeight> { static const bool flow = false; }
; } }
741LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::NoteEntry>::value && !std::is_same
<llvm::ELFYAML::NoteEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::NoteEntry, llvm::StringRef>
::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::NoteEntry> { static const bool flow = false; }; } }
742LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::ProgramHeader>::value && !std::
is_same<llvm::ELFYAML::ProgramHeader, std::string>::value
&& !std::is_same<llvm::ELFYAML::ProgramHeader, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ProgramHeader> { static const bool flow = false; }; } }
743LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::SectionHeader>::value && !std::
is_same<llvm::ELFYAML::SectionHeader, std::string>::value
&& !std::is_same<llvm::ELFYAML::SectionHeader, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionHeader> { static const bool flow = false; }; } }
744LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<std::unique_ptr<llvm::ELFYAML::Chunk> >::value &&
!std::is_same<std::unique_ptr<llvm::ELFYAML::Chunk>
, std::string>::value && !std::is_same<std::unique_ptr
<llvm::ELFYAML::Chunk>, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<std::unique_ptr
<llvm::ELFYAML::Chunk> > { static const bool flow = false
; }; } }
745LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::Symbol>::value && !std::is_same
<llvm::ELFYAML::Symbol, std::string>::value && !
std::is_same<llvm::ELFYAML::Symbol, llvm::StringRef>::value
, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Symbol> { static const bool flow = false; }; } }
746LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VerdefEntry>::value && !std::is_same
<llvm::ELFYAML::VerdefEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VerdefEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerdefEntry> { static const bool flow = false; }; } }
747LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VernauxEntry>::value && !std::is_same
<llvm::ELFYAML::VernauxEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VernauxEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VernauxEntry> { static const bool flow = false; }; } }
748LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::VerneedEntry>::value && !std::is_same
<llvm::ELFYAML::VerneedEntry, std::string>::value &&
!std::is_same<llvm::ELFYAML::VerneedEntry, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::VerneedEntry> { static const bool flow = false; }; } }
749LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::Relocation>::value && !std::is_same
<llvm::ELFYAML::Relocation, std::string>::value &&
!std::is_same<llvm::ELFYAML::Relocation, llvm::StringRef>
::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::Relocation> { static const bool flow = false; }; } }
750LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::SectionOrType>::value && !std::
is_same<llvm::ELFYAML::SectionOrType, std::string>::value
&& !std::is_same<llvm::ELFYAML::SectionOrType, llvm
::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::SectionOrType> { static const bool flow = false; }; } }
751LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::ELFYAML::ARMIndexTableEntry>::value && !
std::is_same<llvm::ELFYAML::ARMIndexTableEntry, std::string
>::value && !std::is_same<llvm::ELFYAML::ARMIndexTableEntry
, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::ELFYAML
::ARMIndexTableEntry> { static const bool flow = false; };
} }
752
753namespace llvm {
754namespace yaml {
755
756template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
757 static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
758 raw_ostream &Out);
759 static StringRef input(StringRef Scalar, void *Ctx,
760 ELFYAML::YAMLIntUInt &Val);
761 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
762};
763
764template <>
765struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
766 static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
767};
768
769template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
770 static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
771};
772
773template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
774 static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
775};
776
777template <>
778struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
779 static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
780};
781
782template <>
783struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
784 static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
785};
786
787template <>
788struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
789 static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
790};
791
792template <>
793struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
794 static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
795};
796
797template <>
798struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
799 static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
800};
801
802template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
803 static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
804};
805
806template <>
807struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
808 static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
809};
810
811template <>
812struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
813 static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
814};
815
816template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
817 static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
818};
819
820template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
821 static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
822};
823
824template <>
825struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
826 static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
827};
828
829template <>
830struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
831 static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
832};
833
834template <>
835struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
836 static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
837};
838
839template <>
840struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
841 static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
842};
843
844template <>
845struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
846 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
847};
848
849template <>
850struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
851 static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
852};
853
854template <>
855struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
856 static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
857};
858
859template <>
860struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
861 static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
862};
863
864template <>
865struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
866 static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
867};
868
869template <>
870struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
871 static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
872};
873
874template <>
875struct MappingTraits<ELFYAML::FileHeader> {
876 static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
877};
878
879template <> struct MappingTraits<ELFYAML::SectionHeader> {
880 static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
881};
882
883template <> struct MappingTraits<ELFYAML::ProgramHeader> {
884 static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
885 static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
886};
887
888template <>
889struct MappingTraits<ELFYAML::Symbol> {
890 static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
891 static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
892};
893
894template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
895 static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
896};
897
898template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
899 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
900};
901
902template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
903 static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
904};
905
906template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
907 static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
908};
909
910template <> struct MappingTraits<ELFYAML::DynamicEntry> {
911 static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
912};
913
914template <> struct MappingTraits<ELFYAML::NoteEntry> {
915 static void mapping(IO &IO, ELFYAML::NoteEntry &N);
916};
917
918template <> struct MappingTraits<ELFYAML::VerdefEntry> {
919 static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
920};
921
922template <> struct MappingTraits<ELFYAML::VerneedEntry> {
923 static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
924};
925
926template <> struct MappingTraits<ELFYAML::VernauxEntry> {
927 static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
928};
929
930template <> struct MappingTraits<ELFYAML::LinkerOption> {
931 static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
932};
933
934template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
935 static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
936};
937
938template <> struct MappingTraits<ELFYAML::Relocation> {
939 static void mapping(IO &IO, ELFYAML::Relocation &Rel);
940};
941
942template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
943 static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
944};
945
946template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
947 static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
948 static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
949};
950
951template <>
952struct MappingTraits<ELFYAML::Object> {
953 static void mapping(IO &IO, ELFYAML::Object &Object);
954};
955
956template <> struct MappingTraits<ELFYAML::SectionOrType> {
957 static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
958};
959
960} // end namespace yaml
961} // end namespace llvm
962
963#endif // LLVM_OBJECTYAML_ELFYAML_H

/build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/include/llvm/Support/YAMLTraits.h

1//===- llvm/Support/YAMLTraits.h --------------------------------*- C++ -*-===//
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#ifndef LLVM_SUPPORT_YAMLTRAITS_H
10#define LLVM_SUPPORT_YAMLTRAITS_H
11
12#include "llvm/ADT/BitVector.h"
13#include "llvm/ADT/Optional.h"
14#include "llvm/ADT/SmallVector.h"
15#include "llvm/ADT/StringExtras.h"
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/Twine.h"
19#include "llvm/Support/AlignOf.h"
20#include "llvm/Support/Allocator.h"
21#include "llvm/Support/Endian.h"
22#include "llvm/Support/SMLoc.h"
23#include "llvm/Support/SourceMgr.h"
24#include "llvm/Support/YAMLParser.h"
25#include "llvm/Support/raw_ostream.h"
26#include <cassert>
27#include <map>
28#include <memory>
29#include <new>
30#include <string>
31#include <system_error>
32#include <type_traits>
33#include <vector>
34
35namespace llvm {
36
37class VersionTuple;
38
39namespace yaml {
40
41enum class NodeKind : uint8_t {
42 Scalar,
43 Map,
44 Sequence,
45};
46
47struct EmptyContext {};
48
49/// This class should be specialized by any type that needs to be converted
50/// to/from a YAML mapping. For example:
51///
52/// struct MappingTraits<MyStruct> {
53/// static void mapping(IO &io, MyStruct &s) {
54/// io.mapRequired("name", s.name);
55/// io.mapRequired("size", s.size);
56/// io.mapOptional("age", s.age);
57/// }
58/// };
59template<class T>
60struct MappingTraits {
61 // Must provide:
62 // static void mapping(IO &io, T &fields);
63 // Optionally may provide:
64 // static std::string validate(IO &io, T &fields);
65 // static void enumInput(IO &io, T &value);
66 //
67 // The optional flow flag will cause generated YAML to use a flow mapping
68 // (e.g. { a: 0, b: 1 }):
69 // static const bool flow = true;
70};
71
72/// This class is similar to MappingTraits<T> but allows you to pass in
73/// additional context for each map operation. For example:
74///
75/// struct MappingContextTraits<MyStruct, MyContext> {
76/// static void mapping(IO &io, MyStruct &s, MyContext &c) {
77/// io.mapRequired("name", s.name);
78/// io.mapRequired("size", s.size);
79/// io.mapOptional("age", s.age);
80/// ++c.TimesMapped;
81/// }
82/// };
83template <class T, class Context> struct MappingContextTraits {
84 // Must provide:
85 // static void mapping(IO &io, T &fields, Context &Ctx);
86 // Optionally may provide:
87 // static std::string validate(IO &io, T &fields, Context &Ctx);
88 //
89 // The optional flow flag will cause generated YAML to use a flow mapping
90 // (e.g. { a: 0, b: 1 }):
91 // static const bool flow = true;
92};
93
94/// This class should be specialized by any integral type that converts
95/// to/from a YAML scalar where there is a one-to-one mapping between
96/// in-memory values and a string in YAML. For example:
97///
98/// struct ScalarEnumerationTraits<Colors> {
99/// static void enumeration(IO &io, Colors &value) {
100/// io.enumCase(value, "red", cRed);
101/// io.enumCase(value, "blue", cBlue);
102/// io.enumCase(value, "green", cGreen);
103/// }
104/// };
105template <typename T, typename Enable = void> struct ScalarEnumerationTraits {
106 // Must provide:
107 // static void enumeration(IO &io, T &value);
108};
109
110/// This class should be specialized by any integer type that is a union
111/// of bit values and the YAML representation is a flow sequence of
112/// strings. For example:
113///
114/// struct ScalarBitSetTraits<MyFlags> {
115/// static void bitset(IO &io, MyFlags &value) {
116/// io.bitSetCase(value, "big", flagBig);
117/// io.bitSetCase(value, "flat", flagFlat);
118/// io.bitSetCase(value, "round", flagRound);
119/// }
120/// };
121template <typename T, typename Enable = void> struct ScalarBitSetTraits {
122 // Must provide:
123 // static void bitset(IO &io, T &value);
124};
125
126/// Describe which type of quotes should be used when quoting is necessary.
127/// Some non-printable characters need to be double-quoted, while some others
128/// are fine with simple-quoting, and some don't need any quoting.
129enum class QuotingType { None, Single, Double };
130
131/// This class should be specialized by type that requires custom conversion
132/// to/from a yaml scalar. For example:
133///
134/// template<>
135/// struct ScalarTraits<MyType> {
136/// static void output(const MyType &val, void*, llvm::raw_ostream &out) {
137/// // stream out custom formatting
138/// out << llvm::format("%x", val);
139/// }
140/// static StringRef input(StringRef scalar, void*, MyType &value) {
141/// // parse scalar and set `value`
142/// // return empty string on success, or error string
143/// return StringRef();
144/// }
145/// static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
146/// };
147template <typename T, typename Enable = void> struct ScalarTraits {
148 // Must provide:
149 //
150 // Function to write the value as a string:
151 // static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
152 //
153 // Function to convert a string to a value. Returns the empty
154 // StringRef on success or an error string if string is malformed:
155 // static StringRef input(StringRef scalar, void *ctxt, T &value);
156 //
157 // Function to determine if the value should be quoted.
158 // static QuotingType mustQuote(StringRef);
159};
160
161/// This class should be specialized by type that requires custom conversion
162/// to/from a YAML literal block scalar. For example:
163///
164/// template <>
165/// struct BlockScalarTraits<MyType> {
166/// static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
167/// {
168/// // stream out custom formatting
169/// Out << Value;
170/// }
171/// static StringRef input(StringRef Scalar, void*, MyType &Value) {
172/// // parse scalar and set `value`
173/// // return empty string on success, or error string
174/// return StringRef();
175/// }
176/// };
177template <typename T>
178struct BlockScalarTraits {
179 // Must provide:
180 //
181 // Function to write the value as a string:
182 // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
183 //
184 // Function to convert a string to a value. Returns the empty
185 // StringRef on success or an error string if string is malformed:
186 // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
187 //
188 // Optional:
189 // static StringRef inputTag(T &Val, std::string Tag)
190 // static void outputTag(const T &Val, raw_ostream &Out)
191};
192
193/// This class should be specialized by type that requires custom conversion
194/// to/from a YAML scalar with optional tags. For example:
195///
196/// template <>
197/// struct TaggedScalarTraits<MyType> {
198/// static void output(const MyType &Value, void*, llvm::raw_ostream
199/// &ScalarOut, llvm::raw_ostream &TagOut)
200/// {
201/// // stream out custom formatting including optional Tag
202/// Out << Value;
203/// }
204/// static StringRef input(StringRef Scalar, StringRef Tag, void*, MyType
205/// &Value) {
206/// // parse scalar and set `value`
207/// // return empty string on success, or error string
208/// return StringRef();
209/// }
210/// static QuotingType mustQuote(const MyType &Value, StringRef) {
211/// return QuotingType::Single;
212/// }
213/// };
214template <typename T> struct TaggedScalarTraits {
215 // Must provide:
216 //
217 // Function to write the value and tag as strings:
218 // static void output(const T &Value, void *ctx, llvm::raw_ostream &ScalarOut,
219 // llvm::raw_ostream &TagOut);
220 //
221 // Function to convert a string to a value. Returns the empty
222 // StringRef on success or an error string if string is malformed:
223 // static StringRef input(StringRef Scalar, StringRef Tag, void *ctxt, T
224 // &Value);
225 //
226 // Function to determine if the value should be quoted.
227 // static QuotingType mustQuote(const T &Value, StringRef Scalar);
228};
229
230/// This class should be specialized by any type that needs to be converted
231/// to/from a YAML sequence. For example:
232///
233/// template<>
234/// struct SequenceTraits<MyContainer> {
235/// static size_t size(IO &io, MyContainer &seq) {
236/// return seq.size();
237/// }
238/// static MyType& element(IO &, MyContainer &seq, size_t index) {
239/// if ( index >= seq.size() )
240/// seq.resize(index+1);
241/// return seq[index];
242/// }
243/// };
244template<typename T, typename EnableIf = void>
245struct SequenceTraits {
246 // Must provide:
247 // static size_t size(IO &io, T &seq);
248 // static T::value_type& element(IO &io, T &seq, size_t index);
249 //
250 // The following is option and will cause generated YAML to use
251 // a flow sequence (e.g. [a,b,c]).
252 // static const bool flow = true;
253};
254
255/// This class should be specialized by any type for which vectors of that
256/// type need to be converted to/from a YAML sequence.
257template<typename T, typename EnableIf = void>
258struct SequenceElementTraits {
259 // Must provide:
260 // static const bool flow;
261};
262
263/// This class should be specialized by any type that needs to be converted
264/// to/from a list of YAML documents.
265template<typename T>
266struct DocumentListTraits {
267 // Must provide:
268 // static size_t size(IO &io, T &seq);
269 // static T::value_type& element(IO &io, T &seq, size_t index);
270};
271
272/// This class should be specialized by any type that needs to be converted
273/// to/from a YAML mapping in the case where the names of the keys are not known
274/// in advance, e.g. a string map.
275template <typename T>
276struct CustomMappingTraits {
277 // static void inputOne(IO &io, StringRef key, T &elem);
278 // static void output(IO &io, T &elem);
279};
280
281/// This class should be specialized by any type that can be represented as
282/// a scalar, map, or sequence, decided dynamically. For example:
283///
284/// typedef std::unique_ptr<MyBase> MyPoly;
285///
286/// template<>
287/// struct PolymorphicTraits<MyPoly> {
288/// static NodeKind getKind(const MyPoly &poly) {
289/// return poly->getKind();
290/// }
291/// static MyScalar& getAsScalar(MyPoly &poly) {
292/// if (!poly || !isa<MyScalar>(poly))
293/// poly.reset(new MyScalar());
294/// return *cast<MyScalar>(poly.get());
295/// }
296/// // ...
297/// };
298template <typename T> struct PolymorphicTraits {
299 // Must provide:
300 // static NodeKind getKind(const T &poly);
301 // static scalar_type &getAsScalar(T &poly);
302 // static map_type &getAsMap(T &poly);
303 // static sequence_type &getAsSequence(T &poly);
304};
305
306// Only used for better diagnostics of missing traits
307template <typename T>
308struct MissingTrait;
309
310// Test if ScalarEnumerationTraits<T> is defined on type T.
311template <class T>
312struct has_ScalarEnumerationTraits
313{
314 using Signature_enumeration = void (*)(class IO&, T&);
315
316 template <typename U>
317 static char test(SameType<Signature_enumeration, &U::enumeration>*);
318
319 template <typename U>
320 static double test(...);
321
322 static bool const value =
323 (sizeof(test<ScalarEnumerationTraits<T>>(nullptr)) == 1);
324};
325
326// Test if ScalarBitSetTraits<T> is defined on type T.
327template <class T>
328struct has_ScalarBitSetTraits
329{
330 using Signature_bitset = void (*)(class IO&, T&);
331
332 template <typename U>
333 static char test(SameType<Signature_bitset, &U::bitset>*);
334
335 template <typename U>
336 static double test(...);
337
338 static bool const value = (sizeof(test<ScalarBitSetTraits<T>>(nullptr)) == 1);
339};
340
341// Test if ScalarTraits<T> is defined on type T.
342template <class T>
343struct has_ScalarTraits
344{
345 using Signature_input = StringRef (*)(StringRef, void*, T&);
346 using Signature_output = void (*)(const T&, void*, raw_ostream&);
347 using Signature_mustQuote = QuotingType (*)(StringRef);
348
349 template <typename U>
350 static char test(SameType<Signature_input, &U::input> *,
351 SameType<Signature_output, &U::output> *,
352 SameType<Signature_mustQuote, &U::mustQuote> *);
353
354 template <typename U>
355 static double test(...);
356
357 static bool const value =
358 (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
359};
360
361// Test if BlockScalarTraits<T> is defined on type T.
362template <class T>
363struct has_BlockScalarTraits
364{
365 using Signature_input = StringRef (*)(StringRef, void *, T &);
366 using Signature_output = void (*)(const T &, void *, raw_ostream &);
367
368 template <typename U>
369 static char test(SameType<Signature_input, &U::input> *,
370 SameType<Signature_output, &U::output> *);
371
372 template <typename U>
373 static double test(...);
374
375 static bool const value =
376 (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
377};
378
379// Test if TaggedScalarTraits<T> is defined on type T.
380template <class T> struct has_TaggedScalarTraits {
381 using Signature_input = StringRef (*)(StringRef, StringRef, void *, T &);
382 using Signature_output = void (*)(const T &, void *, raw_ostream &,
383 raw_ostream &);
384 using Signature_mustQuote = QuotingType (*)(const T &, StringRef);
385
386 template <typename U>
387 static char test(SameType<Signature_input, &U::input> *,
388 SameType<Signature_output, &U::output> *,
389 SameType<Signature_mustQuote, &U::mustQuote> *);
390
391 template <typename U> static double test(...);
392
393 static bool const value =
394 (sizeof(test<TaggedScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
395};
396
397// Test if MappingContextTraits<T> is defined on type T.
398template <class T, class Context> struct has_MappingTraits {
399 using Signature_mapping = void (*)(class IO &, T &, Context &);
400
401 template <typename U>
402 static char test(SameType<Signature_mapping, &U::mapping>*);
403
404 template <typename U>
405 static double test(...);
406
407 static bool const value =
408 (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
409};
410
411// Test if MappingTraits<T> is defined on type T.
412template <class T> struct has_MappingTraits<T, EmptyContext> {
413 using Signature_mapping = void (*)(class IO &, T &);
414
415 template <typename U>
416 static char test(SameType<Signature_mapping, &U::mapping> *);
417
418 template <typename U> static double test(...);
419
420 static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
421};
422
423// Test if MappingContextTraits<T>::validate() is defined on type T.
424template <class T, class Context> struct has_MappingValidateTraits {
425 using Signature_validate = std::string (*)(class IO &, T &, Context &);
426
427 template <typename U>
428 static char test(SameType<Signature_validate, &U::validate>*);
429
430 template <typename U>
431 static double test(...);
432
433 static bool const value =
434 (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
435};
436
437// Test if MappingTraits<T>::validate() is defined on type T.
438template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
439 using Signature_validate = std::string (*)(class IO &, T &);
440
441 template <typename U>
442 static char test(SameType<Signature_validate, &U::validate> *);
443
444 template <typename U> static double test(...);
445
446 static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
447};
448
449// Test if MappingContextTraits<T>::enumInput() is defined on type T.
450template <class T, class Context> struct has_MappingEnumInputTraits {
451 using Signature_validate = void (*)(class IO &, T &);
452
453 template <typename U>
454 static char test(SameType<Signature_validate, &U::enumInput> *);
455
456 template <typename U> static double test(...);
457
458 static bool const value =
459 (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
460};
461
462// Test if MappingTraits<T>::enumInput() is defined on type T.
463template <class T> struct has_MappingEnumInputTraits<T, EmptyContext> {
464 using Signature_validate = void (*)(class IO &, T &);
465
466 template <typename U>
467 static char test(SameType<Signature_validate, &U::enumInput> *);
468
469 template <typename U> static double test(...);
470
471 static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
472};
473
474// Test if SequenceTraits<T> is defined on type T.
475template <class T>
476struct has_SequenceMethodTraits
477{
478 using Signature_size = size_t (*)(class IO&, T&);
479
480 template <typename U>
481 static char test(SameType<Signature_size, &U::size>*);
482
483 template <typename U>
484 static double test(...);
485
486 static bool const value = (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
487};
488
489// Test if CustomMappingTraits<T> is defined on type T.
490template <class T>
491struct has_CustomMappingTraits
492{
493 using Signature_input = void (*)(IO &io, StringRef key, T &v);
494
495 template <typename U>
496 static char test(SameType<Signature_input, &U::inputOne>*);
497
498 template <typename U>
499 static double test(...);
500
501 static bool const value =
502 (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
503};
504
505// has_FlowTraits<int> will cause an error with some compilers because
506// it subclasses int. Using this wrapper only instantiates the
507// real has_FlowTraits only if the template type is a class.
508template <typename T, bool Enabled = std::is_class<T>::value>
509class has_FlowTraits
510{
511public:
512 static const bool value = false;
513};
514
515// Some older gcc compilers don't support straight forward tests
516// for members, so test for ambiguity cause by the base and derived
517// classes both defining the member.
518template <class T>
519struct has_FlowTraits<T, true>
520{
521 struct Fallback { bool flow; };
522 struct Derived : T, Fallback { };
523
524 template<typename C>
525 static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
526
527 template<typename C>
528 static char (&f(...))[2];
529
530 static bool const value = sizeof(f<Derived>(nullptr)) == 2;
531};
532
533// Test if SequenceTraits<T> is defined on type T
534template<typename T>
535struct has_SequenceTraits : public std::integral_constant<bool,
536 has_SequenceMethodTraits<T>::value > { };
537
538// Test if DocumentListTraits<T> is defined on type T
539template <class T>
540struct has_DocumentListTraits
541{
542 using Signature_size = size_t (*)(class IO &, T &);
543
544 template <typename U>
545 static char test(SameType<Signature_size, &U::size>*);
546
547 template <typename U>
548 static double test(...);
549
550 static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
551};
552
553template <class T> struct has_PolymorphicTraits {
554 using Signature_getKind = NodeKind (*)(const T &);
555
556 template <typename U>
557 static char test(SameType<Signature_getKind, &U::getKind> *);
558
559 template <typename U> static double test(...);
560
561 static bool const value = (sizeof(test<PolymorphicTraits<T>>(nullptr)) == 1);
562};
563
564inline bool isNumeric(StringRef S) {
565 const auto skipDigits = [](StringRef Input) {
566 return Input.ltrim("0123456789");
567 };
568
569 // Make S.front() and S.drop_front().front() (if S.front() is [+-]) calls
570 // safe.
571 if (S.empty() || S.equals("+") || S.equals("-"))
572 return false;
573
574 if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
575 return true;
576
577 // Infinity and decimal numbers can be prefixed with sign.
578 StringRef Tail = (S.front() == '-' || S.front() == '+') ? S.drop_front() : S;
579
580 // Check for infinity first, because checking for hex and oct numbers is more
581 // expensive.
582 if (Tail.equals(".inf") || Tail.equals(".Inf") || Tail.equals(".INF"))
583 return true;
584
585 // Section 10.3.2 Tag Resolution
586 // YAML 1.2 Specification prohibits Base 8 and Base 16 numbers prefixed with
587 // [-+], so S should be used instead of Tail.
588 if (S.startswith("0o"))
589 return S.size() > 2 &&
590 S.drop_front(2).find_first_not_of("01234567") == StringRef::npos;
591
592 if (S.startswith("0x"))
593 return S.size() > 2 && S.drop_front(2).find_first_not_of(
594 "0123456789abcdefABCDEF") == StringRef::npos;
595
596 // Parse float: [-+]? (\. [0-9]+ | [0-9]+ (\. [0-9]* )?) ([eE] [-+]? [0-9]+)?
597 S = Tail;
598
599 // Handle cases when the number starts with '.' and hence needs at least one
600 // digit after dot (as opposed by number which has digits before the dot), but
601 // doesn't have one.
602 if (S.startswith(".") &&
603 (S.equals(".") ||
604 (S.size() > 1 && std::strchr("0123456789", S[1]) == nullptr)))
605 return false;
606
607 if (S.startswith("E") || S.startswith("e"))
608 return false;
609
610 enum ParseState {
611 Default,
612 FoundDot,
613 FoundExponent,
614 };
615 ParseState State = Default;
616
617 S = skipDigits(S);
618
619 // Accept decimal integer.
620 if (S.empty())
621 return true;
622
623 if (S.front() == '.') {
624 State = FoundDot;
625 S = S.drop_front();
626 } else if (S.front() == 'e' || S.front() == 'E') {
627 State = FoundExponent;
628 S = S.drop_front();
629 } else {
630 return false;
631 }
632
633 if (State == FoundDot) {
634 S = skipDigits(S);
635 if (S.empty())
636 return true;
637
638 if (S.front() == 'e' || S.front() == 'E') {
639 State = FoundExponent;
640 S = S.drop_front();
641 } else {
642 return false;
643 }
644 }
645
646 assert(State == FoundExponent && "Should have found exponent at this point.")(static_cast <bool> (State == FoundExponent && "Should have found exponent at this point."
) ? void (0) : __assert_fail ("State == FoundExponent && \"Should have found exponent at this point.\""
, "llvm/include/llvm/Support/YAMLTraits.h", 646, __extension__
__PRETTY_FUNCTION__))
;
647 if (S.empty())
648 return false;
649
650 if (S.front() == '+' || S.front() == '-') {
651 S = S.drop_front();
652 if (S.empty())
653 return false;
654 }
655
656 return skipDigits(S).empty();
657}
658
659inline bool isNull(StringRef S) {
660 return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
661 S.equals("~");
662}
663
664inline bool isBool(StringRef S) {
665 // FIXME: using parseBool is causing multiple tests to fail.
666 return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
667 S.equals("false") || S.equals("False") || S.equals("FALSE");
668}
669
670// 5.1. Character Set
671// The allowed character range explicitly excludes the C0 control block #x0-#x1F
672// (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
673// control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
674// block #xD800-#xDFFF, #xFFFE, and #xFFFF.
675inline QuotingType needsQuotes(StringRef S) {
676 if (S.empty())
677 return QuotingType::Single;
678
679 QuotingType MaxQuotingNeeded = QuotingType::None;
680 if (isSpace(static_cast<unsigned char>(S.front())) ||
681 isSpace(static_cast<unsigned char>(S.back())))
682 MaxQuotingNeeded = QuotingType::Single;
683 if (isNull(S))
684 MaxQuotingNeeded = QuotingType::Single;
685 if (isBool(S))
686 MaxQuotingNeeded = QuotingType::Single;
687 if (isNumeric(S))
688 MaxQuotingNeeded = QuotingType::Single;
689
690 // 7.3.3 Plain Style
691 // Plain scalars must not begin with most indicators, as this would cause
692 // ambiguity with other YAML constructs.
693 if (std::strchr(R"(-?:\,[]{}#&*!|>'"%@`)", S[0]) != nullptr)
694 MaxQuotingNeeded = QuotingType::Single;
695
696 for (unsigned char C : S) {
697 // Alphanum is safe.
698 if (isAlnum(C))
699 continue;
700
701 switch (C) {
702 // Safe scalar characters.
703 case '_':
704 case '-':
705 case '^':
706 case '.':
707 case ',':
708 case ' ':
709 // TAB (0x9) is allowed in unquoted strings.
710 case 0x9:
711 continue;
712 // LF(0xA) and CR(0xD) may delimit values and so require at least single
713 // quotes. LLVM YAML parser cannot handle single quoted multiline so use
714 // double quoting to produce valid YAML.
715 case 0xA:
716 case 0xD:
717 return QuotingType::Double;
718 // DEL (0x7F) are excluded from the allowed character range.
719 case 0x7F:
720 return QuotingType::Double;
721 // Forward slash is allowed to be unquoted, but we quote it anyway. We have
722 // many tests that use FileCheck against YAML output, and this output often
723 // contains paths. If we quote backslashes but not forward slashes then
724 // paths will come out either quoted or unquoted depending on which platform
725 // the test is run on, making FileCheck comparisons difficult.
726 case '/':
727 default: {
728 // C0 control block (0x0 - 0x1F) is excluded from the allowed character
729 // range.
730 if (C <= 0x1F)
731 return QuotingType::Double;
732
733 // Always double quote UTF-8.
734 if ((C & 0x80) != 0)
735 return QuotingType::Double;
736
737 // The character is not safe, at least simple quoting needed.
738 MaxQuotingNeeded = QuotingType::Single;
739 }
740 }
741 }
742
743 return MaxQuotingNeeded;
744}
745
746template <typename T, typename Context>
747struct missingTraits
748 : public std::integral_constant<bool,
749 !has_ScalarEnumerationTraits<T>::value &&
750 !has_ScalarBitSetTraits<T>::value &&
751 !has_ScalarTraits<T>::value &&
752 !has_BlockScalarTraits<T>::value &&
753 !has_TaggedScalarTraits<T>::value &&
754 !has_MappingTraits<T, Context>::value &&
755 !has_SequenceTraits<T>::value &&
756 !has_CustomMappingTraits<T>::value &&
757 !has_DocumentListTraits<T>::value &&
758 !has_PolymorphicTraits<T>::value> {};
759
760template <typename T, typename Context>
761struct validatedMappingTraits
762 : public std::integral_constant<
763 bool, has_MappingTraits<T, Context>::value &&
764 has_MappingValidateTraits<T, Context>::value> {};
765
766template <typename T, typename Context>
767struct unvalidatedMappingTraits
768 : public std::integral_constant<
769 bool, has_MappingTraits<T, Context>::value &&
770 !has_MappingValidateTraits<T, Context>::value> {};
771
772// Base class for Input and Output.
773class IO {
774public:
775 IO(void *Ctxt = nullptr);
776 virtual ~IO();
777
778 virtual bool outputting() const = 0;
779
780 virtual unsigned beginSequence() = 0;
781 virtual bool preflightElement(unsigned, void *&) = 0;
782 virtual void postflightElement(void*) = 0;
783 virtual void endSequence() = 0;
784 virtual bool canElideEmptySequence() = 0;
785
786 virtual unsigned beginFlowSequence() = 0;
787 virtual bool preflightFlowElement(unsigned, void *&) = 0;
788 virtual void postflightFlowElement(void*) = 0;
789 virtual void endFlowSequence() = 0;
790
791 virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
792 virtual void beginMapping() = 0;
793 virtual void endMapping() = 0;
794 virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
795 virtual void postflightKey(void*) = 0;
796 virtual std::vector<StringRef> keys() = 0;
797
798 virtual void beginFlowMapping() = 0;
799 virtual void endFlowMapping() = 0;
800
801 virtual void beginEnumScalar() = 0;
802 virtual bool matchEnumScalar(const char*, bool) = 0;
803 virtual bool matchEnumFallback() = 0;
804 virtual void endEnumScalar() = 0;
805
806 virtual bool beginBitSetScalar(bool &) = 0;
807 virtual bool bitSetMatch(const char*, bool) = 0;
808 virtual void endBitSetScalar() = 0;
809
810 virtual void scalarString(StringRef &, QuotingType) = 0;
811 virtual void blockScalarString(StringRef &) = 0;
812 virtual void scalarTag(std::string &) = 0;
813
814 virtual NodeKind getNodeKind() = 0;
815
816 virtual void setError(const Twine &) = 0;
817 virtual void setAllowUnknownKeys(bool Allow);
818
819 template <typename T>
820 void enumCase(T &Val, const char* Str, const T ConstVal) {
821 if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
822 Val = ConstVal;
823 }
824 }
825
826 // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
827 template <typename T>
828 void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
829 if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
830 Val = ConstVal;
831 }
832 }
833
834 template <typename FBT, typename T>
835 void enumFallback(T &Val) {
836 if (matchEnumFallback()) {
837 EmptyContext Context;
838 // FIXME: Force integral conversion to allow strong typedefs to convert.
839 FBT Res = static_cast<typename FBT::BaseType>(Val);
840 yamlize(*this, Res, true, Context);
841 Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
842 }
843 }
844
845 template <typename T>
846 void bitSetCase(T &Val, const char* Str, const T ConstVal) {
847 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
848 Val = static_cast<T>(Val | ConstVal);
849 }
850 }
851
852 // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
853 template <typename T>
854 void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
855 if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
856 Val = static_cast<T>(Val | ConstVal);
857 }
858 }
859
860 template <typename T>
861 void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
862 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
863 Val = Val | ConstVal;
864 }
865
866 template <typename T>
867 void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
868 uint32_t Mask) {
869 if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
870 Val = Val | ConstVal;
871 }
872
873 void *getContext() const;
874 void setContext(void *);
875
876 template <typename T> void mapRequired(const char *Key, T &Val) {
877 EmptyContext Ctx;
878 this->processKey(Key, Val, true, Ctx);
8
Calling 'IO::processKey'
12
Returning from 'IO::processKey'
879 }
13
Returning without writing to 'Val.value'
880
881 template <typename T, typename Context>
882 void mapRequired(const char *Key, T &Val, Context &Ctx) {
883 this->processKey(Key, Val, true, Ctx);
884 }
885
886 template <typename T> void mapOptional(const char *Key, T &Val) {
887 EmptyContext Ctx;
888 mapOptionalWithContext(Key, Val, Ctx);
889 }
890
891 template <typename T, typename DefaultT>
892 void mapOptional(const char *Key, T &Val, const DefaultT &Default) {
893 EmptyContext Ctx;
894 mapOptionalWithContext(Key, Val, Default, Ctx);
895 }
896
897 template <typename T, typename Context>
898 std::enable_if_t<has_SequenceTraits<T>::value, void>
899 mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
900 // omit key/value instead of outputting empty sequence
901 if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
902 return;
903 this->processKey(Key, Val, false, Ctx);
904 }
905
906 template <typename T, typename Context>
907 void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
908 this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
909 Ctx);
910 }
911
912 template <typename T, typename Context>
913 std::enable_if_t<!has_SequenceTraits<T>::value, void>
914 mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
915 this->processKey(Key, Val, false, Ctx);
916 }
917
918 template <typename T, typename Context, typename DefaultT>
919 void mapOptionalWithContext(const char *Key, T &Val, const DefaultT &Default,
920 Context &Ctx) {
921 static_assert(std::is_convertible<DefaultT, T>::value,
922 "Default type must be implicitly convertible to value type!");
923 this->processKeyWithDefault(Key, Val, static_cast<const T &>(Default),
924 false, Ctx);
925 }
926
927private:
928 template <typename T, typename Context>
929 void processKeyWithDefault(const char *Key, Optional<T> &Val,
930 const Optional<T> &DefaultValue, bool Required,
931 Context &Ctx);
932
933 template <typename T, typename Context>
934 void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
935 bool Required, Context &Ctx) {
936 void *SaveInfo;
937 bool UseDefault;
938 const bool sameAsDefault = outputting() && Val == DefaultValue;
939 if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
940 SaveInfo) ) {
941 yamlize(*this, Val, Required, Ctx);
942 this->postflightKey(SaveInfo);
943 }
944 else {
945 if ( UseDefault )
946 Val = DefaultValue;
947 }
948 }
949
950 template <typename T, typename Context>
951 void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
952 void *SaveInfo;
953 bool UseDefault;
954 if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
9
Assuming the condition is false
10
Taking false branch
955 yamlize(*this, Val, Required, Ctx);
956 this->postflightKey(SaveInfo);
957 }
958 }
11
Returning without writing to 'Val.value'
959
960private:
961 void *Ctxt;
962};
963
964namespace detail {
965
966template <typename T, typename Context>
967void doMapping(IO &io, T &Val, Context &Ctx) {
968 MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
969}
970
971template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
972 MappingTraits<T>::mapping(io, Val);
973}
974
975} // end namespace detail
976
977template <typename T>
978std::enable_if_t<has_ScalarEnumerationTraits<T>::value, void>
979yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
980 io.beginEnumScalar();
981 ScalarEnumerationTraits<T>::enumeration(io, Val);
982 io.endEnumScalar();
983}
984
985template <typename T>
986std::enable_if_t<has_ScalarBitSetTraits<T>::value, void>
987yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
988 bool DoClear;
989 if ( io.beginBitSetScalar(DoClear) ) {
990 if ( DoClear )
991 Val = T();
992 ScalarBitSetTraits<T>::bitset(io, Val);
993 io.endBitSetScalar();
994 }
995}
996
997template <typename T>
998std::enable_if_t<has_ScalarTraits<T>::value, void> yamlize(IO &io, T &Val, bool,
999 EmptyContext &Ctx) {
1000 if ( io.outputting() ) {
1001 std::string Storage;
1002 raw_string_ostream Buffer(Storage);
1003 ScalarTraits<T>::output(Val, io.getContext(), Buffer);
1004 StringRef Str = Buffer.str();
1005 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
1006 }
1007 else {
1008 StringRef Str;
1009 io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
1010 StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
1011 if ( !Result.empty() ) {
1012 io.setError(Twine(Result));
1013 }
1014 }
1015}
1016
1017template <typename T>
1018std::enable_if_t<has_BlockScalarTraits<T>::value, void>
1019yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
1020 if (YamlIO.outputting()) {
1021 std::string Storage;
1022 raw_string_ostream Buffer(Storage);
1023 BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
1024 StringRef Str = Buffer.str();
1025 YamlIO.blockScalarString(Str);
1026 } else {
1027 StringRef Str;
1028 YamlIO.blockScalarString(Str);
1029 StringRef Result =
1030 BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
1031 if (!Result.empty())
1032 YamlIO.setError(Twine(Result));
1033 }
1034}
1035
1036template <typename T>
1037std::enable_if_t<has_TaggedScalarTraits<T>::value, void>
1038yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1039 if (io.outputting()) {
1040 std::string ScalarStorage, TagStorage;
1041 raw_string_ostream ScalarBuffer(ScalarStorage), TagBuffer(TagStorage);
1042 TaggedScalarTraits<T>::output(Val, io.getContext(), ScalarBuffer,
1043 TagBuffer);
1044 io.scalarTag(TagBuffer.str());
1045 StringRef ScalarStr = ScalarBuffer.str();
1046 io.scalarString(ScalarStr,
1047 TaggedScalarTraits<T>::mustQuote(Val, ScalarStr));
1048 } else {
1049 std::string Tag;
1050 io.scalarTag(Tag);
1051 StringRef Str;
1052 io.scalarString(Str, QuotingType::None);
1053 StringRef Result =
1054 TaggedScalarTraits<T>::input(Str, Tag, io.getContext(), Val);
1055 if (!Result.empty()) {
1056 io.setError(Twine(Result));
1057 }
1058 }
1059}
1060
1061template <typename T, typename Context>
1062std::enable_if_t<validatedMappingTraits<T, Context>::value, void>
1063yamlize(IO &io, T &Val, bool, Context &Ctx) {
1064 if (has_FlowTraits<MappingTraits<T>>::value)
1065 io.beginFlowMapping();
1066 else
1067 io.beginMapping();
1068 if (io.outputting()) {
1069 std::string Err = MappingTraits<T>::validate(io, Val);
1070 if (!Err.empty()) {
1071 errs() << Err << "\n";
1072 assert(Err.empty() && "invalid struct trying to be written as yaml")(static_cast <bool> (Err.empty() && "invalid struct trying to be written as yaml"
) ? void (0) : __assert_fail ("Err.empty() && \"invalid struct trying to be written as yaml\""
, "llvm/include/llvm/Support/YAMLTraits.h", 1072, __extension__
__PRETTY_FUNCTION__))
;
1073 }
1074 }
1075 detail::doMapping(io, Val, Ctx);
1076 if (!io.outputting()) {
1077 std::string Err = MappingTraits<T>::validate(io, Val);
1078 if (!Err.empty())
1079 io.setError(Err);
1080 }
1081 if (has_FlowTraits<MappingTraits<T>>::value)
1082 io.endFlowMapping();
1083 else
1084 io.endMapping();
1085}
1086
1087template <typename T, typename Context>
1088std::enable_if_t<!has_MappingEnumInputTraits<T, Context>::value, bool>
1089yamlizeMappingEnumInput(IO &io, T &Val) {
1090 return false;
1091}
1092
1093template <typename T, typename Context>
1094std::enable_if_t<has_MappingEnumInputTraits<T, Context>::value, bool>
1095yamlizeMappingEnumInput(IO &io, T &Val) {
1096 if (io.outputting())
1097 return false;
1098
1099 io.beginEnumScalar();
1100 MappingTraits<T>::enumInput(io, Val);
1101 bool Matched = !io.matchEnumFallback();
1102 io.endEnumScalar();
1103 return Matched;
1104}
1105
1106template <typename T, typename Context>
1107std::enable_if_t<unvalidatedMappingTraits<T, Context>::value, void>
1108yamlize(IO &io, T &Val, bool, Context &Ctx) {
1109 if (yamlizeMappingEnumInput<T, Context>(io, Val))
1110 return;
1111 if (has_FlowTraits<MappingTraits<T>>::value) {
1112 io.beginFlowMapping();
1113 detail::doMapping(io, Val, Ctx);
1114 io.endFlowMapping();
1115 } else {
1116 io.beginMapping();
1117 detail::doMapping(io, Val, Ctx);
1118 io.endMapping();
1119 }
1120}
1121
1122template <typename T>
1123std::enable_if_t<has_CustomMappingTraits<T>::value, void>
1124yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1125 if ( io.outputting() ) {
1126 io.beginMapping();
1127 CustomMappingTraits<T>::output(io, Val);
1128 io.endMapping();
1129 } else {
1130 io.beginMapping();
1131 for (StringRef key : io.keys())
1132 CustomMappingTraits<T>::inputOne(io, key, Val);
1133 io.endMapping();
1134 }
1135}
1136
1137template <typename T>
1138std::enable_if_t<has_PolymorphicTraits<T>::value, void>
1139yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1140 switch (io.outputting() ? PolymorphicTraits<T>::getKind(Val)
1141 : io.getNodeKind()) {
1142 case NodeKind::Scalar:
1143 return yamlize(io, PolymorphicTraits<T>::getAsScalar(Val), true, Ctx);
1144 case NodeKind::Map:
1145 return yamlize(io, PolymorphicTraits<T>::getAsMap(Val), true, Ctx);
1146 case NodeKind::Sequence:
1147 return yamlize(io, PolymorphicTraits<T>::getAsSequence(Val), true, Ctx);
1148 }
1149}
1150
1151template <typename T>
1152std::enable_if_t<missingTraits<T, EmptyContext>::value, void>
1153yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1154 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1155}
1156
1157template <typename T, typename Context>
1158std::enable_if_t<has_SequenceTraits<T>::value, void>
1159yamlize(IO &io, T &Seq, bool, Context &Ctx) {
1160 if ( has_FlowTraits< SequenceTraits<T>>::value ) {
1161 unsigned incnt = io.beginFlowSequence();
1162 unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1163 for(unsigned i=0; i < count; ++i) {
1164 void *SaveInfo;
1165 if ( io.preflightFlowElement(i, SaveInfo) ) {
1166 yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1167 io.postflightFlowElement(SaveInfo);
1168 }
1169 }
1170 io.endFlowSequence();
1171 }
1172 else {
1173 unsigned incnt = io.beginSequence();
1174 unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1175 for(unsigned i=0; i < count; ++i) {
1176 void *SaveInfo;
1177 if ( io.preflightElement(i, SaveInfo) ) {
1178 yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1179 io.postflightElement(SaveInfo);
1180 }
1181 }
1182 io.endSequence();
1183 }
1184}
1185
1186template<>
1187struct ScalarTraits<bool> {
1188 static void output(const bool &, void* , raw_ostream &);
1189 static StringRef input(StringRef, void *, bool &);
1190 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1191};
1192
1193template<>
1194struct ScalarTraits<StringRef> {
1195 static void output(const StringRef &, void *, raw_ostream &);
1196 static StringRef input(StringRef, void *, StringRef &);
1197 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1198};
1199
1200template<>
1201struct ScalarTraits<std::string> {
1202 static void output(const std::string &, void *, raw_ostream &);
1203 static StringRef input(StringRef, void *, std::string &);
1204 static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1205};
1206
1207template<>
1208struct ScalarTraits<uint8_t> {
1209 static void output(const uint8_t &, void *, raw_ostream &);
1210 static StringRef input(StringRef, void *, uint8_t &);
1211 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1212};
1213
1214template<>
1215struct ScalarTraits<uint16_t> {
1216 static void output(const uint16_t &, void *, raw_ostream &);
1217 static StringRef input(StringRef, void *, uint16_t &);
1218 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1219};
1220
1221template<>
1222struct ScalarTraits<uint32_t> {
1223 static void output(const uint32_t &, void *, raw_ostream &);
1224 static StringRef input(StringRef, void *, uint32_t &);
1225 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1226};
1227
1228template<>
1229struct ScalarTraits<uint64_t> {
1230 static void output(const uint64_t &, void *, raw_ostream &);
1231 static StringRef input(StringRef, void *, uint64_t &);
1232 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1233};
1234
1235template<>
1236struct ScalarTraits<int8_t> {
1237 static void output(const int8_t &, void *, raw_ostream &);
1238 static StringRef input(StringRef, void *, int8_t &);
1239 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1240};
1241
1242template<>
1243struct ScalarTraits<int16_t> {
1244 static void output(const int16_t &, void *, raw_ostream &);
1245 static StringRef input(StringRef, void *, int16_t &);
1246 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1247};
1248
1249template<>
1250struct ScalarTraits<int32_t> {
1251 static void output(const int32_t &, void *, raw_ostream &);
1252 static StringRef input(StringRef, void *, int32_t &);
1253 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1254};
1255
1256template<>
1257struct ScalarTraits<int64_t> {
1258 static void output(const int64_t &, void *, raw_ostream &);
1259 static StringRef input(StringRef, void *, int64_t &);
1260 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1261};
1262
1263template<>
1264struct ScalarTraits<float> {
1265 static void output(const float &, void *, raw_ostream &);
1266 static StringRef input(StringRef, void *, float &);
1267 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1268};
1269
1270template<>
1271struct ScalarTraits<double> {
1272 static void output(const double &, void *, raw_ostream &);
1273 static StringRef input(StringRef, void *, double &);
1274 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1275};
1276
1277// For endian types, we use existing scalar Traits class for the underlying
1278// type. This way endian aware types are supported whenever the traits are
1279// defined for the underlying type.
1280template <typename value_type, support::endianness endian, size_t alignment>
1281struct ScalarTraits<support::detail::packed_endian_specific_integral<
1282 value_type, endian, alignment>,
1283 std::enable_if_t<has_ScalarTraits<value_type>::value>> {
1284 using endian_type =
1285 support::detail::packed_endian_specific_integral<value_type, endian,
1286 alignment>;
1287
1288 static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
1289 ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1290 }
1291
1292 static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1293 value_type V;
1294 auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1295 E = static_cast<endian_type>(V);
1296 return R;
1297 }
1298
1299 static QuotingType mustQuote(StringRef Str) {
1300 return ScalarTraits<value_type>::mustQuote(Str);
1301 }
1302};
1303
1304template <typename value_type, support::endianness endian, size_t alignment>
1305struct ScalarEnumerationTraits<
1306 support::detail::packed_endian_specific_integral<value_type, endian,
1307 alignment>,
1308 std::enable_if_t<has_ScalarEnumerationTraits<value_type>::value>> {
1309 using endian_type =
1310 support::detail::packed_endian_specific_integral<value_type, endian,
1311 alignment>;
1312
1313 static void enumeration(IO &io, endian_type &E) {
1314 value_type V = E;
1315 ScalarEnumerationTraits<value_type>::enumeration(io, V);
1316 E = V;
1317 }
1318};
1319
1320template <typename value_type, support::endianness endian, size_t alignment>
1321struct ScalarBitSetTraits<
1322 support::detail::packed_endian_specific_integral<value_type, endian,
1323 alignment>,
1324 std::enable_if_t<has_ScalarBitSetTraits<value_type>::value>> {
1325 using endian_type =
1326 support::detail::packed_endian_specific_integral<value_type, endian,
1327 alignment>;
1328 static void bitset(IO &io, endian_type &E) {
1329 value_type V = E;
1330 ScalarBitSetTraits<value_type>::bitset(io, V);
1331 E = V;
1332 }
1333};
1334
1335// Utility for use within MappingTraits<>::mapping() method
1336// to [de]normalize an object for use with YAML conversion.
1337template <typename TNorm, typename TFinal>
1338struct MappingNormalization {
1339 MappingNormalization(IO &i_o, TFinal &Obj)
1340 : io(i_o), BufPtr(nullptr), Result(Obj) {
1341 if ( io.outputting() ) {
1342 BufPtr = new (&Buffer) TNorm(io, Obj);
1343 }
1344 else {
1345 BufPtr = new (&Buffer) TNorm(io);
1346 }
1347 }
1348
1349 ~MappingNormalization() {
1350 if ( ! io.outputting() ) {
1351 Result = BufPtr->denormalize(io);
1352 }
1353 BufPtr->~TNorm();
1354 }
1355
1356 TNorm* operator->() { return BufPtr; }
1357
1358private:
1359 using Storage = AlignedCharArrayUnion<TNorm>;
1360
1361 Storage Buffer;
1362 IO &io;
1363 TNorm *BufPtr;
1364 TFinal &Result;
1365};
1366
1367// Utility for use within MappingTraits<>::mapping() method
1368// to [de]normalize an object for use with YAML conversion.
1369template <typename TNorm, typename TFinal>
1370struct MappingNormalizationHeap {
1371 MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
1372 : io(i_o), Result(Obj) {
1373 if ( io.outputting() ) {
1374 BufPtr = new (&Buffer) TNorm(io, Obj);
1375 }
1376 else if (allocator) {
1377 BufPtr = allocator->Allocate<TNorm>();
1378 new (BufPtr) TNorm(io);
1379 } else {
1380 BufPtr = new TNorm(io);
1381 }
1382 }
1383
1384 ~MappingNormalizationHeap() {
1385 if ( io.outputting() ) {
1386 BufPtr->~TNorm();
1387 }
1388 else {
1389 Result = BufPtr->denormalize(io);
1390 }
1391 }
1392
1393 TNorm* operator->() { return BufPtr; }
1394
1395private:
1396 using Storage = AlignedCharArrayUnion<TNorm>;
1397
1398 Storage Buffer;
1399 IO &io;
1400 TNorm *BufPtr = nullptr;
1401 TFinal &Result;
1402};
1403
1404///
1405/// The Input class is used to parse a yaml document into in-memory structs
1406/// and vectors.
1407///
1408/// It works by using YAMLParser to do a syntax parse of the entire yaml
1409/// document, then the Input class builds a graph of HNodes which wraps
1410/// each yaml Node. The extra layer is buffering. The low level yaml
1411/// parser only lets you look at each node once. The buffering layer lets
1412/// you search and interate multiple times. This is necessary because
1413/// the mapRequired() method calls may not be in the same order
1414/// as the keys in the document.
1415///
1416class Input : public IO {
1417public:
1418 // Construct a yaml Input object from a StringRef and optional
1419 // user-data. The DiagHandler can be specified to provide
1420 // alternative error reporting.
1421 Input(StringRef InputContent,
1422 void *Ctxt = nullptr,
1423 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1424 void *DiagHandlerCtxt = nullptr);
1425 Input(MemoryBufferRef Input,
1426 void *Ctxt = nullptr,
1427 SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1428 void *DiagHandlerCtxt = nullptr);
1429 ~Input() override;
1430
1431 // Check if there was an syntax or semantic error during parsing.
1432 std::error_code error();
1433
1434private:
1435 bool outputting() const override;
1436 bool mapTag(StringRef, bool) override;
1437 void beginMapping() override;
1438 void endMapping() override;
1439 bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1440 void postflightKey(void *) override;
1441 std::vector<StringRef> keys() override;
1442 void beginFlowMapping() override;
1443 void endFlowMapping() override;
1444 unsigned beginSequence() override;
1445 void endSequence() override;
1446 bool preflightElement(unsigned index, void *&) override;
1447 void postflightElement(void *) override;
1448 unsigned beginFlowSequence() override;
1449 bool preflightFlowElement(unsigned , void *&) override;
1450 void postflightFlowElement(void *) override;
1451 void endFlowSequence() override;
1452 void beginEnumScalar() override;
1453 bool matchEnumScalar(const char*, bool) override;
1454 bool matchEnumFallback() override;
1455 void endEnumScalar() override;
1456 bool beginBitSetScalar(bool &) override;
1457 bool bitSetMatch(const char *, bool ) override;
1458 void endBitSetScalar() override;
1459 void scalarString(StringRef &, QuotingType) override;
1460 void blockScalarString(StringRef &) override;
1461 void scalarTag(std::string &) override;
1462 NodeKind getNodeKind() override;
1463 void setError(const Twine &message) override;
1464 bool canElideEmptySequence() override;
1465
1466 class HNode {
1467 virtual void anchor();
1468
1469 public:
1470 HNode(Node *n) : _node(n) { }
1471 virtual ~HNode() = default;
1472
1473 static bool classof(const HNode *) { return true; }
1474
1475 Node *_node;
1476 };
1477
1478 class EmptyHNode : public HNode {
1479 void anchor() override;
1480
1481 public:
1482 EmptyHNode(Node *n) : HNode(n) { }
1483
1484 static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
1485
1486 static bool classof(const EmptyHNode *) { return true; }
1487 };
1488
1489 class ScalarHNode : public HNode {
1490 void anchor() override;
1491
1492 public:
1493 ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1494
1495 StringRef value() const { return _value; }
1496
1497 static bool classof(const HNode *n) {
1498 return ScalarNode::classof(n->_node) ||
1499 BlockScalarNode::classof(n->_node);
1500 }
1501
1502 static bool classof(const ScalarHNode *) { return true; }
1503
1504 protected:
1505 StringRef _value;
1506 };
1507
1508 class MapHNode : public HNode {
1509 void anchor() override;
1510
1511 public:
1512 MapHNode(Node *n) : HNode(n) { }
1513
1514 static bool classof(const HNode *n) {
1515 return MappingNode::classof(n->_node);
1516 }
1517
1518 static bool classof(const MapHNode *) { return true; }
1519
1520 using NameToNodeAndLoc =
1521 StringMap<std::pair<std::unique_ptr<HNode>, SMRange>>;
1522
1523 NameToNodeAndLoc Mapping;
1524 SmallVector<std::string, 6> ValidKeys;
1525 };
1526
1527 class SequenceHNode : public HNode {
1528 void anchor() override;
1529
1530 public:
1531 SequenceHNode(Node *n) : HNode(n) { }
1532
1533 static bool classof(const HNode *n) {
1534 return SequenceNode::classof(n->_node);
1535 }
1536
1537 static bool classof(const SequenceHNode *) { return true; }
1538
1539 std::vector<std::unique_ptr<HNode>> Entries;
1540 };
1541
1542 std::unique_ptr<Input::HNode> createHNodes(Node *node);
1543 void setError(HNode *hnode, const Twine &message);
1544 void setError(Node *node, const Twine &message);
1545 void setError(const SMRange &Range, const Twine &message);
1546
1547 void reportWarning(HNode *hnode, const Twine &message);
1548 void reportWarning(Node *hnode, const Twine &message);
1549 void reportWarning(const SMRange &Range, const Twine &message);
1550
1551public:
1552 // These are only used by operator>>. They could be private
1553 // if those templated things could be made friends.
1554 bool setCurrentDocument();
1555 bool nextDocument();
1556
1557 /// Returns the current node that's being parsed by the YAML Parser.
1558 const Node *getCurrentNode() const;
1559
1560 void setAllowUnknownKeys(bool Allow) override;
1561
1562private:
1563 SourceMgr SrcMgr; // must be before Strm
1564 std::unique_ptr<llvm::yaml::Stream> Strm;
1565 std::unique_ptr<HNode> TopNode;
1566 std::error_code EC;
1567 BumpPtrAllocator StringAllocator;
1568 document_iterator DocIterator;
1569 llvm::BitVector BitValuesUsed;
1570 HNode *CurrentNode = nullptr;
1571 bool ScalarMatchFound = false;
1572 bool AllowUnknownKeys = false;
1573};
1574
1575///
1576/// The Output class is used to generate a yaml document from in-memory structs
1577/// and vectors.
1578///
1579class Output : public IO {
1580public:
1581 Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1582 ~Output() override;
1583
1584 /// Set whether or not to output optional values which are equal
1585 /// to the default value. By default, when outputting if you attempt
1586 /// to write a value that is equal to the default, the value gets ignored.
1587 /// Sometimes, it is useful to be able to see these in the resulting YAML
1588 /// anyway.
1589 void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
1590
1591 bool outputting() const override;
1592 bool mapTag(StringRef, bool) override;
1593 void beginMapping() override;
1594 void endMapping() override;
1595 bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1596 void postflightKey(void *) override;
1597 std::vector<StringRef> keys() override;
1598 void beginFlowMapping() override;
1599 void endFlowMapping() override;
1600 unsigned beginSequence() override;
1601 void endSequence() override;
1602 bool preflightElement(unsigned, void *&) override;
1603 void postflightElement(void *) override;
1604 unsigned beginFlowSequence() override;
1605 bool preflightFlowElement(unsigned, void *&) override;
1606 void postflightFlowElement(void *) override;
1607 void endFlowSequence() override;
1608 void beginEnumScalar() override;
1609 bool matchEnumScalar(const char*, bool) override;
1610 bool matchEnumFallback() override;
1611 void endEnumScalar() override;
1612 bool beginBitSetScalar(bool &) override;
1613 bool bitSetMatch(const char *, bool ) override;
1614 void endBitSetScalar() override;
1615 void scalarString(StringRef &, QuotingType) override;
1616 void blockScalarString(StringRef &) override;
1617 void scalarTag(std::string &) override;
1618 NodeKind getNodeKind() override;
1619 void setError(const Twine &message) override;
1620 bool canElideEmptySequence() override;
1621
1622 // These are only used by operator<<. They could be private
1623 // if that templated operator could be made a friend.
1624 void beginDocuments();
1625 bool preflightDocument(unsigned);
1626 void postflightDocument();
1627 void endDocuments();
1628
1629private:
1630 void output(StringRef s);
1631 void outputUpToEndOfLine(StringRef s);
1632 void newLineCheck(bool EmptySequence = false);
1633 void outputNewLine();
1634 void paddedKey(StringRef key);
1635 void flowKey(StringRef Key);
1636
1637 enum InState {
1638 inSeqFirstElement,
1639 inSeqOtherElement,
1640 inFlowSeqFirstElement,
1641 inFlowSeqOtherElement,
1642 inMapFirstKey,
1643 inMapOtherKey,
1644 inFlowMapFirstKey,
1645 inFlowMapOtherKey
1646 };
1647
1648 static bool inSeqAnyElement(InState State);
1649 static bool inFlowSeqAnyElement(InState State);
1650 static bool inMapAnyKey(InState State);
1651 static bool inFlowMapAnyKey(InState State);
1652
1653 raw_ostream &Out;
1654 int WrapColumn;
1655 SmallVector<InState, 8> StateStack;
1656 int Column = 0;
1657 int ColumnAtFlowStart = 0;
1658 int ColumnAtMapFlowStart = 0;
1659 bool NeedBitValueComma = false;
1660 bool NeedFlowSequenceComma = false;
1661 bool EnumerationMatchFound = false;
1662 bool WriteDefaultValues = false;
1663 StringRef Padding;
1664 StringRef PaddingBeforeContainer;
1665};
1666
1667template <typename T, typename Context>
1668void IO::processKeyWithDefault(const char *Key, Optional<T> &Val,
1669 const Optional<T> &DefaultValue, bool Required,
1670 Context &Ctx) {
1671 assert(!DefaultValue && "Optional<T> shouldn't have a value!")(static_cast <bool> (!DefaultValue && "Optional<T> shouldn't have a value!"
) ? void (0) : __assert_fail ("!DefaultValue && \"Optional<T> shouldn't have a value!\""
, "llvm/include/llvm/Support/YAMLTraits.h", 1671, __extension__
__PRETTY_FUNCTION__))
;
1672 void *SaveInfo;
1673 bool UseDefault = true;
1674 const bool sameAsDefault = outputting() && !Val;
1675 if (!outputting() && !Val)
1676 Val = T();
1677 if (Val &&
1678 this->preflightKey(Key, Required, sameAsDefault, UseDefault, SaveInfo)) {
1679
1680 // When reading an Optional<X> key from a YAML description, we allow the
1681 // special "<none>" value, which can be used to specify that no value was
1682 // requested, i.e. the DefaultValue will be assigned. The DefaultValue is
1683 // usually None.
1684 bool IsNone = false;
1685 if (!outputting())
1686 if (const auto *Node = dyn_cast<ScalarNode>(((Input *)this)->getCurrentNode()))
1687 // We use rtrim to ignore possible white spaces that might exist when a
1688 // comment is present on the same line.
1689 IsNone = Node->getRawValue().rtrim(' ') == "<none>";
1690
1691 if (IsNone)
1692 Val = DefaultValue;
1693 else
1694 yamlize(*this, *Val, Required, Ctx);
1695 this->postflightKey(SaveInfo);
1696 } else {
1697 if (UseDefault)
1698 Val = DefaultValue;
1699 }
1700}
1701
1702/// YAML I/O does conversion based on types. But often native data types
1703/// are just a typedef of built in intergral types (e.g. int). But the C++
1704/// type matching system sees through the typedef and all the typedefed types
1705/// look like a built in type. This will cause the generic YAML I/O conversion
1706/// to be used. To provide better control over the YAML conversion, you can
1707/// use this macro instead of typedef. It will create a class with one field
1708/// and automatic conversion operators to and from the base type.
1709/// Based on BOOST_STRONG_TYPEDEF
1710#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)struct _type { _type() = default; _type(const _base v) : value
(v) {} _type(const _type &v) = default; _type &operator
=(const _type &rhs) = default; _type &operator=(const
_base &rhs) { value = rhs; return *this; } operator const
_base & () const { return value; } bool operator==(const
_type &rhs) const { return value == rhs.value; } bool operator
==(const _base &rhs) const { return value == rhs; } bool operator
<(const _type &rhs) const { return value < rhs.value
; } _base value; using BaseType = _base; };
\
1711 struct _type { \
1712 _type() = default; \
1713 _type(const _base v) : value(v) {} \
1714 _type(const _type &v) = default; \
1715 _type &operator=(const _type &rhs) = default; \
1716 _type &operator=(const _base &rhs) { value = rhs; return *this; } \
1717 operator const _base & () const { return value; } \
1718 bool operator==(const _type &rhs) const { return value == rhs.value; } \
1719 bool operator==(const _base &rhs) const { return value == rhs; } \
1720 bool operator<(const _type &rhs) const { return value < rhs.value; } \
1721 _base value; \
1722 using BaseType = _base; \
1723 };
1724
1725///
1726/// Use these types instead of uintXX_t in any mapping to have
1727/// its yaml output formatted as hexadecimal.
1728///
1729LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)struct Hex8 { Hex8() = default; Hex8(const uint8_t v) : value
(v) {} Hex8(const Hex8 &v) = default; Hex8 &operator=
(const Hex8 &rhs) = default; Hex8 &operator=(const uint8_t
&rhs) { value = rhs; return *this; } operator const uint8_t
& () const { return value; } bool operator==(const Hex8 &
rhs) const { return value == rhs.value; } bool operator==(const
uint8_t &rhs) const { return value == rhs; } bool operator
<(const Hex8 &rhs) const { return value < rhs.value
; } uint8_t value; using BaseType = uint8_t; };
1730LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)struct Hex16 { Hex16() = default; Hex16(const uint16_t v) : value
(v) {} Hex16(const Hex16 &v) = default; Hex16 &operator
=(const Hex16 &rhs) = default; Hex16 &operator=(const
uint16_t &rhs) { value = rhs; return *this; } operator const
uint16_t & () const { return value; } bool operator==(const
Hex16 &rhs) const { return value == rhs.value; } bool operator
==(const uint16_t &rhs) const { return value == rhs; } bool
operator<(const Hex16 &rhs) const { return value <
rhs.value; } uint16_t value; using BaseType = uint16_t; };
1731LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)struct Hex32 { Hex32() = default; Hex32(const uint32_t v) : value
(v) {} Hex32(const Hex32 &v) = default; Hex32 &operator
=(const Hex32 &rhs) = default; Hex32 &operator=(const
uint32_t &rhs) { value = rhs; return *this; } operator const
uint32_t & () const { return value; } bool operator==(const
Hex32 &rhs) const { return value == rhs.value; } bool operator
==(const uint32_t &rhs) const { return value == rhs; } bool
operator<(const Hex32 &rhs) const { return value <
rhs.value; } uint32_t value; using BaseType = uint32_t; };
1732LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)struct Hex64 { Hex64() = default; Hex64(const uint64_t v) : value
(v) {} Hex64(const Hex64 &v) = default; Hex64 &operator
=(const Hex64 &rhs) = default; Hex64 &operator=(const
uint64_t &rhs) { value = rhs; return *this; } operator const
uint64_t & () const { return value; } bool operator==(const
Hex64 &rhs) const { return value == rhs.value; } bool operator
==(const uint64_t &rhs) const { return value == rhs; } bool
operator<(const Hex64 &rhs) const { return value <
rhs.value; } uint64_t value; using BaseType = uint64_t; };
1733
1734template<>
1735struct ScalarTraits<Hex8> {
1736 static void output(const Hex8 &, void *, raw_ostream &);
1737 static StringRef input(StringRef, void *, Hex8 &);
1738 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1739};
1740
1741template<>
1742struct ScalarTraits<Hex16> {
1743 static void output(const Hex16 &, void *, raw_ostream &);
1744 static StringRef input(StringRef, void *, Hex16 &);
1745 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1746};
1747
1748template<>
1749struct ScalarTraits<Hex32> {
1750 static void output(const Hex32 &, void *, raw_ostream &);
1751 static StringRef input(StringRef, void *, Hex32 &);
1752 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1753};
1754
1755template<>
1756struct ScalarTraits<Hex64> {
1757 static void output(const Hex64 &, void *, raw_ostream &);
1758 static StringRef input(StringRef, void *, Hex64 &);
1759 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1760};
1761
1762template <> struct ScalarTraits<VersionTuple> {
1763 static void output(const VersionTuple &Value, void *, llvm::raw_ostream &Out);
1764 static StringRef input(StringRef, void *, VersionTuple &);
1765 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1766};
1767
1768// Define non-member operator>> so that Input can stream in a document list.
1769template <typename T>
1770inline std::enable_if_t<has_DocumentListTraits<T>::value, Input &>
1771operator>>(Input &yin, T &docList) {
1772 int i = 0;
1773 EmptyContext Ctx;
1774 while ( yin.setCurrentDocument() ) {
1775 yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1776 if ( yin.error() )
1777 return yin;
1778 yin.nextDocument();
1779 ++i;
1780 }
1781 return yin;
1782}
1783
1784// Define non-member operator>> so that Input can stream in a map as a document.
1785template <typename T>
1786inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Input &>
1787operator>>(Input &yin, T &docMap) {
1788 EmptyContext Ctx;
1789 yin.setCurrentDocument();
1790 yamlize(yin, docMap, true, Ctx);
1791 return yin;
1792}
1793
1794// Define non-member operator>> so that Input can stream in a sequence as
1795// a document.
1796template <typename T>
1797inline std::enable_if_t<has_SequenceTraits<T>::value, Input &>
1798operator>>(Input &yin, T &docSeq) {
1799 EmptyContext Ctx;
1800 if (yin.setCurrentDocument())
1801 yamlize(yin, docSeq, true, Ctx);
1802 return yin;
1803}
1804
1805// Define non-member operator>> so that Input can stream in a block scalar.
1806template <typename T>
1807inline std::enable_if_t<has_BlockScalarTraits<T>::value, Input &>
1808operator>>(Input &In, T &Val) {
1809 EmptyContext Ctx;
1810 if (In.setCurrentDocument())
1811 yamlize(In, Val, true, Ctx);
1812 return In;
1813}
1814
1815// Define non-member operator>> so that Input can stream in a string map.
1816template <typename T>
1817inline std::enable_if_t<has_CustomMappingTraits<T>::value, Input &>
1818operator>>(Input &In, T &Val) {
1819 EmptyContext Ctx;
1820 if (In.setCurrentDocument())
1821 yamlize(In, Val, true, Ctx);
1822 return In;
1823}
1824
1825// Define non-member operator>> so that Input can stream in a polymorphic type.
1826template <typename T>
1827inline std::enable_if_t<has_PolymorphicTraits<T>::value, Input &>
1828operator>>(Input &In, T &Val) {
1829 EmptyContext Ctx;
1830 if (In.setCurrentDocument())
1831 yamlize(In, Val, true, Ctx);
1832 return In;
1833}
1834
1835// Provide better error message about types missing a trait specialization
1836template <typename T>
1837inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Input &>
1838operator>>(Input &yin, T &docSeq) {
1839 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1840 return yin;
1841}
1842
1843// Define non-member operator<< so that Output can stream out document list.
1844template <typename T>
1845inline std::enable_if_t<has_DocumentListTraits<T>::value, Output &>
1846operator<<(Output &yout, T &docList) {
1847 EmptyContext Ctx;
1848 yout.beginDocuments();
1849 const size_t count = DocumentListTraits<T>::size(yout, docList);
1850 for(size_t i=0; i < count; ++i) {
1851 if ( yout.preflightDocument(i) ) {
1852 yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1853 Ctx);
1854 yout.postflightDocument();
1855 }
1856 }
1857 yout.endDocuments();
1858 return yout;
1859}
1860
1861// Define non-member operator<< so that Output can stream out a map.
1862template <typename T>
1863inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Output &>
1864operator<<(Output &yout, T &map) {
1865 EmptyContext Ctx;
1866 yout.beginDocuments();
1867 if ( yout.preflightDocument(0) ) {
1868 yamlize(yout, map, true, Ctx);
1869 yout.postflightDocument();
1870 }
1871 yout.endDocuments();
1872 return yout;
1873}
1874
1875// Define non-member operator<< so that Output can stream out a sequence.
1876template <typename T>
1877inline std::enable_if_t<has_SequenceTraits<T>::value, Output &>
1878operator<<(Output &yout, T &seq) {
1879 EmptyContext Ctx;
1880 yout.beginDocuments();
1881 if ( yout.preflightDocument(0) ) {
1882 yamlize(yout, seq, true, Ctx);
1883 yout.postflightDocument();
1884 }
1885 yout.endDocuments();
1886 return yout;
1887}
1888
1889// Define non-member operator<< so that Output can stream out a block scalar.
1890template <typename T>
1891inline std::enable_if_t<has_BlockScalarTraits<T>::value, Output &>
1892operator<<(Output &Out, T &Val) {
1893 EmptyContext Ctx;
1894 Out.beginDocuments();
1895 if (Out.preflightDocument(0)) {
1896 yamlize(Out, Val, true, Ctx);
1897 Out.postflightDocument();
1898 }
1899 Out.endDocuments();
1900 return Out;
1901}
1902
1903// Define non-member operator<< so that Output can stream out a string map.
1904template <typename T>
1905inline std::enable_if_t<has_CustomMappingTraits<T>::value, Output &>
1906operator<<(Output &Out, T &Val) {
1907 EmptyContext Ctx;
1908 Out.beginDocuments();
1909 if (Out.preflightDocument(0)) {
1910 yamlize(Out, Val, true, Ctx);
1911 Out.postflightDocument();
1912 }
1913 Out.endDocuments();
1914 return Out;
1915}
1916
1917// Define non-member operator<< so that Output can stream out a polymorphic
1918// type.
1919template <typename T>
1920inline std::enable_if_t<has_PolymorphicTraits<T>::value, Output &>
1921operator<<(Output &Out, T &Val) {
1922 EmptyContext Ctx;
1923 Out.beginDocuments();
1924 if (Out.preflightDocument(0)) {
1925 // FIXME: The parser does not support explicit documents terminated with a
1926 // plain scalar; the end-marker is included as part of the scalar token.
1927 assert(PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && "plain scalar documents are not supported")(static_cast <bool> (PolymorphicTraits<T>::getKind
(Val) != NodeKind::Scalar && "plain scalar documents are not supported"
) ? void (0) : __assert_fail ("PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && \"plain scalar documents are not supported\""
, "llvm/include/llvm/Support/YAMLTraits.h", 1927, __extension__
__PRETTY_FUNCTION__))
;
1928 yamlize(Out, Val, true, Ctx);
1929 Out.postflightDocument();
1930 }
1931 Out.endDocuments();
1932 return Out;
1933}
1934
1935// Provide better error message about types missing a trait specialization
1936template <typename T>
1937inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Output &>
1938operator<<(Output &yout, T &seq) {
1939 char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1940 return yout;
1941}
1942
1943template <bool B> struct IsFlowSequenceBase {};
1944template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1945
1946template <typename T, bool Flow>
1947struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1948private:
1949 using type = typename T::value_type;
1950
1951public:
1952 static size_t size(IO &io, T &seq) { return seq.size(); }
1953
1954 static type &element(IO &io, T &seq, size_t index) {
1955 if (index >= seq.size())
1956 seq.resize(index + 1);
1957 return seq[index];
1958 }
1959};
1960
1961// Simple helper to check an expression can be used as a bool-valued template
1962// argument.
1963template <bool> struct CheckIsBool { static const bool value = true; };
1964
1965// If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1966// SequenceTraits that do the obvious thing.
1967template <typename T>
1968struct SequenceTraits<
1969 std::vector<T>,
1970 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1971 : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1972template <typename T, unsigned N>
1973struct SequenceTraits<
1974 SmallVector<T, N>,
1975 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1976 : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1977template <typename T>
1978struct SequenceTraits<
1979 SmallVectorImpl<T>,
1980 std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1981 : SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
1982
1983// Sequences of fundamental types use flow formatting.
1984template <typename T>
1985struct SequenceElementTraits<T,
1986 std::enable_if_t<std::is_fundamental<T>::value>> {
1987 static const bool flow = true;
1988};
1989
1990// Sequences of strings use block formatting.
1991template<> struct SequenceElementTraits<std::string> {
1992 static const bool flow = false;
1993};
1994template<> struct SequenceElementTraits<StringRef> {
1995 static const bool flow = false;
1996};
1997template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
1998 static const bool flow = false;
1999};
2000
2001/// Implementation of CustomMappingTraits for std::map<std::string, T>.
2002template <typename T> struct StdMapStringCustomMappingTraitsImpl {
2003 using map_type = std::map<std::string, T>;
2004
2005 static void inputOne(IO &io, StringRef key, map_type &v) {
2006 io.mapRequired(key.str().c_str(), v[std::string(key)]);
2007 }
2008
2009 static void output(IO &io, map_type &v) {
2010 for (auto &p : v)
2011 io.mapRequired(p.first.c_str(), p.second);
2012 }
2013};
2014
2015} // end namespace yaml
2016} // end namespace llvm
2017
2018#define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<TYPE>::value && !std::is_same<TYPE, std::string
>::value && !std::is_same<TYPE, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<TYPE>
{ static const bool flow = FLOW; }; } }
\
2019 namespace llvm { \
2020 namespace yaml { \
2021 static_assert( \
2022 !std::is_fundamental<TYPE>::value && \
2023 !std::is_same<TYPE, std::string>::value && \
2024 !std::is_same<TYPE, llvm::StringRef>::value, \
2025 "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \
2026 template <> struct SequenceElementTraits<TYPE> { \
2027 static const bool flow = FLOW; \
2028 }; \
2029 } \
2030 }
2031
2032/// Utility for declaring that a std::vector of a particular type
2033/// should be considered a YAML sequence.
2034#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = false; }; } }
\
2035 LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = false; }; } }
2036
2037/// Utility for declaring that a std::vector of a particular type
2038/// should be considered a YAML flow sequence.
2039#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = true; }; } }
\
2040 LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<type>::value && !std::is_same<type, std::string
>::value && !std::is_same<type, llvm::StringRef
>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<type>
{ static const bool flow = true; }; } }
2041
2042#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)namespace llvm { namespace yaml { template <> struct MappingTraits
<Type> { static void mapping(IO &IO, Type &Obj)
; }; } }
\
2043 namespace llvm { \
2044 namespace yaml { \
2045 template <> struct MappingTraits<Type> { \
2046 static void mapping(IO &IO, Type &Obj); \
2047 }; \
2048 } \
2049 }
2050
2051#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarEnumerationTraits
<Type> { static void enumeration(IO &io, Type &
Value); }; } }
\
2052 namespace llvm { \
2053 namespace yaml { \
2054 template <> struct ScalarEnumerationTraits<Type> { \
2055 static void enumeration(IO &io, Type &Value); \
2056 }; \
2057 } \
2058 }
2059
2060#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)namespace llvm { namespace yaml { template <> struct ScalarBitSetTraits
<Type> { static void bitset(IO &IO, Type &Options
); }; } }
\
2061 namespace llvm { \
2062 namespace yaml { \
2063 template <> struct ScalarBitSetTraits<Type> { \
2064 static void bitset(IO &IO, Type &Options); \
2065 }; \
2066 } \
2067 }
2068
2069#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)namespace llvm { namespace yaml { template <> struct ScalarTraits
<Type> { static void output(const Type &Value, void
*ctx, raw_ostream &Out); static StringRef input(StringRef
Scalar, void *ctxt, Type &Value); static QuotingType mustQuote
(StringRef) { return MustQuote; } }; } }
\
2070 namespace llvm { \
2071 namespace yaml { \
2072 template <> struct ScalarTraits<Type> { \
2073 static void output(const Type &Value, void *ctx, raw_ostream &Out); \
2074 static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
2075 static QuotingType mustQuote(StringRef) { return MustQuote; } \
2076 }; \
2077 } \
2078 }
2079
2080/// Utility for declaring that a std::vector of a particular type
2081/// should be considered a YAML document list.
2082#define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)namespace llvm { namespace yaml { template <unsigned N>
struct DocumentListTraits<SmallVector<_type, N>>
: public SequenceTraitsImpl<SmallVector<_type, N>, false
> {}; template <> struct DocumentListTraits<std::
vector<_type>> : public SequenceTraitsImpl<std::vector
<_type>, false> {}; } }
\
2083 namespace llvm { \
2084 namespace yaml { \
2085 template <unsigned N> \
2086 struct DocumentListTraits<SmallVector<_type, N>> \
2087 : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \
2088 template <> \
2089 struct DocumentListTraits<std::vector<_type>> \
2090 : public SequenceTraitsImpl<std::vector<_type>, false> {}; \
2091 } \
2092 }
2093
2094/// Utility for declaring that std::map<std::string, _type> should be considered
2095/// a YAML map.
2096#define LLVM_YAML_IS_STRING_MAP(_type)namespace llvm { namespace yaml { template <> struct CustomMappingTraits
<std::map<std::string, _type>> : public StdMapStringCustomMappingTraitsImpl
<_type> {}; } }
\
2097 namespace llvm { \
2098 namespace yaml { \
2099 template <> \
2100 struct CustomMappingTraits<std::map<std::string, _type>> \
2101 : public StdMapStringCustomMappingTraitsImpl<_type> {}; \
2102 } \
2103 }
2104
2105LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex64)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::yaml::Hex64>::value && !std::is_same<
llvm::yaml::Hex64, std::string>::value && !std::is_same
<llvm::yaml::Hex64, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::yaml
::Hex64> { static const bool flow = true; }; } }
2106LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex32)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::yaml::Hex32>::value && !std::is_same<
llvm::yaml::Hex32, std::string>::value && !std::is_same
<llvm::yaml::Hex32, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::yaml
::Hex32> { static const bool flow = true; }; } }
2107LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex16)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::yaml::Hex16>::value && !std::is_same<
llvm::yaml::Hex16, std::string>::value && !std::is_same
<llvm::yaml::Hex16, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::yaml
::Hex16> { static const bool flow = true; }; } }
2108LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex8)namespace llvm { namespace yaml { static_assert( !std::is_fundamental
<llvm::yaml::Hex8>::value && !std::is_same<llvm
::yaml::Hex8, std::string>::value && !std::is_same
<llvm::yaml::Hex8, llvm::StringRef>::value, "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"
); template <> struct SequenceElementTraits<llvm::yaml
::Hex8> { static const bool flow = true; }; } }
2109
2110#endif // LLVM_SUPPORT_YAMLTRAITS_H