Bug Summary

File: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 -disable-llvm-verifier -discard-value-names -main-file-name ELFYAML.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/build-llvm/lib/ObjectYAML -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/build-llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ObjectYAML -I /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/include -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-13/lib/clang/13.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 -O2 -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 -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/build-llvm/lib/ObjectYAML -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -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-2021-05-07-005843-9350-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210506100649+6304c0836a4d/llvm/lib/ObjectYAML/ELFYAML.cpp

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

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