diff options
author | dim <dim@FreeBSD.org> | 2017-09-26 19:56:36 +0000 |
---|---|---|
committer | Luiz Souza <luiz@netgate.com> | 2018-02-21 15:12:19 -0300 |
commit | 1dcd2e8d24b295bc73e513acec2ed1514bb66be4 (patch) | |
tree | 4bd13a34c251e980e1a6b13584ca1f63b0dfe670 /contrib/llvm/lib/ObjectYAML | |
parent | f45541ca2a56a1ba1202f94c080b04e96c1fa239 (diff) | |
download | FreeBSD-src-1dcd2e8d24b295bc73e513acec2ed1514bb66be4.zip FreeBSD-src-1dcd2e8d24b295bc73e513acec2ed1514bb66be4.tar.gz |
Merge clang, llvm, lld, lldb, compiler-rt and libc++ 5.0.0 release.
MFC r309126 (by emaste):
Correct lld llvm-tblgen dependency file name
MFC r309169:
Get rid of separate Subversion mergeinfo properties for llvm-dwarfdump
and llvm-lto. The mergeinfo confuses Subversion enormously, and these
directories will just use the mergeinfo for llvm itself.
MFC r312765:
Pull in r276136 from upstream llvm trunk (by Wei Mi):
Use ValueOffsetPair to enhance value reuse during SCEV expansion.
In D12090, the ExprValueMap was added to reuse existing value during
SCEV expansion. However, const folding and sext/zext distribution can
make the reuse still difficult.
A simplified case is: suppose we know S1 expands to V1 in
ExprValueMap, and
S1 = S2 + C_a
S3 = S2 + C_b
where C_a and C_b are different SCEVConstants. Then we'd like to
expand S3 as V1 - C_a + C_b instead of expanding S2 literally. It is
helpful when S2 is a complex SCEV expr and S2 has no entry in
ExprValueMap, which is usually caused by the fact that S3 is
generated from S1 after const folding.
In order to do that, we represent ExprValueMap as a mapping from SCEV
to ValueOffsetPair. We will save both S1->{V1, 0} and S2->{V1, C_a}
into the ExprValueMap when we create SCEV for V1. When S3 is
expanded, it will first expand S2 to V1 - C_a because of S2->{V1,
C_a} in the map, then expand S3 to V1 - C_a + C_b.
Differential Revision: https://reviews.llvm.org/D21313
This should fix assertion failures when building OpenCV >= 3.1.
PR: 215649
MFC r312831:
Revert r312765 for now, since it causes assertions when building
lang/spidermonkey24.
Reported by: antoine
PR: 215649
MFC r316511 (by jhb):
Add an implementation of __ffssi2() derived from __ffsdi2().
Newer versions of GCC include an __ffssi2() symbol in libgcc and the
compiler can emit calls to it in generated code. This is true for at
least GCC 6.2 when compiling world for mips and mips64.
Reviewed by: jmallett, dim
Sponsored by: DARPA / AFRL
Differential Revision: https://reviews.freebsd.org/D10086
MFC r318601 (by adrian):
[libcompiler-rt] add bswapdi2/bswapsi2
This is required for mips gcc 6.3 userland to build/run.
Reviewed by: emaste, dim
Approved by: emaste
Differential Revision: https://reviews.freebsd.org/D10838
MFC r318884 (by emaste):
lldb: map TRAP_CAP to a trace trap
In the absense of a more specific handler for TRAP_CAP (generated by
ENOTCAPABLE or ECAPMODE while in capability mode) treat it as a trace
trap.
Example usage (testing the bug in PR219173):
% proccontrol -m trapcap lldb usr.bin/hexdump/obj/hexdump -- -Cv -s 1 /bin/ls
...
(lldb) run
Process 12980 launching
Process 12980 launched: '.../usr.bin/hexdump/obj/hexdump' (x86_64)
Process 12980 stopped
* thread #1, stop reason = trace
frame #0: 0x0000004b80c65f1a libc.so.7`__sys_lseek + 10
...
In the future we should have LLDB control the trapcap procctl itself
(as it does with ASLR), as well as report a specific stop reason.
This change eliminates an assertion failure from LLDB for now.
MFC r319796:
Remove a few unneeded files from libllvm, libclang and liblldb.
MFC r319885 (by emaste):
lld: ELF: Fix ICF crash on absolute symbol relocations.
If two sections contained relocations to absolute symbols with the same
value we would crash when trying to access their sections. Add a check that
both symbols point to sections before accessing their sections, and treat
absolute symbols as equal if their values are equal.
Obtained from: LLD commit r292578
MFC r319918:
Revert r319796 for now, it can cause undefined references when linking
in some circumstances.
Reported by: Shawn Webb <shawn.webb@hardenedbsd.org>
MFC r319957 (by emaste):
lld: Add armelf emulation mode
Obtained from: LLD r305375
MFC r321369:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
5.0.0 (trunk r308421). Upstream has branched for the 5.0.0 release,
which should be in about a month. Please report bugs and regressions,
so we can get them into the release.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
MFC r321420:
Add a few more object files to liblldb, which should solve errors when
linking the lldb executable in some cases. In particular, when the
-ffunction-sections -fdata-sections options are turned off, or
ineffective.
Reported by: Shawn Webb, Mark Millard
MFC r321433:
Cleanup stale Options.inc files from the previous libllvm build for
clang 4.0.0. Otherwise, these can get included before the two newly
generated ones (which are different) for clang 5.0.0.
Reported by: Mark Millard
MFC r321439 (by bdrewery):
Move llvm Options.inc hack from r321433 for NO_CLEAN to lib/clang/libllvm.
The files are only ever generated to .OBJDIR, not to WORLDTMP (as a
sysroot) and are only ever included from a compilation. So using
a beforebuild target here removes the file before the compilation
tries to include it.
MFC r321664:
Pull in r308891 from upstream llvm trunk (by Benjamin Kramer):
[CodeGenPrepare] Cut off FindAllMemoryUses if there are too many uses.
This avoids excessive compile time. The case I'm looking at is
Function.cpp from an old version of LLVM that still had the giant
memcmp string matcher in it. Before r308322 this compiled in about 2
minutes, after it, clang takes infinite* time to compile it. With
this patch we're at 5 min, which is still bad but this is a
pathological case.
The cut off at 20 uses was chosen by looking at other cut-offs in LLVM
for user scanning. It's probably too high, but does the job and is
very unlikely to regress anything.
Fixes PR33900.
* I'm impatient and aborted after 15 minutes, on the bug report it was
killed after 2h.
Pull in r308986 from upstream llvm trunk (by Simon Pilgrim):
[X86][CGP] Reduce memcmp() expansion to 2 load pairs (PR33914)
D35067/rL308322 attempted to support up to 4 load pairs for memcmp
inlining which resulted in regressions for some optimized libc memcmp
implementations (PR33914).
Until we can match these more optimal cases, this patch reduces the
memcmp expansion to a maximum of 2 load pairs (which matches what we
do for -Os).
This patch should be considered for the 5.0.0 release branch as well
Differential Revision: https://reviews.llvm.org/D35830
These fix a hang (or extremely long compile time) when building older
LLVM ports.
Reported by: antoine
PR: 219139
MFC r321719:
Pull in r309503 from upstream clang trunk (by Richard Smith):
PR33902: Invalidate line number cache when adding more text to
existing buffer.
This led to crashes as the line number cache would report a bogus
line number for a line of code, and we'd try to find a nonexistent
column within the line when printing diagnostics.
This fixes an assertion when building the graphics/champlain port.
Reported by: antoine, kwm
PR: 219139
MFC r321723:
Upgrade our copies of clang, llvm, lld and lldb to r309439 from the
upstream release_50 branch. This is just after upstream's 5.0.0-rc1.
MFC r322320:
Upgrade our copies of clang, llvm and libc++ to r310316 from the
upstream release_50 branch.
MFC r322326 (by emaste):
lldb: Make i386-*-freebsd expression work on JIT path
* Enable i386 ABI creation for freebsd
* Added an extra argument in ABISysV_i386::PrepareTrivialCall for mmap
syscall
* Unlike linux, the last argument of mmap is actually 64-bit(off_t).
This requires us to push an additional word for the higher order bits.
* Prior to this change, ktrace dump will show mmap failures due to
invalid argument coming from the 6th mmap argument.
Submitted by: Karnajit Wangkhem
Differential Revision: https://reviews.llvm.org/D34776
MFC r322360 (by emaste):
lldb: Report inferior signals as signals, not exceptions, on FreeBSD
This is the FreeBSD equivalent of LLVM r238549.
This serves 2 purposes:
* LLDB should handle inferior process signals SIGSEGV/SIGILL/SIGBUS/
SIGFPE the way it is suppose to be handled. Prior to this fix these
signals will neither create a coredump, nor exit from the debugger
or work for signal handling scenario.
* eInvalidCrashReason need not report "unknown crash reason" if we have
a valid si_signo
llvm.org/pr23699
Patch by Karnajit Wangkhem
Differential Revision: https://reviews.llvm.org/D35223
Submitted by: Karnajit Wangkhem
Obtained from: LLVM r310591
MFC r322474 (by emaste):
lld: Add `-z muldefs` option.
Obtained from: LLVM r310757
MFC r322740:
Upgrade our copies of clang, llvm, lld and libc++ to r311219 from the
upstream release_50 branch.
MFC r322855:
Upgrade our copies of clang, llvm, lldb and compiler-rt to r311606 from
the upstream release_50 branch.
As of this version, lib/msun's trig test should also work correctly
again (see bug 220989 for more information).
PR: 220989
MFC r323112:
Upgrade our copies of clang, llvm, lldb and compiler-rt to r312293 from
the upstream release_50 branch. This corresponds to 5.0.0 rc4.
As of this version, the cad/stepcode port should now compile in a more
reasonable time on i386 (see bug 221836 for more information).
PR: 221836
MFC r323245:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
5.0.0 release (upstream r312559).
Release notes for llvm, clang and lld will be available here soon:
<http://releases.llvm.org/5.0.0/docs/ReleaseNotes.html>
<http://releases.llvm.org/5.0.0/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/5.0.0/tools/lld/docs/ReleaseNotes.html>
Relnotes: yes
(cherry picked from commit 12cd91cf4c6b96a24427c0de5374916f2808d263)
Diffstat (limited to 'contrib/llvm/lib/ObjectYAML')
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/COFFYAML.cpp | 73 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp | 958 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp | 590 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp | 806 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/DWARFEmitter.cpp | 333 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/DWARFVisitor.cpp | 178 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/DWARFVisitor.h | 97 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp | 19 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/ELFYAML.cpp | 871 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/MachOYAML.cpp | 79 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp | 12 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/WasmYAML.cpp | 411 | ||||
-rw-r--r-- | contrib/llvm/lib/ObjectYAML/YAML.cpp | 5 |
13 files changed, 3932 insertions, 500 deletions
diff --git a/contrib/llvm/lib/ObjectYAML/COFFYAML.cpp b/contrib/llvm/lib/ObjectYAML/COFFYAML.cpp index 7f9f4c1..1103159 100644 --- a/contrib/llvm/lib/ObjectYAML/COFFYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/COFFYAML.cpp @@ -12,17 +12,25 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/COFFYAML.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/YAMLTraits.h" +#include <cstdint> +#include <cstring> #define ECase(X) IO.enumCase(Value, #X, COFF::X); + namespace llvm { namespace COFFYAML { + Section::Section() { memset(&Header, 0, sizeof(COFF::section)); } Symbol::Symbol() { memset(&Header, 0, sizeof(COFF::symbol)); } Object::Object() { memset(&Header, 0, sizeof(COFF::header)); } -} + +} // end namespace COFFYAML namespace yaml { + void ScalarEnumerationTraits<COFFYAML::COMDATType>::enumeration( IO &IO, COFFYAML::COMDATType &Value) { IO.enumCase(Value, "0", 0); @@ -172,20 +180,20 @@ void ScalarEnumerationTraits<COFF::RelocationTypeAMD64>::enumeration( void ScalarEnumerationTraits<COFF::WindowsSubsystem>::enumeration( IO &IO, COFF::WindowsSubsystem &Value) { - ECase(IMAGE_SUBSYSTEM_UNKNOWN); - ECase(IMAGE_SUBSYSTEM_NATIVE); - ECase(IMAGE_SUBSYSTEM_WINDOWS_GUI); - ECase(IMAGE_SUBSYSTEM_WINDOWS_CUI); - ECase(IMAGE_SUBSYSTEM_OS2_CUI); - ECase(IMAGE_SUBSYSTEM_POSIX_CUI); - ECase(IMAGE_SUBSYSTEM_NATIVE_WINDOWS); - ECase(IMAGE_SUBSYSTEM_WINDOWS_CE_GUI); - ECase(IMAGE_SUBSYSTEM_EFI_APPLICATION); - ECase(IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER); - ECase(IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER); - ECase(IMAGE_SUBSYSTEM_EFI_ROM); - ECase(IMAGE_SUBSYSTEM_XBOX); - ECase(IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION); + ECase(IMAGE_SUBSYSTEM_UNKNOWN); + ECase(IMAGE_SUBSYSTEM_NATIVE); + ECase(IMAGE_SUBSYSTEM_WINDOWS_GUI); + ECase(IMAGE_SUBSYSTEM_WINDOWS_CUI); + ECase(IMAGE_SUBSYSTEM_OS2_CUI); + ECase(IMAGE_SUBSYSTEM_POSIX_CUI); + ECase(IMAGE_SUBSYSTEM_NATIVE_WINDOWS); + ECase(IMAGE_SUBSYSTEM_WINDOWS_CE_GUI); + ECase(IMAGE_SUBSYSTEM_EFI_APPLICATION); + ECase(IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER); + ECase(IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER); + ECase(IMAGE_SUBSYSTEM_EFI_ROM); + ECase(IMAGE_SUBSYSTEM_XBOX); + ECase(IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION); } #undef ECase @@ -252,12 +260,15 @@ void ScalarBitSetTraits<COFF::DLLCharacteristics>::bitset( #undef BCase namespace { + struct NSectionSelectionType { NSectionSelectionType(IO &) : SelectionType(COFFYAML::COMDATType(0)) {} NSectionSelectionType(IO &, uint8_t C) : SelectionType(COFFYAML::COMDATType(C)) {} + uint8_t denormalize(IO &) { return SelectionType; } + COFFYAML::COMDATType SelectionType; }; @@ -266,7 +277,9 @@ struct NWeakExternalCharacteristics { : Characteristics(COFFYAML::WeakExternalCharacteristics(0)) {} NWeakExternalCharacteristics(IO &, uint32_t C) : Characteristics(COFFYAML::WeakExternalCharacteristics(C)) {} + uint32_t denormalize(IO &) { return Characteristics; } + COFFYAML::WeakExternalCharacteristics Characteristics; }; @@ -275,7 +288,9 @@ struct NSectionCharacteristics { : Characteristics(COFF::SectionCharacteristics(0)) {} NSectionCharacteristics(IO &, uint32_t C) : Characteristics(COFF::SectionCharacteristics(C)) {} + uint32_t denormalize(IO &) { return Characteristics; } + COFF::SectionCharacteristics Characteristics; }; @@ -284,13 +299,16 @@ struct NAuxTokenType { : AuxType(COFFYAML::AuxSymbolType(0)) {} NAuxTokenType(IO &, uint8_t C) : AuxType(COFFYAML::AuxSymbolType(C)) {} + uint32_t denormalize(IO &) { return AuxType; } + COFFYAML::AuxSymbolType AuxType; }; struct NStorageClass { NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {} NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {} + uint8_t denormalize(IO &) { return StorageClass; } COFF::SymbolStorageClass StorageClass; @@ -299,7 +317,9 @@ struct NStorageClass { struct NMachine { NMachine(IO &) : Machine(COFF::MachineTypes(0)) {} NMachine(IO &, uint16_t M) : Machine(COFF::MachineTypes(M)) {} + uint16_t denormalize(IO &) { return Machine; } + COFF::MachineTypes Machine; }; @@ -307,6 +327,7 @@ struct NHeaderCharacteristics { NHeaderCharacteristics(IO &) : Characteristics(COFF::Characteristics(0)) {} NHeaderCharacteristics(IO &, uint16_t C) : Characteristics(COFF::Characteristics(C)) {} + uint16_t denormalize(IO &) { return Characteristics; } COFF::Characteristics Characteristics; @@ -316,13 +337,16 @@ template <typename RelocType> struct NType { NType(IO &) : Type(RelocType(0)) {} NType(IO &, uint16_t T) : Type(RelocType(T)) {} + uint16_t denormalize(IO &) { return Type; } + RelocType Type; }; struct NWindowsSubsystem { NWindowsSubsystem(IO &) : Subsystem(COFF::WindowsSubsystem(0)) {} NWindowsSubsystem(IO &, uint16_t C) : Subsystem(COFF::WindowsSubsystem(C)) {} + uint16_t denormalize(IO &) { return Subsystem; } COFF::WindowsSubsystem Subsystem; @@ -332,12 +356,13 @@ struct NDLLCharacteristics { NDLLCharacteristics(IO &) : Characteristics(COFF::DLLCharacteristics(0)) {} NDLLCharacteristics(IO &, uint16_t C) : Characteristics(COFF::DLLCharacteristics(C)) {} + uint16_t denormalize(IO &) { return Characteristics; } COFF::DLLCharacteristics Characteristics; }; -} +} // end anonymous namespace void MappingTraits<COFFYAML::Relocation>::mapping(IO &IO, COFFYAML::Relocation &Rel) { @@ -488,7 +513,16 @@ void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) { IO.mapOptional("VirtualAddress", Sec.Header.VirtualAddress, 0U); IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U); IO.mapOptional("Alignment", Sec.Alignment, 0U); - IO.mapRequired("SectionData", Sec.SectionData); + + // If this is a .debug$S or .debug$T section parse the semantic representation + // of the symbols/types. If it is any other kind of section, just deal in raw + // bytes. + IO.mapOptional("SectionData", Sec.SectionData); + if (Sec.Name == ".debug$S") + IO.mapOptional("Subsections", Sec.DebugS); + else if (Sec.Name == ".debug$T") + IO.mapOptional("Types", Sec.DebugT); + IO.mapOptional("Relocations", Sec.Relocations); } @@ -500,5 +534,6 @@ void MappingTraits<COFFYAML::Object>::mapping(IO &IO, COFFYAML::Object &Obj) { IO.mapRequired("symbols", Obj.Symbols); } -} -} +} // end namespace yaml + +} // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp new file mode 100644 index 0000000..60b0ea2 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp @@ -0,0 +1,958 @@ +//===- CodeViewYAMLDebugSections.cpp - CodeView YAMLIO debug sections -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/COFF.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h" +#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h" +#include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <memory> +#include <string> +#include <tuple> +#include <vector> + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::CodeViewYAML; +using namespace llvm::CodeViewYAML::detail; +using namespace llvm::yaml; + +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite) +LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport) +LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport) +LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData) + +LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false) +LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind) +LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags) + +LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport) +LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData) +LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock) +LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite) + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +struct YAMLSubsectionBase { + explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {} + virtual ~YAMLSubsectionBase() = default; + + virtual void map(IO &IO) = 0; + virtual std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const = 0; + + DebugSubsectionKind Kind; +}; + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +namespace { + +struct YAMLChecksumsSubsection : public YAMLSubsectionBase { + YAMLChecksumsSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLChecksumsSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &FC); + + std::vector<SourceFileChecksumEntry> Checksums; +}; + +struct YAMLLinesSubsection : public YAMLSubsectionBase { + YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLLinesSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugLinesSubsectionRef &Lines); + + SourceLineInfo Lines; +}; + +struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase { + YAMLInlineeLinesSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugInlineeLinesSubsectionRef &Lines); + + InlineeInfo InlineeLines; +}; + +struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase { + YAMLCrossModuleExportsSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeExports) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>> + fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports); + + std::vector<CrossModuleExport> Exports; +}; + +struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase { + YAMLCrossModuleImportsSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::CrossScopeImports) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugCrossModuleImportsSubsectionRef &Imports); + + std::vector<YAMLCrossModuleImport> Imports; +}; + +struct YAMLSymbolsSubsection : public YAMLSubsectionBase { + YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLSymbolsSubsection>> + fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols); + + std::vector<CodeViewYAML::SymbolRecord> Symbols; +}; + +struct YAMLStringTableSubsection : public YAMLSubsectionBase { + YAMLStringTableSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLStringTableSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings); + + std::vector<StringRef> Strings; +}; + +struct YAMLFrameDataSubsection : public YAMLSubsectionBase { + YAMLFrameDataSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLFrameDataSubsection>> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugFrameDataSubsectionRef &Frames); + + std::vector<YAMLFrameData> Frames; +}; + +struct YAMLCoffSymbolRVASubsection : public YAMLSubsectionBase { + YAMLCoffSymbolRVASubsection() + : YAMLSubsectionBase(DebugSubsectionKind::CoffSymbolRVA) {} + + void map(IO &IO) override; + std::shared_ptr<DebugSubsection> + toCodeViewSubsection(BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const override; + static Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>> + fromCodeViewSubsection(const DebugSymbolRVASubsectionRef &RVAs); + + std::vector<uint32_t> RVAs; +}; + +} // end anonymous namespace + +void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) { + io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns); + io.enumFallback<Hex16>(Flags); +} + +void ScalarEnumerationTraits<FileChecksumKind>::enumeration( + IO &io, FileChecksumKind &Kind) { + io.enumCase(Kind, "None", FileChecksumKind::None); + io.enumCase(Kind, "MD5", FileChecksumKind::MD5); + io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1); + io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256); +} + +void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value, + void *ctx, raw_ostream &Out) { + StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()), + Value.Bytes.size()); + Out << toHex(Bytes); +} + +StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt, + HexFormattedString &Value) { + std::string H = fromHex(Scalar); + Value.Bytes.assign(H.begin(), H.end()); + return StringRef(); +} + +void MappingTraits<SourceLineEntry>::mapping(IO &IO, SourceLineEntry &Obj) { + IO.mapRequired("Offset", Obj.Offset); + IO.mapRequired("LineStart", Obj.LineStart); + IO.mapRequired("IsStatement", Obj.IsStatement); + IO.mapRequired("EndDelta", Obj.EndDelta); +} + +void MappingTraits<SourceColumnEntry>::mapping(IO &IO, SourceColumnEntry &Obj) { + IO.mapRequired("StartColumn", Obj.StartColumn); + IO.mapRequired("EndColumn", Obj.EndColumn); +} + +void MappingTraits<SourceLineBlock>::mapping(IO &IO, SourceLineBlock &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("Lines", Obj.Lines); + IO.mapRequired("Columns", Obj.Columns); +} + +void MappingTraits<CrossModuleExport>::mapping(IO &IO, CrossModuleExport &Obj) { + IO.mapRequired("LocalId", Obj.Local); + IO.mapRequired("GlobalId", Obj.Global); +} + +void MappingTraits<YAMLCrossModuleImport>::mapping(IO &IO, + YAMLCrossModuleImport &Obj) { + IO.mapRequired("Module", Obj.ModuleName); + IO.mapRequired("Imports", Obj.ImportIds); +} + +void MappingTraits<SourceFileChecksumEntry>::mapping( + IO &IO, SourceFileChecksumEntry &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("Kind", Obj.Kind); + IO.mapRequired("Checksum", Obj.ChecksumBytes); +} + +void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("LineNum", Obj.SourceLineNum); + IO.mapRequired("Inlinee", Obj.Inlinee); + IO.mapOptional("ExtraFiles", Obj.ExtraFiles); +} + +void MappingTraits<YAMLFrameData>::mapping(IO &IO, YAMLFrameData &Obj) { + IO.mapRequired("CodeSize", Obj.CodeSize); + IO.mapRequired("FrameFunc", Obj.FrameFunc); + IO.mapRequired("LocalSize", Obj.LocalSize); + IO.mapOptional("MaxStackSize", Obj.MaxStackSize); + IO.mapOptional("ParamsSize", Obj.ParamsSize); + IO.mapOptional("PrologSize", Obj.PrologSize); + IO.mapOptional("RvaStart", Obj.RvaStart); + IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize); +} + +void YAMLChecksumsSubsection::map(IO &IO) { + IO.mapTag("!FileChecksums", true); + IO.mapRequired("Checksums", Checksums); +} + +void YAMLLinesSubsection::map(IO &IO) { + IO.mapTag("!Lines", true); + IO.mapRequired("CodeSize", Lines.CodeSize); + + IO.mapRequired("Flags", Lines.Flags); + IO.mapRequired("RelocOffset", Lines.RelocOffset); + IO.mapRequired("RelocSegment", Lines.RelocSegment); + IO.mapRequired("Blocks", Lines.Blocks); +} + +void YAMLInlineeLinesSubsection::map(IO &IO) { + IO.mapTag("!InlineeLines", true); + IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles); + IO.mapRequired("Sites", InlineeLines.Sites); +} + +void YAMLCrossModuleExportsSubsection::map(IO &IO) { + IO.mapTag("!CrossModuleExports", true); + IO.mapOptional("Exports", Exports); +} + +void YAMLCrossModuleImportsSubsection::map(IO &IO) { + IO.mapTag("!CrossModuleImports", true); + IO.mapOptional("Imports", Imports); +} + +void YAMLSymbolsSubsection::map(IO &IO) { + IO.mapTag("!Symbols", true); + IO.mapRequired("Records", Symbols); +} + +void YAMLStringTableSubsection::map(IO &IO) { + IO.mapTag("!StringTable", true); + IO.mapRequired("Strings", Strings); +} + +void YAMLFrameDataSubsection::map(IO &IO) { + IO.mapTag("!FrameData", true); + IO.mapRequired("Frames", Frames); +} + +void YAMLCoffSymbolRVASubsection::map(IO &IO) { + IO.mapTag("!COFFSymbolRVAs", true); + IO.mapRequired("RVAs", RVAs); +} + +void MappingTraits<YAMLDebugSubsection>::mapping( + IO &IO, YAMLDebugSubsection &Subsection) { + if (!IO.outputting()) { + if (IO.mapTag("!FileChecksums")) { + auto SS = std::make_shared<YAMLChecksumsSubsection>(); + Subsection.Subsection = SS; + } else if (IO.mapTag("!Lines")) { + Subsection.Subsection = std::make_shared<YAMLLinesSubsection>(); + } else if (IO.mapTag("!InlineeLines")) { + Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>(); + } else if (IO.mapTag("!CrossModuleExports")) { + Subsection.Subsection = + std::make_shared<YAMLCrossModuleExportsSubsection>(); + } else if (IO.mapTag("!CrossModuleImports")) { + Subsection.Subsection = + std::make_shared<YAMLCrossModuleImportsSubsection>(); + } else if (IO.mapTag("!Symbols")) { + Subsection.Subsection = std::make_shared<YAMLSymbolsSubsection>(); + } else if (IO.mapTag("!StringTable")) { + Subsection.Subsection = std::make_shared<YAMLStringTableSubsection>(); + } else if (IO.mapTag("!FrameData")) { + Subsection.Subsection = std::make_shared<YAMLFrameDataSubsection>(); + } else if (IO.mapTag("!COFFSymbolRVAs")) { + Subsection.Subsection = std::make_shared<YAMLCoffSymbolRVASubsection>(); + } else { + llvm_unreachable("Unexpected subsection tag!"); + } + } + Subsection.Subsection->map(IO); +} + +std::shared_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + auto Result = std::make_shared<DebugChecksumsSubsection>(*SC.strings()); + for (const auto &CS : Checksums) { + Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes); + } + return Result; +} + +std::shared_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings() && SC.hasChecksums()); + auto Result = + std::make_shared<DebugLinesSubsection>(*SC.checksums(), *SC.strings()); + Result->setCodeSize(Lines.CodeSize); + Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset); + Result->setFlags(Lines.Flags); + for (const auto &LC : Lines.Blocks) { + Result->createBlock(LC.FileName); + if (Result->hasColumnInfo()) { + for (const auto &Item : zip(LC.Lines, LC.Columns)) { + auto &L = std::get<0>(Item); + auto &C = std::get<1>(Item); + uint32_t LE = L.LineStart + L.EndDelta; + Result->addLineAndColumnInfo(L.Offset, + LineInfo(L.LineStart, LE, L.IsStatement), + C.StartColumn, C.EndColumn); + } + } else { + for (const auto &L : LC.Lines) { + uint32_t LE = L.LineStart + L.EndDelta; + Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement)); + } + } + } + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLInlineeLinesSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasChecksums()); + auto Result = std::make_shared<DebugInlineeLinesSubsection>( + *SC.checksums(), InlineeLines.HasExtraFiles); + + for (const auto &Site : InlineeLines.Sites) { + Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, + Site.SourceLineNum); + if (!InlineeLines.HasExtraFiles) + continue; + + for (auto EF : Site.ExtraFiles) { + Result->addExtraFile(EF); + } + } + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLCrossModuleExportsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared<DebugCrossModuleExportsSubsection>(); + for (const auto &M : Exports) + Result->addMapping(M.Local, M.Global); + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLCrossModuleImportsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + + auto Result = + std::make_shared<DebugCrossModuleImportsSubsection>(*SC.strings()); + for (const auto &M : Imports) { + for (const auto Id : M.ImportIds) + Result->addImport(M.ModuleName, Id); + } + return Result; +} + +std::shared_ptr<DebugSubsection> YAMLSymbolsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared<DebugSymbolsSubsection>(); + for (const auto &Sym : Symbols) + Result->addSymbol( + Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile)); + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLStringTableSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared<DebugStringTableSubsection>(); + for (const auto &Str : this->Strings) + Result->insert(Str); + return Result; +} + +std::shared_ptr<DebugSubsection> YAMLFrameDataSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + assert(SC.hasStrings()); + + auto Result = std::make_shared<DebugFrameDataSubsection>(); + for (const auto &YF : Frames) { + codeview::FrameData F; + F.CodeSize = YF.CodeSize; + F.Flags = YF.Flags; + F.LocalSize = YF.LocalSize; + F.MaxStackSize = YF.MaxStackSize; + F.ParamsSize = YF.ParamsSize; + F.PrologSize = YF.PrologSize; + F.RvaStart = YF.RvaStart; + F.SavedRegsSize = YF.SavedRegsSize; + F.FrameFunc = SC.strings()->insert(YF.FrameFunc); + Result->addFrameData(F); + } + return Result; +} + +std::shared_ptr<DebugSubsection> +YAMLCoffSymbolRVASubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, + const codeview::StringsAndChecksums &SC) const { + auto Result = std::make_shared<DebugSymbolRVASubsection>(); + for (const auto &RVA : RVAs) + Result->addRVA(RVA); + return Result; +} + +static Expected<SourceFileChecksumEntry> +convertOneChecksum(const DebugStringTableSubsectionRef &Strings, + const FileChecksumEntry &CS) { + auto ExpectedString = Strings.getString(CS.FileNameOffset); + if (!ExpectedString) + return ExpectedString.takeError(); + + SourceFileChecksumEntry Result; + Result.ChecksumBytes.Bytes = CS.Checksum; + Result.Kind = CS.Kind; + Result.FileName = *ExpectedString; + return Result; +} + +static Expected<StringRef> +getFileName(const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) { + auto Iter = Checksums.getArray().at(FileID); + if (Iter == Checksums.getArray().end()) + return make_error<CodeViewError>(cv_error_code::no_records); + uint32_t Offset = Iter->FileNameOffset; + return Strings.getString(Offset); +} + +Expected<std::shared_ptr<YAMLChecksumsSubsection>> +YAMLChecksumsSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &FC) { + auto Result = std::make_shared<YAMLChecksumsSubsection>(); + + for (const auto &CS : FC) { + auto ConvertedCS = convertOneChecksum(Strings, CS); + if (!ConvertedCS) + return ConvertedCS.takeError(); + Result->Checksums.push_back(*ConvertedCS); + } + return Result; +} + +Expected<std::shared_ptr<YAMLLinesSubsection>> +YAMLLinesSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugLinesSubsectionRef &Lines) { + auto Result = std::make_shared<YAMLLinesSubsection>(); + Result->Lines.CodeSize = Lines.header()->CodeSize; + Result->Lines.RelocOffset = Lines.header()->RelocOffset; + Result->Lines.RelocSegment = Lines.header()->RelocSegment; + Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags)); + for (const auto &L : Lines) { + SourceLineBlock Block; + auto EF = getFileName(Strings, Checksums, L.NameIndex); + if (!EF) + return EF.takeError(); + Block.FileName = *EF; + if (Lines.hasColumnInfo()) { + for (const auto &C : L.Columns) { + SourceColumnEntry SCE; + SCE.EndColumn = C.EndColumn; + SCE.StartColumn = C.StartColumn; + Block.Columns.push_back(SCE); + } + } + for (const auto &LN : L.LineNumbers) { + SourceLineEntry SLE; + LineInfo LI(LN.Flags); + SLE.Offset = LN.Offset; + SLE.LineStart = LI.getStartLine(); + SLE.EndDelta = LI.getLineDelta(); + SLE.IsStatement = LI.isStatement(); + Block.Lines.push_back(SLE); + } + Result->Lines.Blocks.push_back(Block); + } + return Result; +} + +Expected<std::shared_ptr<YAMLInlineeLinesSubsection>> +YAMLInlineeLinesSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugChecksumsSubsectionRef &Checksums, + const DebugInlineeLinesSubsectionRef &Lines) { + auto Result = std::make_shared<YAMLInlineeLinesSubsection>(); + + Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles(); + for (const auto &IL : Lines) { + InlineeSite Site; + auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID); + if (!ExpF) + return ExpF.takeError(); + Site.FileName = *ExpF; + Site.Inlinee = IL.Header->Inlinee.getIndex(); + Site.SourceLineNum = IL.Header->SourceLineNum; + if (Lines.hasExtraFiles()) { + for (const auto EF : IL.ExtraFiles) { + auto ExpF2 = getFileName(Strings, Checksums, EF); + if (!ExpF2) + return ExpF2.takeError(); + Site.ExtraFiles.push_back(*ExpF2); + } + } + Result->InlineeLines.Sites.push_back(Site); + } + return Result; +} + +Expected<std::shared_ptr<YAMLCrossModuleExportsSubsection>> +YAMLCrossModuleExportsSubsection::fromCodeViewSubsection( + const DebugCrossModuleExportsSubsectionRef &Exports) { + auto Result = std::make_shared<YAMLCrossModuleExportsSubsection>(); + Result->Exports.assign(Exports.begin(), Exports.end()); + return Result; +} + +Expected<std::shared_ptr<YAMLCrossModuleImportsSubsection>> +YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugCrossModuleImportsSubsectionRef &Imports) { + auto Result = std::make_shared<YAMLCrossModuleImportsSubsection>(); + for (const auto &CMI : Imports) { + YAMLCrossModuleImport YCMI; + auto ExpectedStr = Strings.getString(CMI.Header->ModuleNameOffset); + if (!ExpectedStr) + return ExpectedStr.takeError(); + YCMI.ModuleName = *ExpectedStr; + YCMI.ImportIds.assign(CMI.Imports.begin(), CMI.Imports.end()); + Result->Imports.push_back(YCMI); + } + return Result; +} + +Expected<std::shared_ptr<YAMLSymbolsSubsection>> +YAMLSymbolsSubsection::fromCodeViewSubsection( + const DebugSymbolsSubsectionRef &Symbols) { + auto Result = std::make_shared<YAMLSymbolsSubsection>(); + for (const auto &Sym : Symbols) { + auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym); + if (!S) + return joinErrors(make_error<CodeViewError>( + cv_error_code::corrupt_record, + "Invalid CodeView Symbol Record in SymbolRecord " + "subsection of .debug$S while converting to YAML!"), + S.takeError()); + + Result->Symbols.push_back(*S); + } + return Result; +} + +Expected<std::shared_ptr<YAMLStringTableSubsection>> +YAMLStringTableSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings) { + auto Result = std::make_shared<YAMLStringTableSubsection>(); + BinaryStreamReader Reader(Strings.getBuffer()); + StringRef S; + // First item is a single null string, skip it. + if (auto EC = Reader.readCString(S)) + return std::move(EC); + assert(S.empty()); + while (Reader.bytesRemaining() > 0) { + if (auto EC = Reader.readCString(S)) + return std::move(EC); + Result->Strings.push_back(S); + } + return Result; +} + +Expected<std::shared_ptr<YAMLFrameDataSubsection>> +YAMLFrameDataSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugFrameDataSubsectionRef &Frames) { + auto Result = std::make_shared<YAMLFrameDataSubsection>(); + for (const auto &F : Frames) { + YAMLFrameData YF; + YF.CodeSize = F.CodeSize; + YF.Flags = F.Flags; + YF.LocalSize = F.LocalSize; + YF.MaxStackSize = F.MaxStackSize; + YF.ParamsSize = F.ParamsSize; + YF.PrologSize = F.PrologSize; + YF.RvaStart = F.RvaStart; + YF.SavedRegsSize = F.SavedRegsSize; + + auto ES = Strings.getString(F.FrameFunc); + if (!ES) + return joinErrors( + make_error<CodeViewError>( + cv_error_code::no_records, + "Could not find string for string id while mapping FrameData!"), + ES.takeError()); + YF.FrameFunc = *ES; + Result->Frames.push_back(YF); + } + return Result; +} + +Expected<std::shared_ptr<YAMLCoffSymbolRVASubsection>> +YAMLCoffSymbolRVASubsection::fromCodeViewSubsection( + const DebugSymbolRVASubsectionRef &Section) { + auto Result = std::make_shared<YAMLCoffSymbolRVASubsection>(); + for (const auto &RVA : Section) { + Result->RVAs.push_back(RVA); + } + return Result; +} + +Expected<std::vector<std::shared_ptr<DebugSubsection>>> +llvm::CodeViewYAML::toCodeViewSubsectionList( + BumpPtrAllocator &Allocator, ArrayRef<YAMLDebugSubsection> Subsections, + const codeview::StringsAndChecksums &SC) { + std::vector<std::shared_ptr<DebugSubsection>> Result; + if (Subsections.empty()) + return std::move(Result); + + for (const auto &SS : Subsections) { + std::shared_ptr<DebugSubsection> CVS; + CVS = SS.Subsection->toCodeViewSubsection(Allocator, SC); + assert(CVS != nullptr); + Result.push_back(std::move(CVS)); + } + return std::move(Result); +} + +namespace { + +struct SubsectionConversionVisitor : public DebugSubsectionVisitor { + SubsectionConversionVisitor() = default; + + Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override; + Error visitLines(DebugLinesSubsectionRef &Lines, + const StringsAndChecksumsRef &State) override; + Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums, + const StringsAndChecksumsRef &State) override; + Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees, + const StringsAndChecksumsRef &State) override; + Error visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &Checksums, + const StringsAndChecksumsRef &State) override; + Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees, + const StringsAndChecksumsRef &State) override; + Error visitStringTable(DebugStringTableSubsectionRef &ST, + const StringsAndChecksumsRef &State) override; + Error visitSymbols(DebugSymbolsSubsectionRef &Symbols, + const StringsAndChecksumsRef &State) override; + Error visitFrameData(DebugFrameDataSubsectionRef &Symbols, + const StringsAndChecksumsRef &State) override; + Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &Symbols, + const StringsAndChecksumsRef &State) override; + + YAMLDebugSubsection Subsection; +}; + +} // end anonymous namespace + +Error SubsectionConversionVisitor::visitUnknown( + DebugUnknownSubsectionRef &Unknown) { + return make_error<CodeViewError>(cv_error_code::operation_unsupported); +} + +Error SubsectionConversionVisitor::visitLines( + DebugLinesSubsectionRef &Lines, const StringsAndChecksumsRef &State) { + auto Result = YAMLLinesSubsection::fromCodeViewSubsection( + State.strings(), State.checksums(), Lines); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitFileChecksums( + DebugChecksumsSubsectionRef &Checksums, + const StringsAndChecksumsRef &State) { + auto Result = YAMLChecksumsSubsection::fromCodeViewSubsection(State.strings(), + Checksums); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitInlineeLines( + DebugInlineeLinesSubsectionRef &Inlinees, + const StringsAndChecksumsRef &State) { + auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection( + State.strings(), State.checksums(), Inlinees); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitCrossModuleExports( + DebugCrossModuleExportsSubsectionRef &Exports, + const StringsAndChecksumsRef &State) { + auto Result = + YAMLCrossModuleExportsSubsection::fromCodeViewSubsection(Exports); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitCrossModuleImports( + DebugCrossModuleImportsSubsectionRef &Imports, + const StringsAndChecksumsRef &State) { + auto Result = YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( + State.strings(), Imports); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitStringTable( + DebugStringTableSubsectionRef &Strings, + const StringsAndChecksumsRef &State) { + auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitSymbols( + DebugSymbolsSubsectionRef &Symbols, const StringsAndChecksumsRef &State) { + auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitFrameData( + DebugFrameDataSubsectionRef &Frames, const StringsAndChecksumsRef &State) { + auto Result = + YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitCOFFSymbolRVAs( + DebugSymbolRVASubsectionRef &RVAs, const StringsAndChecksumsRef &State) { + auto Result = YAMLCoffSymbolRVASubsection::fromCodeViewSubsection(RVAs); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Expected<YAMLDebugSubsection> +YAMLDebugSubsection::fromCodeViewSubection(const StringsAndChecksumsRef &SC, + const DebugSubsectionRecord &SS) { + SubsectionConversionVisitor V; + if (auto EC = visitDebugSubsection(SS, V, SC)) + return std::move(EC); + + return V.Subsection; +} + +std::vector<YAMLDebugSubsection> +llvm::CodeViewYAML::fromDebugS(ArrayRef<uint8_t> Data, + const StringsAndChecksumsRef &SC) { + BinaryStreamReader Reader(Data, support::little); + uint32_t Magic; + + ExitOnError Err("Invalid .debug$S section!"); + Err(Reader.readInteger(Magic)); + assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!"); + + DebugSubsectionArray Subsections; + Err(Reader.readArray(Subsections, Reader.bytesRemaining())); + + std::vector<YAMLDebugSubsection> Result; + + for (const auto &SS : Subsections) { + auto YamlSS = Err(YAMLDebugSubsection::fromCodeViewSubection(SC, SS)); + Result.push_back(YamlSS); + } + return Result; +} + +void llvm::CodeViewYAML::initializeStringsAndChecksums( + ArrayRef<YAMLDebugSubsection> Sections, codeview::StringsAndChecksums &SC) { + // String Table and Checksums subsections don't use the allocator. + BumpPtrAllocator Allocator; + + // It's possible for checksums and strings to even appear in different debug$S + // sections, so we have to make this a stateful function that can build up + // the strings and checksums field over multiple iterations. + + // File Checksums require the string table, but may become before it, so we + // have to scan for strings first, then scan for checksums again from the + // beginning. + if (!SC.hasStrings()) { + for (const auto &SS : Sections) { + if (SS.Subsection->Kind != DebugSubsectionKind::StringTable) + continue; + + auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); + SC.setStrings( + std::static_pointer_cast<DebugStringTableSubsection>(Result)); + break; + } + } + + if (SC.hasStrings() && !SC.hasChecksums()) { + for (const auto &SS : Sections) { + if (SS.Subsection->Kind != DebugSubsectionKind::FileChecksums) + continue; + + auto Result = SS.Subsection->toCodeViewSubsection(Allocator, SC); + SC.setChecksums( + std::static_pointer_cast<DebugChecksumsSubsection>(Result)); + break; + } + } +} diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp new file mode 100644 index 0000000..dbe4e2a --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp @@ -0,0 +1,590 @@ +//===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/EnumTables.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/SymbolSerializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" +#include <algorithm> +#include <cstdint> +#include <cstring> +#include <string> +#include <vector> + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::CodeViewYAML; +using namespace llvm::CodeViewYAML::detail; +using namespace llvm::yaml; + +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) + +// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp +LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false) +LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false) + +LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind) + +LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags) +LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags) +LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions) +LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType) +LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId) +LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType) +LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal) + +LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName) + +LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, true) + +StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) { + return ScalarTraits<StringRef>::input(S, V, T.value); +} + +void ScalarTraits<TypeName>::output(const TypeName &T, void *V, + raw_ostream &R) { + ScalarTraits<StringRef>::output(T.value, V, R); +} + +void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io, + SymbolKind &Value) { + auto SymbolNames = getSymbolTypeNames(); + for (const auto &E : SymbolNames) + io.enumCase(Value, E.Name.str().c_str(), E.Value); +} + +void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io, + CompileSym2Flags &Flags) { + auto FlagNames = getCompileSym2FlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<CompileSym2Flags>(E.Value)); + } +} + +void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io, + CompileSym3Flags &Flags) { + auto FlagNames = getCompileSym3FlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<CompileSym3Flags>(E.Value)); + } +} + +void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) { + auto FlagNames = getExportSymFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<ExportFlags>(E.Value)); + } +} + +void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) { + auto FlagNames = getProcSymFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<PublicSymFlags>(E.Value)); + } +} + +void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) { + auto FlagNames = getLocalFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<LocalSymFlags>(E.Value)); + } +} + +void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) { + auto FlagNames = getProcSymFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<ProcSymFlags>(E.Value)); + } +} + +void ScalarBitSetTraits<FrameProcedureOptions>::bitset( + IO &io, FrameProcedureOptions &Flags) { + auto FlagNames = getFrameProcSymFlagNames(); + for (const auto &E : FlagNames) { + io.bitSetCase(Flags, E.Name.str().c_str(), + static_cast<FrameProcedureOptions>(E.Value)); + } +} + +void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) { + auto CpuNames = getCPUTypeNames(); + for (const auto &E : CpuNames) { + io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value)); + } +} + +void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) { + auto RegNames = getRegisterNames(); + for (const auto &E : RegNames) { + io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value)); + } + io.enumFallback<Hex16>(Reg); +} + +void ScalarEnumerationTraits<TrampolineType>::enumeration( + IO &io, TrampolineType &Tramp) { + auto TrampNames = getTrampolineNames(); + for (const auto &E : TrampNames) { + io.enumCase(Tramp, E.Name.str().c_str(), + static_cast<TrampolineType>(E.Value)); + } +} + +void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io, + ThunkOrdinal &Ord) { + auto ThunkNames = getThunkOrdinalNames(); + for (const auto &E : ThunkNames) { + io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value)); + } +} + +void ScalarEnumerationTraits<FrameCookieKind>::enumeration( + IO &io, FrameCookieKind &FC) { + auto ThunkNames = getFrameCookieKindNames(); + for (const auto &E : ThunkNames) { + io.enumCase(FC, E.Name.str().c_str(), + static_cast<FrameCookieKind>(E.Value)); + } +} + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +struct SymbolRecordBase { + codeview::SymbolKind Kind; + + explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {} + virtual ~SymbolRecordBase() = default; + + virtual void map(yaml::IO &io) = 0; + virtual codeview::CVSymbol + toCodeViewSymbol(BumpPtrAllocator &Allocator, + CodeViewContainer Container) const = 0; + virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0; +}; + +template <typename T> struct SymbolRecordImpl : public SymbolRecordBase { + explicit SymbolRecordImpl(codeview::SymbolKind K) + : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {} + + void map(yaml::IO &io) override; + + codeview::CVSymbol + toCodeViewSymbol(BumpPtrAllocator &Allocator, + CodeViewContainer Container) const override { + return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container); + } + + Error fromCodeViewSymbol(codeview::CVSymbol CVS) override { + return SymbolDeserializer::deserializeAs<T>(CVS, Symbol); + } + + mutable T Symbol; +}; + +struct UnknownSymbolRecord : public SymbolRecordBase { + explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {} + + void map(yaml::IO &io) override; + + CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, + CodeViewContainer Container) const override { + RecordPrefix Prefix; + uint32_t TotalLen = sizeof(RecordPrefix) + Data.size(); + Prefix.RecordKind = Kind; + Prefix.RecordLen = TotalLen - 2; + uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen); + ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix)); + ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size()); + return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen)); + } + + Error fromCodeViewSymbol(CVSymbol CVS) override { + this->Kind = CVS.kind(); + Data = CVS.RecordData.drop_front(sizeof(RecordPrefix)); + return Error::success(); + } + + std::vector<uint8_t> Data; +}; + +template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {} + +void UnknownSymbolRecord::map(yaml::IO &io) { + yaml::BinaryRef Binary; + if (io.outputting()) + Binary = yaml::BinaryRef(Data); + io.mapRequired("Data", Binary); + if (!io.outputting()) { + std::string Str; + raw_string_ostream OS(Str); + Binary.writeAsBinary(OS); + OS.flush(); + Data.assign(Str.begin(), Str.end()); + } +} + +template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) { + IO.mapRequired("Parent", Symbol.Parent); + IO.mapRequired("End", Symbol.End); + IO.mapRequired("Next", Symbol.Next); + IO.mapRequired("Off", Symbol.Offset); + IO.mapRequired("Seg", Symbol.Segment); + IO.mapRequired("Len", Symbol.Length); + IO.mapRequired("Ordinal", Symbol.Thunk); +} + +template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("Size", Symbol.Size); + IO.mapRequired("ThunkOff", Symbol.ThunkOffset); + IO.mapRequired("TargetOff", Symbol.TargetOffset); + IO.mapRequired("ThunkSection", Symbol.ThunkSection); + IO.mapRequired("TargetSection", Symbol.TargetSection); +} + +template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) { + IO.mapRequired("SectionNumber", Symbol.SectionNumber); + IO.mapRequired("Alignment", Symbol.Alignment); + IO.mapRequired("Rva", Symbol.Rva); + IO.mapRequired("Length", Symbol.Length); + IO.mapRequired("Characteristics", Symbol.Characteristics); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) { + IO.mapRequired("Size", Symbol.Size); + IO.mapRequired("Characteristics", Symbol.Characteristics); + IO.mapRequired("Offset", Symbol.Offset); + IO.mapRequired("Segment", Symbol.Segment); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) { + IO.mapRequired("Ordinal", Symbol.Ordinal); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) { + IO.mapOptional("PtrParent", Symbol.Parent, 0U); + IO.mapOptional("PtrEnd", Symbol.End, 0U); + IO.mapOptional("PtrNext", Symbol.Next, 0U); + IO.mapRequired("CodeSize", Symbol.CodeSize); + IO.mapRequired("DbgStart", Symbol.DbgStart); + IO.mapRequired("DbgEnd", Symbol.DbgEnd); + IO.mapRequired("FunctionType", Symbol.FunctionType); + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("DisplayName", Symbol.Name); +} + +template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Index); + IO.mapRequired("Seg", Symbol.Register); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) { + IO.mapRequired("Flags", Symbol.Flags); + IO.mapOptional("Offset", Symbol.Offset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) { + IO.mapRequired("SumName", Symbol.SumName); + IO.mapRequired("SymOffset", Symbol.SymOffset); + IO.mapRequired("Mod", Symbol.Module); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) { + IO.mapRequired("Entries", Symbol.Fields); +} + +template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) { + IO.mapOptional("PtrParent", Symbol.Parent, 0U); + IO.mapOptional("PtrEnd", Symbol.End, 0U); + IO.mapRequired("Inlinee", Symbol.Inlinee); + // TODO: The binary annotations +} + +template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("Flags", Symbol.Flags); + + IO.mapRequired("VarName", Symbol.Name); +} + +template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> +void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) { + // TODO: Print the subfields +} + +template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) { + IO.mapOptional("PtrParent", Symbol.Parent, 0U); + IO.mapOptional("PtrEnd", Symbol.End, 0U); + IO.mapRequired("CodeSize", Symbol.CodeSize); + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("BlockName", Symbol.Name); +} + +template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) { + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("DisplayName", Symbol.Name); +} + +template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) { + IO.mapRequired("Signature", Symbol.Signature); + IO.mapRequired("ObjectName", Symbol.Name); +} + +template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) { + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Machine", Symbol.Machine); + IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); + IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); + IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); + IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); + IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); + IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); + IO.mapRequired("Version", Symbol.Version); +} + +template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) { + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Machine", Symbol.Machine); + IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); + IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); + IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); + IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE); + IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); + IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); + IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); + IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE); + IO.mapRequired("Version", Symbol.Version); +} + +template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) { + IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes); + IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes); + IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding); + IO.mapRequired("BytesOfCalleeSavedRegisters", + Symbol.BytesOfCalleeSavedRegisters); + IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler); + IO.mapRequired("SectionIdOfExceptionHandler", + Symbol.SectionIdOfExceptionHandler); + IO.mapRequired("Flags", Symbol.Flags); +} + +template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) { + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("Type", Symbol.Type); +} + +template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) { + IO.mapRequired("Index", Symbol.Index); + IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset); + IO.mapRequired("Flags", Symbol.Flags); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) { + IO.mapOptional("Offset", Symbol.CodeOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize); + IO.mapRequired("Type", Symbol.Type); +} + +template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) { + IO.mapRequired("Register", Symbol.Register); + IO.mapRequired("CookieKind", Symbol.CookieKind); + IO.mapRequired("Flags", Symbol.Flags); +} + +template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) { + IO.mapRequired("FuncID", Symbol.Indices); +} + +template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("UDTName", Symbol.Name); +} + +template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) { + IO.mapRequired("BuildId", Symbol.BuildId); +} + +template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) { + IO.mapRequired("Offset", Symbol.Offset); + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("VarName", Symbol.Name); +} + +template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) { + IO.mapRequired("Offset", Symbol.Offset); + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("Register", Symbol.Register); + IO.mapRequired("VarName", Symbol.Name); +} + +template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapRequired("Value", Symbol.Value); + IO.mapRequired("Name", Symbol.Name); +} + +template <> void SymbolRecordImpl<DataSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapOptional("Offset", Symbol.DataOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("DisplayName", Symbol.Name); +} + +template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) { + IO.mapRequired("Type", Symbol.Type); + IO.mapOptional("Offset", Symbol.DataOffset, 0U); + IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); + IO.mapRequired("DisplayName", Symbol.Name); +} + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol( + BumpPtrAllocator &Allocator, CodeViewContainer Container) const { + return Symbol->toCodeViewSymbol(Allocator, Container); +} + +namespace llvm { +namespace yaml { + +template <> struct MappingTraits<SymbolRecordBase> { + static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); } +}; + +} // end namespace yaml +} // end namespace llvm + +template <typename SymbolType> +static inline Expected<CodeViewYAML::SymbolRecord> +fromCodeViewSymbolImpl(CVSymbol Symbol) { + CodeViewYAML::SymbolRecord Result; + + auto Impl = std::make_shared<SymbolType>(Symbol.kind()); + if (auto EC = Impl->fromCodeViewSymbol(Symbol)) + return std::move(EC); + Result.Symbol = Impl; + return Result; +} + +Expected<CodeViewYAML::SymbolRecord> +CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { +#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol); +#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + SYMBOL_RECORD(EnumName, EnumVal, ClassName) + switch (Symbol.kind()) { +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" + default: + return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol); + } + return make_error<CodeViewError>(cv_error_code::corrupt_record); +} + +template <typename ConcreteType> +static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, + CodeViewYAML::SymbolRecord &Obj) { + if (!IO.outputting()) + Obj.Symbol = std::make_shared<ConcreteType>(Kind); + + IO.mapRequired(Class, *Obj.Symbol); +} + +void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( + IO &IO, CodeViewYAML::SymbolRecord &Obj) { + SymbolKind Kind; + if (IO.outputting()) + Kind = Obj.Symbol->Kind; + IO.mapRequired("Kind", Kind); + +#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \ + Obj); \ + break; +#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + SYMBOL_RECORD(EnumName, EnumVal, ClassName) + switch (Kind) { +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" + default: + mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj); + } +} diff --git a/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp new file mode 100644 index 0000000..81046b2 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/CodeViewYAMLTypes.cpp @@ -0,0 +1,806 @@ +//===- CodeViewYAMLTypes.cpp - CodeView YAMLIO types implementation -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CodeViewYAMLTypes.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/COFF.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamWriter.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <vector> + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::CodeViewYAML; +using namespace llvm::CodeViewYAML::detail; +using namespace llvm::yaml; + +LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord) +LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) + +LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false) +LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false) + +LLVM_YAML_DECLARE_ENUM_TRAITS(TypeLeafKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(PointerToMemberRepresentation) +LLVM_YAML_DECLARE_ENUM_TRAITS(VFTableSlotKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(CallingConvention) +LLVM_YAML_DECLARE_ENUM_TRAITS(PointerKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(PointerMode) +LLVM_YAML_DECLARE_ENUM_TRAITS(HfaKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(MemberAccess) +LLVM_YAML_DECLARE_ENUM_TRAITS(MethodKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(WindowsRTClassKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(LabelType) + +LLVM_YAML_DECLARE_BITSET_TRAITS(PointerOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(ModifierOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(FunctionOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(ClassOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(MethodOptions) + +LLVM_YAML_DECLARE_MAPPING_TRAITS(OneMethodRecord) +LLVM_YAML_DECLARE_MAPPING_TRAITS(MemberPointerInfo) + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +struct LeafRecordBase { + TypeLeafKind Kind; + + explicit LeafRecordBase(TypeLeafKind K) : Kind(K) {} + virtual ~LeafRecordBase() = default; + + virtual void map(yaml::IO &io) = 0; + virtual CVType toCodeViewRecord(TypeTableBuilder &TTB) const = 0; + virtual Error fromCodeViewRecord(CVType Type) = 0; +}; + +template <typename T> struct LeafRecordImpl : public LeafRecordBase { + explicit LeafRecordImpl(TypeLeafKind K) + : LeafRecordBase(K), Record(static_cast<TypeRecordKind>(K)) {} + + void map(yaml::IO &io) override; + + Error fromCodeViewRecord(CVType Type) override { + return TypeDeserializer::deserializeAs<T>(Type, Record); + } + + CVType toCodeViewRecord(TypeTableBuilder &TTB) const override { + TTB.writeKnownType(Record); + return CVType(Kind, TTB.records().back()); + } + + mutable T Record; +}; + +template <> struct LeafRecordImpl<FieldListRecord> : public LeafRecordBase { + explicit LeafRecordImpl(TypeLeafKind K) : LeafRecordBase(K) {} + + void map(yaml::IO &io) override; + CVType toCodeViewRecord(TypeTableBuilder &TTB) const override; + Error fromCodeViewRecord(CVType Type) override; + + std::vector<MemberRecord> Members; +}; + +struct MemberRecordBase { + TypeLeafKind Kind; + + explicit MemberRecordBase(TypeLeafKind K) : Kind(K) {} + virtual ~MemberRecordBase() = default; + + virtual void map(yaml::IO &io) = 0; + virtual void writeTo(FieldListRecordBuilder &FLRB) = 0; +}; + +template <typename T> struct MemberRecordImpl : public MemberRecordBase { + explicit MemberRecordImpl(TypeLeafKind K) + : MemberRecordBase(K), Record(static_cast<TypeRecordKind>(K)) {} + + void map(yaml::IO &io) override; + + void writeTo(FieldListRecordBuilder &FLRB) override { + FLRB.writeMemberType(Record); + } + + mutable T Record; +}; + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +void ScalarTraits<GUID>::output(const GUID &G, void *, llvm::raw_ostream &OS) { + OS << G; +} + +StringRef ScalarTraits<GUID>::input(StringRef Scalar, void *Ctx, GUID &S) { + if (Scalar.size() != 38) + return "GUID strings are 38 characters long"; + if (Scalar[0] != '{' || Scalar[37] != '}') + return "GUID is not enclosed in {}"; + if (Scalar[9] != '-' || Scalar[14] != '-' || Scalar[19] != '-' || + Scalar[24] != '-') + return "GUID sections are not properly delineated with dashes"; + + uint8_t *OutBuffer = S.Guid; + for (auto Iter = Scalar.begin(); Iter != Scalar.end();) { + if (*Iter == '-' || *Iter == '{' || *Iter == '}') { + ++Iter; + continue; + } + uint8_t Value = (llvm::hexDigitValue(*Iter++) << 4); + Value |= llvm::hexDigitValue(*Iter++); + *OutBuffer++ = Value; + } + + return ""; +} + +void ScalarTraits<TypeIndex>::output(const TypeIndex &S, void *, + raw_ostream &OS) { + OS << S.getIndex(); +} + +StringRef ScalarTraits<TypeIndex>::input(StringRef Scalar, void *Ctx, + TypeIndex &S) { + uint32_t I; + StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I); + S.setIndex(I); + return Result; +} + +void ScalarTraits<APSInt>::output(const APSInt &S, void *, raw_ostream &OS) { + S.print(OS, S.isSigned()); +} + +StringRef ScalarTraits<APSInt>::input(StringRef Scalar, void *Ctx, APSInt &S) { + S = APSInt(Scalar); + return ""; +} + +void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io, + TypeLeafKind &Value) { +#define CV_TYPE(name, val) io.enumCase(Value, #name, name); +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +#undef CV_TYPE +} + +void ScalarEnumerationTraits<PointerToMemberRepresentation>::enumeration( + IO &IO, PointerToMemberRepresentation &Value) { + IO.enumCase(Value, "Unknown", PointerToMemberRepresentation::Unknown); + IO.enumCase(Value, "SingleInheritanceData", + PointerToMemberRepresentation::SingleInheritanceData); + IO.enumCase(Value, "MultipleInheritanceData", + PointerToMemberRepresentation::MultipleInheritanceData); + IO.enumCase(Value, "VirtualInheritanceData", + PointerToMemberRepresentation::VirtualInheritanceData); + IO.enumCase(Value, "GeneralData", PointerToMemberRepresentation::GeneralData); + IO.enumCase(Value, "SingleInheritanceFunction", + PointerToMemberRepresentation::SingleInheritanceFunction); + IO.enumCase(Value, "MultipleInheritanceFunction", + PointerToMemberRepresentation::MultipleInheritanceFunction); + IO.enumCase(Value, "VirtualInheritanceFunction", + PointerToMemberRepresentation::VirtualInheritanceFunction); + IO.enumCase(Value, "GeneralFunction", + PointerToMemberRepresentation::GeneralFunction); +} + +void ScalarEnumerationTraits<VFTableSlotKind>::enumeration( + IO &IO, VFTableSlotKind &Kind) { + IO.enumCase(Kind, "Near16", VFTableSlotKind::Near16); + IO.enumCase(Kind, "Far16", VFTableSlotKind::Far16); + IO.enumCase(Kind, "This", VFTableSlotKind::This); + IO.enumCase(Kind, "Outer", VFTableSlotKind::Outer); + IO.enumCase(Kind, "Meta", VFTableSlotKind::Meta); + IO.enumCase(Kind, "Near", VFTableSlotKind::Near); + IO.enumCase(Kind, "Far", VFTableSlotKind::Far); +} + +void ScalarEnumerationTraits<CallingConvention>::enumeration( + IO &IO, CallingConvention &Value) { + IO.enumCase(Value, "NearC", CallingConvention::NearC); + IO.enumCase(Value, "FarC", CallingConvention::FarC); + IO.enumCase(Value, "NearPascal", CallingConvention::NearPascal); + IO.enumCase(Value, "FarPascal", CallingConvention::FarPascal); + IO.enumCase(Value, "NearFast", CallingConvention::NearFast); + IO.enumCase(Value, "FarFast", CallingConvention::FarFast); + IO.enumCase(Value, "NearStdCall", CallingConvention::NearStdCall); + IO.enumCase(Value, "FarStdCall", CallingConvention::FarStdCall); + IO.enumCase(Value, "NearSysCall", CallingConvention::NearSysCall); + IO.enumCase(Value, "FarSysCall", CallingConvention::FarSysCall); + IO.enumCase(Value, "ThisCall", CallingConvention::ThisCall); + IO.enumCase(Value, "MipsCall", CallingConvention::MipsCall); + IO.enumCase(Value, "Generic", CallingConvention::Generic); + IO.enumCase(Value, "AlphaCall", CallingConvention::AlphaCall); + IO.enumCase(Value, "PpcCall", CallingConvention::PpcCall); + IO.enumCase(Value, "SHCall", CallingConvention::SHCall); + IO.enumCase(Value, "ArmCall", CallingConvention::ArmCall); + IO.enumCase(Value, "AM33Call", CallingConvention::AM33Call); + IO.enumCase(Value, "TriCall", CallingConvention::TriCall); + IO.enumCase(Value, "SH5Call", CallingConvention::SH5Call); + IO.enumCase(Value, "M32RCall", CallingConvention::M32RCall); + IO.enumCase(Value, "ClrCall", CallingConvention::ClrCall); + IO.enumCase(Value, "Inline", CallingConvention::Inline); + IO.enumCase(Value, "NearVector", CallingConvention::NearVector); +} + +void ScalarEnumerationTraits<PointerKind>::enumeration(IO &IO, + PointerKind &Kind) { + IO.enumCase(Kind, "Near16", PointerKind::Near16); + IO.enumCase(Kind, "Far16", PointerKind::Far16); + IO.enumCase(Kind, "Huge16", PointerKind::Huge16); + IO.enumCase(Kind, "BasedOnSegment", PointerKind::BasedOnSegment); + IO.enumCase(Kind, "BasedOnValue", PointerKind::BasedOnValue); + IO.enumCase(Kind, "BasedOnSegmentValue", PointerKind::BasedOnSegmentValue); + IO.enumCase(Kind, "BasedOnAddress", PointerKind::BasedOnAddress); + IO.enumCase(Kind, "BasedOnSegmentAddress", + PointerKind::BasedOnSegmentAddress); + IO.enumCase(Kind, "BasedOnType", PointerKind::BasedOnType); + IO.enumCase(Kind, "BasedOnSelf", PointerKind::BasedOnSelf); + IO.enumCase(Kind, "Near32", PointerKind::Near32); + IO.enumCase(Kind, "Far32", PointerKind::Far32); + IO.enumCase(Kind, "Near64", PointerKind::Near64); +} + +void ScalarEnumerationTraits<PointerMode>::enumeration(IO &IO, + PointerMode &Mode) { + IO.enumCase(Mode, "Pointer", PointerMode::Pointer); + IO.enumCase(Mode, "LValueReference", PointerMode::LValueReference); + IO.enumCase(Mode, "PointerToDataMember", PointerMode::PointerToDataMember); + IO.enumCase(Mode, "PointerToMemberFunction", + PointerMode::PointerToMemberFunction); + IO.enumCase(Mode, "RValueReference", PointerMode::RValueReference); +} + +void ScalarEnumerationTraits<HfaKind>::enumeration(IO &IO, HfaKind &Value) { + IO.enumCase(Value, "None", HfaKind::None); + IO.enumCase(Value, "Float", HfaKind::Float); + IO.enumCase(Value, "Double", HfaKind::Double); + IO.enumCase(Value, "Other", HfaKind::Other); +} + +void ScalarEnumerationTraits<MemberAccess>::enumeration(IO &IO, + MemberAccess &Access) { + IO.enumCase(Access, "None", MemberAccess::None); + IO.enumCase(Access, "Private", MemberAccess::Private); + IO.enumCase(Access, "Protected", MemberAccess::Protected); + IO.enumCase(Access, "Public", MemberAccess::Public); +} + +void ScalarEnumerationTraits<MethodKind>::enumeration(IO &IO, + MethodKind &Kind) { + IO.enumCase(Kind, "Vanilla", MethodKind::Vanilla); + IO.enumCase(Kind, "Virtual", MethodKind::Virtual); + IO.enumCase(Kind, "Static", MethodKind::Static); + IO.enumCase(Kind, "Friend", MethodKind::Friend); + IO.enumCase(Kind, "IntroducingVirtual", MethodKind::IntroducingVirtual); + IO.enumCase(Kind, "PureVirtual", MethodKind::PureVirtual); + IO.enumCase(Kind, "PureIntroducingVirtual", + MethodKind::PureIntroducingVirtual); +} + +void ScalarEnumerationTraits<WindowsRTClassKind>::enumeration( + IO &IO, WindowsRTClassKind &Value) { + IO.enumCase(Value, "None", WindowsRTClassKind::None); + IO.enumCase(Value, "Ref", WindowsRTClassKind::RefClass); + IO.enumCase(Value, "Value", WindowsRTClassKind::ValueClass); + IO.enumCase(Value, "Interface", WindowsRTClassKind::Interface); +} + +void ScalarEnumerationTraits<LabelType>::enumeration(IO &IO, LabelType &Value) { + IO.enumCase(Value, "Near", LabelType::Near); + IO.enumCase(Value, "Far", LabelType::Far); +} + +void ScalarBitSetTraits<PointerOptions>::bitset(IO &IO, + PointerOptions &Options) { + IO.bitSetCase(Options, "None", PointerOptions::None); + IO.bitSetCase(Options, "Flat32", PointerOptions::Flat32); + IO.bitSetCase(Options, "Volatile", PointerOptions::Volatile); + IO.bitSetCase(Options, "Const", PointerOptions::Const); + IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned); + IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict); + IO.bitSetCase(Options, "WinRTSmartPointer", + PointerOptions::WinRTSmartPointer); +} + +void ScalarBitSetTraits<ModifierOptions>::bitset(IO &IO, + ModifierOptions &Options) { + IO.bitSetCase(Options, "None", ModifierOptions::None); + IO.bitSetCase(Options, "Const", ModifierOptions::Const); + IO.bitSetCase(Options, "Volatile", ModifierOptions::Volatile); + IO.bitSetCase(Options, "Unaligned", ModifierOptions::Unaligned); +} + +void ScalarBitSetTraits<FunctionOptions>::bitset(IO &IO, + FunctionOptions &Options) { + IO.bitSetCase(Options, "None", FunctionOptions::None); + IO.bitSetCase(Options, "CxxReturnUdt", FunctionOptions::CxxReturnUdt); + IO.bitSetCase(Options, "Constructor", FunctionOptions::Constructor); + IO.bitSetCase(Options, "ConstructorWithVirtualBases", + FunctionOptions::ConstructorWithVirtualBases); +} + +void ScalarBitSetTraits<ClassOptions>::bitset(IO &IO, ClassOptions &Options) { + IO.bitSetCase(Options, "None", ClassOptions::None); + IO.bitSetCase(Options, "HasConstructorOrDestructor", + ClassOptions::HasConstructorOrDestructor); + IO.bitSetCase(Options, "HasOverloadedOperator", + ClassOptions::HasOverloadedOperator); + IO.bitSetCase(Options, "Nested", ClassOptions::Nested); + IO.bitSetCase(Options, "ContainsNestedClass", + ClassOptions::ContainsNestedClass); + IO.bitSetCase(Options, "HasOverloadedAssignmentOperator", + ClassOptions::HasOverloadedAssignmentOperator); + IO.bitSetCase(Options, "HasConversionOperator", + ClassOptions::HasConversionOperator); + IO.bitSetCase(Options, "ForwardReference", ClassOptions::ForwardReference); + IO.bitSetCase(Options, "Scoped", ClassOptions::Scoped); + IO.bitSetCase(Options, "HasUniqueName", ClassOptions::HasUniqueName); + IO.bitSetCase(Options, "Sealed", ClassOptions::Sealed); + IO.bitSetCase(Options, "Intrinsic", ClassOptions::Intrinsic); +} + +void ScalarBitSetTraits<MethodOptions>::bitset(IO &IO, MethodOptions &Options) { + IO.bitSetCase(Options, "None", MethodOptions::None); + IO.bitSetCase(Options, "Pseudo", MethodOptions::Pseudo); + IO.bitSetCase(Options, "NoInherit", MethodOptions::NoInherit); + IO.bitSetCase(Options, "NoConstruct", MethodOptions::NoConstruct); + IO.bitSetCase(Options, "CompilerGenerated", MethodOptions::CompilerGenerated); + IO.bitSetCase(Options, "Sealed", MethodOptions::Sealed); +} + +void MappingTraits<MemberPointerInfo>::mapping(IO &IO, MemberPointerInfo &MPI) { + IO.mapRequired("ContainingType", MPI.ContainingType); + IO.mapRequired("Representation", MPI.Representation); +} + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +template <> void LeafRecordImpl<ModifierRecord>::map(IO &IO) { + IO.mapRequired("ModifiedType", Record.ModifiedType); + IO.mapRequired("Modifiers", Record.Modifiers); +} + +template <> void LeafRecordImpl<ProcedureRecord>::map(IO &IO) { + IO.mapRequired("ReturnType", Record.ReturnType); + IO.mapRequired("CallConv", Record.CallConv); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("ParameterCount", Record.ParameterCount); + IO.mapRequired("ArgumentList", Record.ArgumentList); +} + +template <> void LeafRecordImpl<MemberFunctionRecord>::map(IO &IO) { + IO.mapRequired("ReturnType", Record.ReturnType); + IO.mapRequired("ClassType", Record.ClassType); + IO.mapRequired("ThisType", Record.ThisType); + IO.mapRequired("CallConv", Record.CallConv); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("ParameterCount", Record.ParameterCount); + IO.mapRequired("ArgumentList", Record.ArgumentList); + IO.mapRequired("ThisPointerAdjustment", Record.ThisPointerAdjustment); +} + +template <> void LeafRecordImpl<LabelRecord>::map(IO &IO) { + IO.mapRequired("Mode", Record.Mode); +} + +template <> void LeafRecordImpl<MemberFuncIdRecord>::map(IO &IO) { + IO.mapRequired("ClassType", Record.ClassType); + IO.mapRequired("FunctionType", Record.FunctionType); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl<ArgListRecord>::map(IO &IO) { + IO.mapRequired("ArgIndices", Record.ArgIndices); +} + +template <> void LeafRecordImpl<StringListRecord>::map(IO &IO) { + IO.mapRequired("StringIndices", Record.StringIndices); +} + +template <> void LeafRecordImpl<PointerRecord>::map(IO &IO) { + IO.mapRequired("ReferentType", Record.ReferentType); + IO.mapRequired("Attrs", Record.Attrs); + IO.mapOptional("MemberInfo", Record.MemberInfo); +} + +template <> void LeafRecordImpl<ArrayRecord>::map(IO &IO) { + IO.mapRequired("ElementType", Record.ElementType); + IO.mapRequired("IndexType", Record.IndexType); + IO.mapRequired("Size", Record.Size); + IO.mapRequired("Name", Record.Name); +} + +void LeafRecordImpl<FieldListRecord>::map(IO &IO) { + IO.mapRequired("FieldList", Members); +} + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +namespace { + +class MemberRecordConversionVisitor : public TypeVisitorCallbacks { +public: + explicit MemberRecordConversionVisitor(std::vector<MemberRecord> &Records) + : Records(Records) {} + +#define TYPE_RECORD(EnumName, EnumVal, Name) +#define MEMBER_RECORD(EnumName, EnumVal, Name) \ + Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \ + return visitKnownMemberImpl(Record); \ + } +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +private: + template <typename T> Error visitKnownMemberImpl(T &Record) { + TypeLeafKind K = static_cast<TypeLeafKind>(Record.getKind()); + auto Impl = std::make_shared<MemberRecordImpl<T>>(K); + Impl->Record = Record; + Records.push_back(MemberRecord{Impl}); + return Error::success(); + } + + std::vector<MemberRecord> &Records; +}; + +} // end anonymous namespace + +Error LeafRecordImpl<FieldListRecord>::fromCodeViewRecord(CVType Type) { + MemberRecordConversionVisitor V(Members); + return visitMemberRecordStream(Type.content(), V); +} + +CVType +LeafRecordImpl<FieldListRecord>::toCodeViewRecord(TypeTableBuilder &TTB) const { + FieldListRecordBuilder FLRB(TTB); + FLRB.begin(); + for (const auto &Member : Members) { + Member.Member->writeTo(FLRB); + } + FLRB.end(true); + return CVType(Kind, TTB.records().back()); +} + +void MappingTraits<OneMethodRecord>::mapping(IO &io, OneMethodRecord &Record) { + io.mapRequired("Type", Record.Type); + io.mapRequired("Attrs", Record.Attrs.Attrs); + io.mapRequired("VFTableOffset", Record.VFTableOffset); + io.mapRequired("Name", Record.Name); +} + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +template <> void LeafRecordImpl<ClassRecord>::map(IO &IO) { + IO.mapRequired("MemberCount", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + IO.mapRequired("DerivationList", Record.DerivationList); + IO.mapRequired("VTableShape", Record.VTableShape); + IO.mapRequired("Size", Record.Size); +} + +template <> void LeafRecordImpl<UnionRecord>::map(IO &IO) { + IO.mapRequired("MemberCount", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + IO.mapRequired("Size", Record.Size); +} + +template <> void LeafRecordImpl<EnumRecord>::map(IO &IO) { + IO.mapRequired("NumEnumerators", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + IO.mapRequired("UnderlyingType", Record.UnderlyingType); +} + +template <> void LeafRecordImpl<BitFieldRecord>::map(IO &IO) { + IO.mapRequired("Type", Record.Type); + IO.mapRequired("BitSize", Record.BitSize); + IO.mapRequired("BitOffset", Record.BitOffset); +} + +template <> void LeafRecordImpl<VFTableShapeRecord>::map(IO &IO) { + IO.mapRequired("Slots", Record.Slots); +} + +template <> void LeafRecordImpl<TypeServer2Record>::map(IO &IO) { + IO.mapRequired("Guid", Record.Guid); + IO.mapRequired("Age", Record.Age); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl<StringIdRecord>::map(IO &IO) { + IO.mapRequired("Id", Record.Id); + IO.mapRequired("String", Record.String); +} + +template <> void LeafRecordImpl<FuncIdRecord>::map(IO &IO) { + IO.mapRequired("ParentScope", Record.ParentScope); + IO.mapRequired("FunctionType", Record.FunctionType); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl<UdtSourceLineRecord>::map(IO &IO) { + IO.mapRequired("UDT", Record.UDT); + IO.mapRequired("SourceFile", Record.SourceFile); + IO.mapRequired("LineNumber", Record.LineNumber); +} + +template <> void LeafRecordImpl<UdtModSourceLineRecord>::map(IO &IO) { + IO.mapRequired("UDT", Record.UDT); + IO.mapRequired("SourceFile", Record.SourceFile); + IO.mapRequired("LineNumber", Record.LineNumber); + IO.mapRequired("Module", Record.Module); +} + +template <> void LeafRecordImpl<BuildInfoRecord>::map(IO &IO) { + IO.mapRequired("ArgIndices", Record.ArgIndices); +} + +template <> void LeafRecordImpl<VFTableRecord>::map(IO &IO) { + IO.mapRequired("CompleteClass", Record.CompleteClass); + IO.mapRequired("OverriddenVFTable", Record.OverriddenVFTable); + IO.mapRequired("VFPtrOffset", Record.VFPtrOffset); + IO.mapRequired("MethodNames", Record.MethodNames); +} + +template <> void LeafRecordImpl<MethodOverloadListRecord>::map(IO &IO) { + IO.mapRequired("Methods", Record.Methods); +} + +template <> void MemberRecordImpl<OneMethodRecord>::map(IO &IO) { + MappingTraits<OneMethodRecord>::mapping(IO, Record); +} + +template <> void MemberRecordImpl<OverloadedMethodRecord>::map(IO &IO) { + IO.mapRequired("NumOverloads", Record.NumOverloads); + IO.mapRequired("MethodList", Record.MethodList); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<NestedTypeRecord>::map(IO &IO) { + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<DataMemberRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("FieldOffset", Record.FieldOffset); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<StaticDataMemberRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<EnumeratorRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Value", Record.Value); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl<VFPtrRecord>::map(IO &IO) { + IO.mapRequired("Type", Record.Type); +} + +template <> void MemberRecordImpl<BaseClassRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Offset", Record.Offset); +} + +template <> void MemberRecordImpl<VirtualBaseClassRecord>::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("BaseType", Record.BaseType); + IO.mapRequired("VBPtrType", Record.VBPtrType); + IO.mapRequired("VBPtrOffset", Record.VBPtrOffset); + IO.mapRequired("VTableIndex", Record.VTableIndex); +} + +template <> void MemberRecordImpl<ListContinuationRecord>::map(IO &IO) { + IO.mapRequired("ContinuationIndex", Record.ContinuationIndex); +} + +} // end namespace detail +} // end namespace CodeViewYAML +} // end namespace llvm + +template <typename T> +static inline Expected<LeafRecord> fromCodeViewRecordImpl(CVType Type) { + LeafRecord Result; + + auto Impl = std::make_shared<LeafRecordImpl<T>>(Type.kind()); + if (auto EC = Impl->fromCodeViewRecord(Type)) + return std::move(EC); + Result.Leaf = Impl; + return Result; +} + +Expected<LeafRecord> LeafRecord::fromCodeViewRecord(CVType Type) { +#define TYPE_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + return fromCodeViewRecordImpl<ClassName##Record>(Type); +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + TYPE_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Type.kind()) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: + llvm_unreachable("Unknown leaf kind!"); + } + return make_error<CodeViewError>(cv_error_code::corrupt_record); +} + +CVType LeafRecord::toCodeViewRecord(BumpPtrAllocator &Alloc) const { + TypeTableBuilder TTB(Alloc); + return Leaf->toCodeViewRecord(TTB); +} + +CVType LeafRecord::toCodeViewRecord(TypeTableBuilder &TTB) const { + return Leaf->toCodeViewRecord(TTB); +} + +namespace llvm { +namespace yaml { + +template <> struct MappingTraits<LeafRecordBase> { + static void mapping(IO &io, LeafRecordBase &Record) { Record.map(io); } +}; + +template <> struct MappingTraits<MemberRecordBase> { + static void mapping(IO &io, MemberRecordBase &Record) { Record.map(io); } +}; + +} // end namespace yaml +} // end namespace llvm + +template <typename ConcreteType> +static void mapLeafRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, + LeafRecord &Obj) { + if (!IO.outputting()) + Obj.Leaf = std::make_shared<LeafRecordImpl<ConcreteType>>(Kind); + + if (Kind == LF_FIELDLIST) + Obj.Leaf->map(IO); + else + IO.mapRequired(Class, *Obj.Leaf); +} + +void MappingTraits<LeafRecord>::mapping(IO &IO, LeafRecord &Obj) { + TypeLeafKind Kind; + if (IO.outputting()) + Kind = Obj.Leaf->Kind; + IO.mapRequired("Kind", Kind); + +#define TYPE_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + mapLeafRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \ + break; +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + TYPE_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Kind) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: { llvm_unreachable("Unknown leaf kind!"); } + } +} + +template <typename ConcreteType> +static void mapMemberRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, + MemberRecord &Obj) { + if (!IO.outputting()) + Obj.Member = std::make_shared<MemberRecordImpl<ConcreteType>>(Kind); + + IO.mapRequired(Class, *Obj.Member); +} + +void MappingTraits<MemberRecord>::mapping(IO &IO, MemberRecord &Obj) { + TypeLeafKind Kind; + if (IO.outputting()) + Kind = Obj.Member->Kind; + IO.mapRequired("Kind", Kind); + +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + mapMemberRecordImpl<ClassName##Record>(IO, #ClassName, Kind, Obj); \ + break; +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define TYPE_RECORD(EnumName, EnumVal, ClassName) +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Kind) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: { llvm_unreachable("Unknown member kind!"); } + } +} + +std::vector<LeafRecord> +llvm::CodeViewYAML::fromDebugT(ArrayRef<uint8_t> DebugT) { + ExitOnError Err("Invalid .debug$T section!"); + BinaryStreamReader Reader(DebugT, support::little); + CVTypeArray Types; + uint32_t Magic; + + Err(Reader.readInteger(Magic)); + assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$T section!"); + + std::vector<LeafRecord> Result; + Err(Reader.readArray(Types, Reader.bytesRemaining())); + for (const auto &T : Types) { + auto CVT = Err(LeafRecord::fromCodeViewRecord(T)); + Result.push_back(CVT); + } + return Result; +} + +ArrayRef<uint8_t> llvm::CodeViewYAML::toDebugT(ArrayRef<LeafRecord> Leafs, + BumpPtrAllocator &Alloc) { + TypeTableBuilder TTB(Alloc, false); + uint32_t Size = sizeof(uint32_t); + for (const auto &Leaf : Leafs) { + CVType T = Leaf.toCodeViewRecord(TTB); + Size += T.length(); + assert(T.length() % 4 == 0 && "Improper type record alignment!"); + } + uint8_t *ResultBuffer = Alloc.Allocate<uint8_t>(Size); + MutableArrayRef<uint8_t> Output(ResultBuffer, Size); + BinaryStreamWriter Writer(Output, support::little); + ExitOnError Err("Error writing type record to .debug$T section"); + Err(Writer.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC)); + for (const auto &R : TTB.records()) { + Err(Writer.writeBytes(R)); + } + assert(Writer.bytesRemaining() == 0 && "Didn't write all type record bytes!"); + return Output; +} diff --git a/contrib/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/contrib/llvm/lib/ObjectYAML/DWARFEmitter.cpp new file mode 100644 index 0000000..89fc652 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/DWARFEmitter.cpp @@ -0,0 +1,333 @@ +//===- DWARFEmitter - Convert YAML to DWARF binary data -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief The DWARF component of yaml2obj. Provided as library code for tests. +/// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/DWARFEmitter.h" +#include "DWARFVisitor.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ObjectYAML/DWARFYAML.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/LEB128.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SwapByteOrder.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <memory> +#include <string> +#include <vector> + +using namespace llvm; + +template <typename T> +static void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) { + if (IsLittleEndian != sys::IsLittleEndianHost) + sys::swapByteOrder(Integer); + OS.write(reinterpret_cast<char *>(&Integer), sizeof(T)); +} + +static void writeVariableSizedInteger(uint64_t Integer, size_t Size, + raw_ostream &OS, bool IsLittleEndian) { + if (8 == Size) + writeInteger((uint64_t)Integer, OS, IsLittleEndian); + else if (4 == Size) + writeInteger((uint32_t)Integer, OS, IsLittleEndian); + else if (2 == Size) + writeInteger((uint16_t)Integer, OS, IsLittleEndian); + else if (1 == Size) + writeInteger((uint8_t)Integer, OS, IsLittleEndian); + else + assert(false && "Invalid integer write size."); +} + +static void ZeroFillBytes(raw_ostream &OS, size_t Size) { + std::vector<uint8_t> FillData; + FillData.insert(FillData.begin(), Size, 0); + OS.write(reinterpret_cast<char *>(FillData.data()), Size); +} + +void writeInitialLength(const DWARFYAML::InitialLength &Length, raw_ostream &OS, + bool IsLittleEndian) { + writeInteger((uint32_t)Length.TotalLength, OS, IsLittleEndian); + if (Length.isDWARF64()) + writeInteger((uint64_t)Length.TotalLength64, OS, IsLittleEndian); +} + +void DWARFYAML::EmitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (auto Str : DI.DebugStrings) { + OS.write(Str.data(), Str.size()); + OS.write('\0'); + } +} + +void DWARFYAML::EmitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (auto AbbrevDecl : DI.AbbrevDecls) { + encodeULEB128(AbbrevDecl.Code, OS); + encodeULEB128(AbbrevDecl.Tag, OS); + OS.write(AbbrevDecl.Children); + for (auto Attr : AbbrevDecl.Attributes) { + encodeULEB128(Attr.Attribute, OS); + encodeULEB128(Attr.Form, OS); + if (Attr.Form == dwarf::DW_FORM_implicit_const) + encodeSLEB128(Attr.Value, OS); + } + encodeULEB128(0, OS); + encodeULEB128(0, OS); + } +} + +void DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (auto Range : DI.ARanges) { + auto HeaderStart = OS.tell(); + writeInitialLength(Range.Length, OS, DI.IsLittleEndian); + writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian); + writeInteger((uint32_t)Range.CuOffset, OS, DI.IsLittleEndian); + writeInteger((uint8_t)Range.AddrSize, OS, DI.IsLittleEndian); + writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian); + + auto HeaderSize = OS.tell() - HeaderStart; + auto FirstDescriptor = alignTo(HeaderSize, Range.AddrSize * 2); + ZeroFillBytes(OS, FirstDescriptor - HeaderSize); + + for (auto Descriptor : Range.Descriptors) { + writeVariableSizedInteger(Descriptor.Address, Range.AddrSize, OS, + DI.IsLittleEndian); + writeVariableSizedInteger(Descriptor.Length, Range.AddrSize, OS, + DI.IsLittleEndian); + } + ZeroFillBytes(OS, Range.AddrSize * 2); + } +} + +void DWARFYAML::EmitPubSection(raw_ostream &OS, + const DWARFYAML::PubSection &Sect, + bool IsLittleEndian) { + writeInitialLength(Sect.Length, OS, IsLittleEndian); + writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian); + writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian); + writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian); + for (auto Entry : Sect.Entries) { + writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian); + if (Sect.IsGNUStyle) + writeInteger((uint32_t)Entry.Descriptor, OS, IsLittleEndian); + OS.write(Entry.Name.data(), Entry.Name.size()); + OS.write('\0'); + } +} + +/// \brief An extension of the DWARFYAML::ConstVisitor which writes compile +/// units and DIEs to a stream. +class DumpVisitor : public DWARFYAML::ConstVisitor { + raw_ostream &OS; + +protected: + void onStartCompileUnit(const DWARFYAML::Unit &CU) override { + writeInitialLength(CU.Length, OS, DebugInfo.IsLittleEndian); + writeInteger((uint16_t)CU.Version, OS, DebugInfo.IsLittleEndian); + if(CU.Version >= 5) { + writeInteger((uint8_t)CU.Type, OS, DebugInfo.IsLittleEndian); + writeInteger((uint8_t)CU.AddrSize, OS, DebugInfo.IsLittleEndian); + writeInteger((uint32_t)CU.AbbrOffset, OS, DebugInfo.IsLittleEndian); + }else { + writeInteger((uint32_t)CU.AbbrOffset, OS, DebugInfo.IsLittleEndian); + writeInteger((uint8_t)CU.AddrSize, OS, DebugInfo.IsLittleEndian); + } + + } + + void onStartDIE(const DWARFYAML::Unit &CU, + const DWARFYAML::Entry &DIE) override { + encodeULEB128(DIE.AbbrCode, OS); + } + + void onValue(const uint8_t U) override { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const uint16_t U) override { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const uint32_t U) override { + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const uint64_t U, const bool LEB = false) override { + if (LEB) + encodeULEB128(U, OS); + else + writeInteger(U, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const int64_t S, const bool LEB = false) override { + if (LEB) + encodeSLEB128(S, OS); + else + writeInteger(S, OS, DebugInfo.IsLittleEndian); + } + + void onValue(const StringRef String) override { + OS.write(String.data(), String.size()); + OS.write('\0'); + } + + void onValue(const MemoryBufferRef MBR) override { + OS.write(MBR.getBufferStart(), MBR.getBufferSize()); + } + +public: + DumpVisitor(const DWARFYAML::Data &DI, raw_ostream &Out) + : DWARFYAML::ConstVisitor(DI), OS(Out) {} +}; + +void DWARFYAML::EmitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { + DumpVisitor Visitor(DI, OS); + Visitor.traverseDebugInfo(); +} + +static void EmitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) { + OS.write(File.Name.data(), File.Name.size()); + OS.write('\0'); + encodeULEB128(File.DirIdx, OS); + encodeULEB128(File.ModTime, OS); + encodeULEB128(File.Length, OS); +} + +void DWARFYAML::EmitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (const auto &LineTable : DI.DebugLines) { + writeInitialLength(LineTable.Length, OS, DI.IsLittleEndian); + uint64_t SizeOfPrologueLength = LineTable.Length.isDWARF64() ? 8 : 4; + writeInteger((uint16_t)LineTable.Version, OS, DI.IsLittleEndian); + writeVariableSizedInteger(LineTable.PrologueLength, SizeOfPrologueLength, + OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.MinInstLength, OS, DI.IsLittleEndian); + if (LineTable.Version >= 4) + writeInteger((uint8_t)LineTable.MaxOpsPerInst, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.DefaultIsStmt, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.LineBase, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.LineRange, OS, DI.IsLittleEndian); + writeInteger((uint8_t)LineTable.OpcodeBase, OS, DI.IsLittleEndian); + + for (auto OpcodeLength : LineTable.StandardOpcodeLengths) + writeInteger((uint8_t)OpcodeLength, OS, DI.IsLittleEndian); + + for (auto IncludeDir : LineTable.IncludeDirs) { + OS.write(IncludeDir.data(), IncludeDir.size()); + OS.write('\0'); + } + OS.write('\0'); + + for (auto File : LineTable.Files) + EmitFileEntry(OS, File); + OS.write('\0'); + + for (auto Op : LineTable.Opcodes) { + writeInteger((uint8_t)Op.Opcode, OS, DI.IsLittleEndian); + if (Op.Opcode == 0) { + encodeULEB128(Op.ExtLen, OS); + writeInteger((uint8_t)Op.SubOpcode, OS, DI.IsLittleEndian); + switch (Op.SubOpcode) { + case dwarf::DW_LNE_set_address: + case dwarf::DW_LNE_set_discriminator: + writeVariableSizedInteger(Op.Data, DI.CompileUnits[0].AddrSize, OS, + DI.IsLittleEndian); + break; + case dwarf::DW_LNE_define_file: + EmitFileEntry(OS, Op.FileEntry); + break; + case dwarf::DW_LNE_end_sequence: + break; + default: + for (auto OpByte : Op.UnknownOpcodeData) + writeInteger((uint8_t)OpByte, OS, DI.IsLittleEndian); + } + } else if (Op.Opcode < LineTable.OpcodeBase) { + switch (Op.Opcode) { + case dwarf::DW_LNS_copy: + case dwarf::DW_LNS_negate_stmt: + case dwarf::DW_LNS_set_basic_block: + case dwarf::DW_LNS_const_add_pc: + case dwarf::DW_LNS_set_prologue_end: + case dwarf::DW_LNS_set_epilogue_begin: + break; + + case dwarf::DW_LNS_advance_pc: + case dwarf::DW_LNS_set_file: + case dwarf::DW_LNS_set_column: + case dwarf::DW_LNS_set_isa: + encodeULEB128(Op.Data, OS); + break; + + case dwarf::DW_LNS_advance_line: + encodeSLEB128(Op.SData, OS); + break; + + case dwarf::DW_LNS_fixed_advance_pc: + writeInteger((uint16_t)Op.Data, OS, DI.IsLittleEndian); + break; + + default: + for (auto OpData : Op.StandardOpcodeData) { + encodeULEB128(OpData, OS); + } + } + } + } + } +} + +using EmitFuncType = void (*)(raw_ostream &, const DWARFYAML::Data &); + +static void +EmitDebugSectionImpl(const DWARFYAML::Data &DI, EmitFuncType EmitFunc, + StringRef Sec, + StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) { + std::string Data; + raw_string_ostream DebugInfoStream(Data); + EmitFunc(DebugInfoStream, DI); + DebugInfoStream.flush(); + if (!Data.empty()) + OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data); +} + +Expected<StringMap<std::unique_ptr<MemoryBuffer>>> +DWARFYAML::EmitDebugSections(StringRef YAMLString, + bool IsLittleEndian) { + StringMap<std::unique_ptr<MemoryBuffer>> DebugSections; + + yaml::Input YIn(YAMLString); + + DWARFYAML::Data DI; + DI.IsLittleEndian = IsLittleEndian; + YIn >> DI; + if (YIn.error()) + return errorCodeToError(YIn.error()); + + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugInfo, "debug_info", + DebugSections); + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugLine, "debug_line", + DebugSections); + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugStr, "debug_str", + DebugSections); + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAbbrev, "debug_abbrev", + DebugSections); + EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAranges, "debug_aranges", + DebugSections); + return std::move(DebugSections); +} diff --git a/contrib/llvm/lib/ObjectYAML/DWARFVisitor.cpp b/contrib/llvm/lib/ObjectYAML/DWARFVisitor.cpp new file mode 100644 index 0000000..36a9f76 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/DWARFVisitor.cpp @@ -0,0 +1,178 @@ +//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include "DWARFVisitor.h" +#include "llvm/ObjectYAML/DWARFYAML.h" + +using namespace llvm; + +template <typename T> +void DWARFYAML::VisitorImpl<T>::onVariableSizeValue(uint64_t U, unsigned Size) { + switch (Size) { + case 8: + onValue((uint64_t)U); + break; + case 4: + onValue((uint32_t)U); + break; + case 2: + onValue((uint16_t)U); + break; + case 1: + onValue((uint8_t)U); + break; + default: + llvm_unreachable("Invalid integer write size."); + } +} + +unsigned getOffsetSize(const DWARFYAML::Unit &Unit) { + return Unit.Length.isDWARF64() ? 8 : 4; +} + +unsigned getRefSize(const DWARFYAML::Unit &Unit) { + if (Unit.Version == 2) + return Unit.AddrSize; + return getOffsetSize(Unit); +} + +template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() { + for (auto &Unit : DebugInfo.CompileUnits) { + onStartCompileUnit(Unit); + auto FirstAbbrevCode = Unit.Entries[0].AbbrCode; + + for (auto &Entry : Unit.Entries) { + onStartDIE(Unit, Entry); + if (Entry.AbbrCode == 0u) + continue; + auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode]; + auto FormVal = Entry.Values.begin(); + auto AbbrForm = Abbrev.Attributes.begin(); + for (; + FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end(); + ++FormVal, ++AbbrForm) { + onForm(*AbbrForm, *FormVal); + dwarf::Form Form = AbbrForm->Form; + bool Indirect; + do { + Indirect = false; + switch (Form) { + case dwarf::DW_FORM_addr: + onVariableSizeValue(FormVal->Value, Unit.AddrSize); + break; + case dwarf::DW_FORM_ref_addr: + onVariableSizeValue(FormVal->Value, getRefSize(Unit)); + break; + case dwarf::DW_FORM_exprloc: + case dwarf::DW_FORM_block: + onValue((uint64_t)FormVal->BlockData.size(), true); + onValue( + MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], + FormVal->BlockData.size()), + "")); + break; + case dwarf::DW_FORM_block1: { + auto writeSize = FormVal->BlockData.size(); + onValue((uint8_t)writeSize); + onValue( + MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], + FormVal->BlockData.size()), + "")); + break; + } + case dwarf::DW_FORM_block2: { + auto writeSize = FormVal->BlockData.size(); + onValue((uint16_t)writeSize); + onValue( + MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], + FormVal->BlockData.size()), + "")); + break; + } + case dwarf::DW_FORM_block4: { + auto writeSize = FormVal->BlockData.size(); + onValue((uint32_t)writeSize); + onValue( + MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], + FormVal->BlockData.size()), + "")); + break; + } + case dwarf::DW_FORM_data1: + case dwarf::DW_FORM_ref1: + case dwarf::DW_FORM_flag: + case dwarf::DW_FORM_strx1: + case dwarf::DW_FORM_addrx1: + onValue((uint8_t)FormVal->Value); + break; + case dwarf::DW_FORM_data2: + case dwarf::DW_FORM_ref2: + case dwarf::DW_FORM_strx2: + case dwarf::DW_FORM_addrx2: + onValue((uint16_t)FormVal->Value); + break; + case dwarf::DW_FORM_data4: + case dwarf::DW_FORM_ref4: + case dwarf::DW_FORM_ref_sup4: + case dwarf::DW_FORM_strx4: + case dwarf::DW_FORM_addrx4: + onValue((uint32_t)FormVal->Value); + break; + case dwarf::DW_FORM_data8: + case dwarf::DW_FORM_ref8: + case dwarf::DW_FORM_ref_sup8: + onValue((uint64_t)FormVal->Value); + break; + case dwarf::DW_FORM_sdata: + onValue((int64_t)FormVal->Value, true); + break; + case dwarf::DW_FORM_udata: + case dwarf::DW_FORM_ref_udata: + onValue((uint64_t)FormVal->Value, true); + break; + case dwarf::DW_FORM_string: + onValue(FormVal->CStr); + break; + case dwarf::DW_FORM_indirect: + onValue((uint64_t)FormVal->Value, true); + Indirect = true; + Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value); + ++FormVal; + break; + case dwarf::DW_FORM_strp: + case dwarf::DW_FORM_sec_offset: + case dwarf::DW_FORM_GNU_ref_alt: + case dwarf::DW_FORM_GNU_strp_alt: + case dwarf::DW_FORM_line_strp: + case dwarf::DW_FORM_strp_sup: + onVariableSizeValue(FormVal->Value, getOffsetSize(Unit)); + break; + case dwarf::DW_FORM_ref_sig8: + onValue((uint64_t)FormVal->Value); + break; + case dwarf::DW_FORM_GNU_addr_index: + case dwarf::DW_FORM_GNU_str_index: + onValue((uint64_t)FormVal->Value, true); + break; + default: + break; + } + } while (Indirect); + } + onEndDIE(Unit, Entry); + } + onEndCompileUnit(Unit); + } +} + +// Explicitly instantiate the two template expansions. +template class DWARFYAML::VisitorImpl<DWARFYAML::Data>; +template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>; diff --git a/contrib/llvm/lib/ObjectYAML/DWARFVisitor.h b/contrib/llvm/lib/ObjectYAML/DWARFVisitor.h new file mode 100644 index 0000000..81ef412 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/DWARFVisitor.h @@ -0,0 +1,97 @@ +//===--- DWARFVisitor.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECTYAML_DWARFVISITOR_H +#define LLVM_OBJECTYAML_DWARFVISITOR_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/Support/MemoryBuffer.h" + +namespace llvm { + +namespace DWARFYAML { + +struct Data; +struct Unit; +struct Entry; +struct FormValue; +struct AttributeAbbrev; + +/// \brief A class to visits DWARFYAML Compile Units and DIEs in preorder. +/// +/// Extensions of this class can either maintain const or non-const references +/// to the DWARFYAML::Data object. +template <typename T> class VisitorImpl { +protected: + T &DebugInfo; + + /// Visitor Functions + /// @{ + virtual void onStartCompileUnit(Unit &CU) {} + virtual void onEndCompileUnit(Unit &CU) {} + virtual void onStartDIE(Unit &CU, Entry &DIE) {} + virtual void onEndDIE(Unit &CU, Entry &DIE) {} + virtual void onForm(AttributeAbbrev &AttAbbrev, FormValue &Value) {} + /// @} + + /// Const Visitor Functions + /// @{ + virtual void onStartCompileUnit(const Unit &CU) {} + virtual void onEndCompileUnit(const Unit &CU) {} + virtual void onStartDIE(const Unit &CU, const Entry &DIE) {} + virtual void onEndDIE(const Unit &CU, const Entry &DIE) {} + virtual void onForm(const AttributeAbbrev &AttAbbrev, + const FormValue &Value) {} + /// @} + + /// Value visitors + /// @{ + virtual void onValue(const uint8_t U) {} + virtual void onValue(const uint16_t U) {} + virtual void onValue(const uint32_t U) {} + virtual void onValue(const uint64_t U, const bool LEB = false) {} + virtual void onValue(const int64_t S, const bool LEB = false) {} + virtual void onValue(const StringRef String) {} + virtual void onValue(const MemoryBufferRef MBR) {} + /// @} + +public: + VisitorImpl(T &DI) : DebugInfo(DI) {} + + virtual ~VisitorImpl() {} + + void traverseDebugInfo(); + +private: + void onVariableSizeValue(uint64_t U, unsigned Size); +}; + +// Making the visior instantiations extern and explicit in the cpp file. This +// prevents them from being instantiated in every compile unit that uses the +// visitors. +extern template class VisitorImpl<DWARFYAML::Data>; +extern template class VisitorImpl<const DWARFYAML::Data>; + +class Visitor : public VisitorImpl<Data> { +public: + Visitor(Data &DI) : VisitorImpl<Data>(DI) {} +}; + +class ConstVisitor : public VisitorImpl<const Data> { +public: + ConstVisitor(const Data &DI) : VisitorImpl<const Data>(DI) {} +}; + +} // namespace DWARFYAML +} // namespace llvm + +#endif diff --git a/contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp b/contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp index 014e63f..d6c09e1 100644 --- a/contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/DWARFYAML.cpp @@ -54,6 +54,8 @@ void MappingTraits<DWARFYAML::AttributeAbbrev>::mapping( IO &IO, DWARFYAML::AttributeAbbrev &AttAbbrev) { IO.mapRequired("Attribute", AttAbbrev.Attribute); IO.mapRequired("Form", AttAbbrev.Form); + if(AttAbbrev.Form == dwarf::DW_FORM_implicit_const) + IO.mapRequired("Value", AttAbbrev.Value); } void MappingTraits<DWARFYAML::ARangeDescriptor>::mapping( @@ -97,6 +99,8 @@ void MappingTraits<DWARFYAML::PubSection>::mapping( void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) { IO.mapRequired("Length", Unit.Length); IO.mapRequired("Version", Unit.Version); + if (Unit.Version >= 5) + IO.mapRequired("UnitType", Unit.Type); IO.mapRequired("AbbrOffset", Unit.AbbrOffset); IO.mapRequired("AddrSize", Unit.AddrSize); IO.mapOptional("Entries", Unit.Entries); @@ -144,9 +148,7 @@ void MappingTraits<DWARFYAML::LineTableOpcode>::mapping( void MappingTraits<DWARFYAML::LineTable>::mapping( IO &IO, DWARFYAML::LineTable &LineTable) { - IO.mapRequired("TotalLength", LineTable.TotalLength); - if (LineTable.TotalLength == UINT32_MAX) - IO.mapRequired("TotalLength64", LineTable.TotalLength64); + IO.mapRequired("Length", LineTable.Length); IO.mapRequired("Version", LineTable.Version); IO.mapRequired("PrologueLength", LineTable.PrologueLength); IO.mapRequired("MinInstLength", LineTable.MinInstLength); @@ -162,6 +164,13 @@ void MappingTraits<DWARFYAML::LineTable>::mapping( IO.mapRequired("Opcodes", LineTable.Opcodes); } -} // namespace llvm::yaml +void MappingTraits<DWARFYAML::InitialLength>::mapping( + IO &IO, DWARFYAML::InitialLength &InitialLength) { + IO.mapRequired("TotalLength", InitialLength.TotalLength); + if (InitialLength.isDWARF64()) + IO.mapRequired("TotalLength64", InitialLength.TotalLength64); +} + +} // end namespace yaml -} // namespace llvm +} // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/ELFYAML.cpp b/contrib/llvm/lib/ObjectYAML/ELFYAML.cpp index fe9af9f..39741da 100644 --- a/contrib/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -12,240 +12,244 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/ELFYAML.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MipsABIFlags.h" +#include "llvm/Support/YAMLTraits.h" +#include <cassert> +#include <cstdint> namespace llvm { -ELFYAML::Section::~Section() {} +ELFYAML::Section::~Section() = default; namespace yaml { -void -ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(IO &IO, - ELFYAML::ELF_ET &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(ET_NONE) - ECase(ET_REL) - ECase(ET_EXEC) - ECase(ET_DYN) - ECase(ET_CORE) +void ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration( + IO &IO, ELFYAML::ELF_ET &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(ET_NONE); + ECase(ET_REL); + ECase(ET_EXEC); + ECase(ET_DYN); + ECase(ET_CORE); #undef ECase IO.enumFallback<Hex16>(Value); } -void -ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(IO &IO, - ELFYAML::ELF_EM &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(EM_NONE) - ECase(EM_M32) - ECase(EM_SPARC) - ECase(EM_386) - ECase(EM_68K) - ECase(EM_88K) - ECase(EM_IAMCU) - ECase(EM_860) - ECase(EM_MIPS) - ECase(EM_S370) - ECase(EM_MIPS_RS3_LE) - ECase(EM_PARISC) - ECase(EM_VPP500) - ECase(EM_SPARC32PLUS) - ECase(EM_960) - ECase(EM_PPC) - ECase(EM_PPC64) - ECase(EM_S390) - ECase(EM_SPU) - ECase(EM_V800) - ECase(EM_FR20) - ECase(EM_RH32) - ECase(EM_RCE) - ECase(EM_ARM) - ECase(EM_ALPHA) - ECase(EM_SH) - ECase(EM_SPARCV9) - ECase(EM_TRICORE) - ECase(EM_ARC) - ECase(EM_H8_300) - ECase(EM_H8_300H) - ECase(EM_H8S) - ECase(EM_H8_500) - ECase(EM_IA_64) - ECase(EM_MIPS_X) - ECase(EM_COLDFIRE) - ECase(EM_68HC12) - ECase(EM_MMA) - ECase(EM_PCP) - ECase(EM_NCPU) - ECase(EM_NDR1) - ECase(EM_STARCORE) - ECase(EM_ME16) - ECase(EM_ST100) - ECase(EM_TINYJ) - ECase(EM_X86_64) - ECase(EM_PDSP) - ECase(EM_PDP10) - ECase(EM_PDP11) - ECase(EM_FX66) - ECase(EM_ST9PLUS) - ECase(EM_ST7) - ECase(EM_68HC16) - ECase(EM_68HC11) - ECase(EM_68HC08) - ECase(EM_68HC05) - ECase(EM_SVX) - ECase(EM_ST19) - ECase(EM_VAX) - ECase(EM_CRIS) - ECase(EM_JAVELIN) - ECase(EM_FIREPATH) - ECase(EM_ZSP) - ECase(EM_MMIX) - ECase(EM_HUANY) - ECase(EM_PRISM) - ECase(EM_AVR) - ECase(EM_FR30) - ECase(EM_D10V) - ECase(EM_D30V) - ECase(EM_V850) - ECase(EM_M32R) - ECase(EM_MN10300) - ECase(EM_MN10200) - ECase(EM_PJ) - ECase(EM_OPENRISC) - ECase(EM_ARC_COMPACT) - ECase(EM_XTENSA) - ECase(EM_VIDEOCORE) - ECase(EM_TMM_GPP) - ECase(EM_NS32K) - ECase(EM_TPC) - ECase(EM_SNP1K) - ECase(EM_ST200) - ECase(EM_IP2K) - ECase(EM_MAX) - ECase(EM_CR) - ECase(EM_F2MC16) - ECase(EM_MSP430) - ECase(EM_BLACKFIN) - ECase(EM_SE_C33) - ECase(EM_SEP) - ECase(EM_ARCA) - ECase(EM_UNICORE) - ECase(EM_EXCESS) - ECase(EM_DXP) - ECase(EM_ALTERA_NIOS2) - ECase(EM_CRX) - ECase(EM_XGATE) - ECase(EM_C166) - ECase(EM_M16C) - ECase(EM_DSPIC30F) - ECase(EM_CE) - ECase(EM_M32C) - ECase(EM_TSK3000) - ECase(EM_RS08) - ECase(EM_SHARC) - ECase(EM_ECOG2) - ECase(EM_SCORE7) - ECase(EM_DSP24) - ECase(EM_VIDEOCORE3) - ECase(EM_LATTICEMICO32) - ECase(EM_SE_C17) - ECase(EM_TI_C6000) - ECase(EM_TI_C2000) - ECase(EM_TI_C5500) - ECase(EM_MMDSP_PLUS) - ECase(EM_CYPRESS_M8C) - ECase(EM_R32C) - ECase(EM_TRIMEDIA) - ECase(EM_HEXAGON) - ECase(EM_8051) - ECase(EM_STXP7X) - ECase(EM_NDS32) - ECase(EM_ECOG1) - ECase(EM_ECOG1X) - ECase(EM_MAXQ30) - ECase(EM_XIMO16) - ECase(EM_MANIK) - ECase(EM_CRAYNV2) - ECase(EM_RX) - ECase(EM_METAG) - ECase(EM_MCST_ELBRUS) - ECase(EM_ECOG16) - ECase(EM_CR16) - ECase(EM_ETPU) - ECase(EM_SLE9X) - ECase(EM_L10M) - ECase(EM_K10M) - ECase(EM_AARCH64) - ECase(EM_AVR32) - ECase(EM_STM8) - ECase(EM_TILE64) - ECase(EM_TILEPRO) - ECase(EM_CUDA) - ECase(EM_TILEGX) - ECase(EM_CLOUDSHIELD) - ECase(EM_COREA_1ST) - ECase(EM_COREA_2ND) - ECase(EM_ARC_COMPACT2) - ECase(EM_OPEN8) - ECase(EM_RL78) - ECase(EM_VIDEOCORE5) - ECase(EM_78KOR) - ECase(EM_56800EX) - ECase(EM_AMDGPU) - ECase(EM_RISCV) - ECase(EM_LANAI) - ECase(EM_BPF) +void ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration( + IO &IO, ELFYAML::ELF_EM &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(EM_NONE); + ECase(EM_M32); + ECase(EM_SPARC); + ECase(EM_386); + ECase(EM_68K); + ECase(EM_88K); + ECase(EM_IAMCU); + ECase(EM_860); + ECase(EM_MIPS); + ECase(EM_S370); + ECase(EM_MIPS_RS3_LE); + ECase(EM_PARISC); + ECase(EM_VPP500); + ECase(EM_SPARC32PLUS); + ECase(EM_960); + ECase(EM_PPC); + ECase(EM_PPC64); + ECase(EM_S390); + ECase(EM_SPU); + ECase(EM_V800); + ECase(EM_FR20); + ECase(EM_RH32); + ECase(EM_RCE); + ECase(EM_ARM); + ECase(EM_ALPHA); + ECase(EM_SH); + ECase(EM_SPARCV9); + ECase(EM_TRICORE); + ECase(EM_ARC); + ECase(EM_H8_300); + ECase(EM_H8_300H); + ECase(EM_H8S); + ECase(EM_H8_500); + ECase(EM_IA_64); + ECase(EM_MIPS_X); + ECase(EM_COLDFIRE); + ECase(EM_68HC12); + ECase(EM_MMA); + ECase(EM_PCP); + ECase(EM_NCPU); + ECase(EM_NDR1); + ECase(EM_STARCORE); + ECase(EM_ME16); + ECase(EM_ST100); + ECase(EM_TINYJ); + ECase(EM_X86_64); + ECase(EM_PDSP); + ECase(EM_PDP10); + ECase(EM_PDP11); + ECase(EM_FX66); + ECase(EM_ST9PLUS); + ECase(EM_ST7); + ECase(EM_68HC16); + ECase(EM_68HC11); + ECase(EM_68HC08); + ECase(EM_68HC05); + ECase(EM_SVX); + ECase(EM_ST19); + ECase(EM_VAX); + ECase(EM_CRIS); + ECase(EM_JAVELIN); + ECase(EM_FIREPATH); + ECase(EM_ZSP); + ECase(EM_MMIX); + ECase(EM_HUANY); + ECase(EM_PRISM); + ECase(EM_AVR); + ECase(EM_FR30); + ECase(EM_D10V); + ECase(EM_D30V); + ECase(EM_V850); + ECase(EM_M32R); + ECase(EM_MN10300); + ECase(EM_MN10200); + ECase(EM_PJ); + ECase(EM_OPENRISC); + ECase(EM_ARC_COMPACT); + ECase(EM_XTENSA); + ECase(EM_VIDEOCORE); + ECase(EM_TMM_GPP); + ECase(EM_NS32K); + ECase(EM_TPC); + ECase(EM_SNP1K); + ECase(EM_ST200); + ECase(EM_IP2K); + ECase(EM_MAX); + ECase(EM_CR); + ECase(EM_F2MC16); + ECase(EM_MSP430); + ECase(EM_BLACKFIN); + ECase(EM_SE_C33); + ECase(EM_SEP); + ECase(EM_ARCA); + ECase(EM_UNICORE); + ECase(EM_EXCESS); + ECase(EM_DXP); + ECase(EM_ALTERA_NIOS2); + ECase(EM_CRX); + ECase(EM_XGATE); + ECase(EM_C166); + ECase(EM_M16C); + ECase(EM_DSPIC30F); + ECase(EM_CE); + ECase(EM_M32C); + ECase(EM_TSK3000); + ECase(EM_RS08); + ECase(EM_SHARC); + ECase(EM_ECOG2); + ECase(EM_SCORE7); + ECase(EM_DSP24); + ECase(EM_VIDEOCORE3); + ECase(EM_LATTICEMICO32); + ECase(EM_SE_C17); + ECase(EM_TI_C6000); + ECase(EM_TI_C2000); + ECase(EM_TI_C5500); + ECase(EM_MMDSP_PLUS); + ECase(EM_CYPRESS_M8C); + ECase(EM_R32C); + ECase(EM_TRIMEDIA); + ECase(EM_HEXAGON); + ECase(EM_8051); + ECase(EM_STXP7X); + ECase(EM_NDS32); + ECase(EM_ECOG1); + ECase(EM_ECOG1X); + ECase(EM_MAXQ30); + ECase(EM_XIMO16); + ECase(EM_MANIK); + ECase(EM_CRAYNV2); + ECase(EM_RX); + ECase(EM_METAG); + ECase(EM_MCST_ELBRUS); + ECase(EM_ECOG16); + ECase(EM_CR16); + ECase(EM_ETPU); + ECase(EM_SLE9X); + ECase(EM_L10M); + ECase(EM_K10M); + ECase(EM_AARCH64); + ECase(EM_AVR32); + ECase(EM_STM8); + ECase(EM_TILE64); + ECase(EM_TILEPRO); + ECase(EM_CUDA); + ECase(EM_TILEGX); + ECase(EM_CLOUDSHIELD); + ECase(EM_COREA_1ST); + ECase(EM_COREA_2ND); + ECase(EM_ARC_COMPACT2); + ECase(EM_OPEN8); + ECase(EM_RL78); + ECase(EM_VIDEOCORE5); + ECase(EM_78KOR); + ECase(EM_56800EX); + ECase(EM_AMDGPU); + ECase(EM_RISCV); + ECase(EM_LANAI); + ECase(EM_BPF); #undef ECase } void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration( IO &IO, ELFYAML::ELF_ELFCLASS &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); +#define ECase(X) IO.enumCase(Value, #X, ELF::X) // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it // here. - ECase(ELFCLASS32) - ECase(ELFCLASS64) + ECase(ELFCLASS32); + ECase(ELFCLASS64); #undef ECase } void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration( IO &IO, ELFYAML::ELF_ELFDATA &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); +#define ECase(X) IO.enumCase(Value, #X, ELF::X) // Since the semantics of ELFDATANONE is "invalid", just don't accept it // here. - ECase(ELFDATA2LSB) - ECase(ELFDATA2MSB) + ECase(ELFDATA2LSB); + ECase(ELFDATA2MSB); #undef ECase } void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration( IO &IO, ELFYAML::ELF_ELFOSABI &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(ELFOSABI_NONE) - ECase(ELFOSABI_HPUX) - ECase(ELFOSABI_NETBSD) - ECase(ELFOSABI_GNU) - ECase(ELFOSABI_GNU) - ECase(ELFOSABI_HURD) - ECase(ELFOSABI_SOLARIS) - ECase(ELFOSABI_AIX) - ECase(ELFOSABI_IRIX) - ECase(ELFOSABI_FREEBSD) - ECase(ELFOSABI_TRU64) - ECase(ELFOSABI_MODESTO) - ECase(ELFOSABI_OPENBSD) - ECase(ELFOSABI_OPENVMS) - ECase(ELFOSABI_NSK) - ECase(ELFOSABI_AROS) - ECase(ELFOSABI_FENIXOS) - ECase(ELFOSABI_CLOUDABI) - ECase(ELFOSABI_C6000_ELFABI) - ECase(ELFOSABI_AMDGPU_HSA) - ECase(ELFOSABI_C6000_LINUX) - ECase(ELFOSABI_ARM) - ECase(ELFOSABI_STANDALONE) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(ELFOSABI_NONE); + ECase(ELFOSABI_HPUX); + ECase(ELFOSABI_NETBSD); + ECase(ELFOSABI_GNU); + ECase(ELFOSABI_GNU); + ECase(ELFOSABI_HURD); + ECase(ELFOSABI_SOLARIS); + ECase(ELFOSABI_AIX); + ECase(ELFOSABI_IRIX); + ECase(ELFOSABI_FREEBSD); + ECase(ELFOSABI_TRU64); + ECase(ELFOSABI_MODESTO); + ECase(ELFOSABI_OPENBSD); + ECase(ELFOSABI_OPENVMS); + ECase(ELFOSABI_NSK); + ECase(ELFOSABI_AROS); + ECase(ELFOSABI_FENIXOS); + ECase(ELFOSABI_CLOUDABI); + ECase(ELFOSABI_C6000_ELFABI); + ECase(ELFOSABI_AMDGPU_HSA); + ECase(ELFOSABI_C6000_LINUX); + ECase(ELFOSABI_ARM); + ECase(ELFOSABI_STANDALONE); #undef ECase } @@ -253,92 +257,92 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO, ELFYAML::ELF_EF &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); assert(Object && "The IO context is not initialized"); -#define BCase(X) IO.bitSetCase(Value, #X, ELF::X); -#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M); +#define BCase(X) IO.bitSetCase(Value, #X, ELF::X) +#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M) switch (Object->Header.Machine) { case ELF::EM_ARM: - BCase(EF_ARM_SOFT_FLOAT) - BCase(EF_ARM_VFP_FLOAT) - BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK) - BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK) + BCase(EF_ARM_SOFT_FLOAT); + BCase(EF_ARM_VFP_FLOAT); + BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK); + BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK); break; case ELF::EM_MIPS: - BCase(EF_MIPS_NOREORDER) - BCase(EF_MIPS_PIC) - BCase(EF_MIPS_CPIC) - BCase(EF_MIPS_ABI2) - BCase(EF_MIPS_32BITMODE) - BCase(EF_MIPS_FP64) - BCase(EF_MIPS_NAN2008) - BCase(EF_MIPS_MICROMIPS) - BCase(EF_MIPS_ARCH_ASE_M16) - BCase(EF_MIPS_ARCH_ASE_MDMX) - BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI) - BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI) - BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI) - BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI) - BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH) - BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH) - BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH) - BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH) + BCase(EF_MIPS_NOREORDER); + BCase(EF_MIPS_PIC); + BCase(EF_MIPS_CPIC); + BCase(EF_MIPS_ABI2); + BCase(EF_MIPS_32BITMODE); + BCase(EF_MIPS_FP64); + BCase(EF_MIPS_NAN2008); + BCase(EF_MIPS_MICROMIPS); + BCase(EF_MIPS_ARCH_ASE_M16); + BCase(EF_MIPS_ARCH_ASE_MDMX); + BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI); + BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI); + BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI); + BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI); + BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH); + BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH); + BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH); + BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH); break; case ELF::EM_HEXAGON: - BCase(EF_HEXAGON_MACH_V2) - BCase(EF_HEXAGON_MACH_V3) - BCase(EF_HEXAGON_MACH_V4) - BCase(EF_HEXAGON_MACH_V5) - BCase(EF_HEXAGON_ISA_V2) - BCase(EF_HEXAGON_ISA_V3) - BCase(EF_HEXAGON_ISA_V4) - BCase(EF_HEXAGON_ISA_V5) + BCase(EF_HEXAGON_MACH_V2); + BCase(EF_HEXAGON_MACH_V3); + BCase(EF_HEXAGON_MACH_V4); + BCase(EF_HEXAGON_MACH_V5); + BCase(EF_HEXAGON_ISA_V2); + BCase(EF_HEXAGON_ISA_V3); + BCase(EF_HEXAGON_ISA_V4); + BCase(EF_HEXAGON_ISA_V5); break; case ELF::EM_AVR: - BCase(EF_AVR_ARCH_AVR1) - BCase(EF_AVR_ARCH_AVR2) - BCase(EF_AVR_ARCH_AVR25) - BCase(EF_AVR_ARCH_AVR3) - BCase(EF_AVR_ARCH_AVR31) - BCase(EF_AVR_ARCH_AVR35) - BCase(EF_AVR_ARCH_AVR4) - BCase(EF_AVR_ARCH_AVR51) - BCase(EF_AVR_ARCH_AVR6) - BCase(EF_AVR_ARCH_AVRTINY) - BCase(EF_AVR_ARCH_XMEGA1) - BCase(EF_AVR_ARCH_XMEGA2) - BCase(EF_AVR_ARCH_XMEGA3) - BCase(EF_AVR_ARCH_XMEGA4) - BCase(EF_AVR_ARCH_XMEGA5) - BCase(EF_AVR_ARCH_XMEGA6) - BCase(EF_AVR_ARCH_XMEGA7) + BCase(EF_AVR_ARCH_AVR1); + BCase(EF_AVR_ARCH_AVR2); + BCase(EF_AVR_ARCH_AVR25); + BCase(EF_AVR_ARCH_AVR3); + BCase(EF_AVR_ARCH_AVR31); + BCase(EF_AVR_ARCH_AVR35); + BCase(EF_AVR_ARCH_AVR4); + BCase(EF_AVR_ARCH_AVR51); + BCase(EF_AVR_ARCH_AVR6); + BCase(EF_AVR_ARCH_AVRTINY); + BCase(EF_AVR_ARCH_XMEGA1); + BCase(EF_AVR_ARCH_XMEGA2); + BCase(EF_AVR_ARCH_XMEGA3); + BCase(EF_AVR_ARCH_XMEGA4); + BCase(EF_AVR_ARCH_XMEGA5); + BCase(EF_AVR_ARCH_XMEGA6); + BCase(EF_AVR_ARCH_XMEGA7); break; case ELF::EM_AMDGPU: case ELF::EM_X86_64: @@ -354,51 +358,52 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration( IO &IO, ELFYAML::ELF_SHT &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); assert(Object && "The IO context is not initialized"); -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(SHT_NULL) - ECase(SHT_PROGBITS) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(SHT_NULL); + ECase(SHT_PROGBITS); // No SHT_SYMTAB. Use the top-level `Symbols` key instead. // FIXME: Issue a diagnostic with this information. - ECase(SHT_STRTAB) - ECase(SHT_RELA) - ECase(SHT_HASH) - ECase(SHT_DYNAMIC) - ECase(SHT_NOTE) - ECase(SHT_NOBITS) - ECase(SHT_REL) - ECase(SHT_SHLIB) - ECase(SHT_DYNSYM) - ECase(SHT_INIT_ARRAY) - ECase(SHT_FINI_ARRAY) - ECase(SHT_PREINIT_ARRAY) - ECase(SHT_GROUP) - ECase(SHT_SYMTAB_SHNDX) - ECase(SHT_LOOS) - ECase(SHT_GNU_ATTRIBUTES) - ECase(SHT_GNU_HASH) - ECase(SHT_GNU_verdef) - ECase(SHT_GNU_verneed) - ECase(SHT_GNU_versym) - ECase(SHT_HIOS) - ECase(SHT_LOPROC) + ECase(SHT_STRTAB); + ECase(SHT_RELA); + ECase(SHT_HASH); + ECase(SHT_DYNAMIC); + ECase(SHT_NOTE); + ECase(SHT_NOBITS); + ECase(SHT_REL); + ECase(SHT_SHLIB); + ECase(SHT_DYNSYM); + ECase(SHT_INIT_ARRAY); + ECase(SHT_FINI_ARRAY); + ECase(SHT_PREINIT_ARRAY); + ECase(SHT_GROUP); + ECase(SHT_SYMTAB_SHNDX); + ECase(SHT_LOOS); + ECase(SHT_LLVM_ODRTAB); + ECase(SHT_GNU_ATTRIBUTES); + ECase(SHT_GNU_HASH); + ECase(SHT_GNU_verdef); + ECase(SHT_GNU_verneed); + ECase(SHT_GNU_versym); + ECase(SHT_HIOS); + ECase(SHT_LOPROC); switch (Object->Header.Machine) { case ELF::EM_ARM: - ECase(SHT_ARM_EXIDX) - ECase(SHT_ARM_PREEMPTMAP) - ECase(SHT_ARM_ATTRIBUTES) - ECase(SHT_ARM_DEBUGOVERLAY) - ECase(SHT_ARM_OVERLAYSECTION) + ECase(SHT_ARM_EXIDX); + ECase(SHT_ARM_PREEMPTMAP); + ECase(SHT_ARM_ATTRIBUTES); + ECase(SHT_ARM_DEBUGOVERLAY); + ECase(SHT_ARM_OVERLAYSECTION); break; case ELF::EM_HEXAGON: - ECase(SHT_HEX_ORDERED) + ECase(SHT_HEX_ORDERED); break; case ELF::EM_X86_64: - ECase(SHT_X86_64_UNWIND) + ECase(SHT_X86_64_UNWIND); break; case ELF::EM_MIPS: - ECase(SHT_MIPS_REGINFO) - ECase(SHT_MIPS_OPTIONS) - ECase(SHT_MIPS_ABIFLAGS) + ECase(SHT_MIPS_REGINFO); + ECase(SHT_MIPS_OPTIONS); + ECase(SHT_MIPS_ABIFLAGS); break; default: // Nothing to do. @@ -410,43 +415,37 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration( void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO, ELFYAML::ELF_SHF &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); -#define BCase(X) IO.bitSetCase(Value, #X, ELF::X); - BCase(SHF_WRITE) - BCase(SHF_ALLOC) - BCase(SHF_EXCLUDE) - BCase(SHF_EXECINSTR) - BCase(SHF_MERGE) - BCase(SHF_STRINGS) - BCase(SHF_INFO_LINK) - BCase(SHF_LINK_ORDER) - BCase(SHF_OS_NONCONFORMING) - BCase(SHF_GROUP) - BCase(SHF_TLS) - switch(Object->Header.Machine) { +#define BCase(X) IO.bitSetCase(Value, #X, ELF::X) + BCase(SHF_WRITE); + BCase(SHF_ALLOC); + BCase(SHF_EXCLUDE); + BCase(SHF_EXECINSTR); + BCase(SHF_MERGE); + BCase(SHF_STRINGS); + BCase(SHF_INFO_LINK); + BCase(SHF_LINK_ORDER); + BCase(SHF_OS_NONCONFORMING); + BCase(SHF_GROUP); + BCase(SHF_TLS); + switch (Object->Header.Machine) { case ELF::EM_ARM: - BCase(SHF_ARM_PURECODE) - break; - case ELF::EM_AMDGPU: - BCase(SHF_AMDGPU_HSA_GLOBAL) - BCase(SHF_AMDGPU_HSA_READONLY) - BCase(SHF_AMDGPU_HSA_CODE) - BCase(SHF_AMDGPU_HSA_AGENT) + BCase(SHF_ARM_PURECODE); break; case ELF::EM_HEXAGON: - BCase(SHF_HEX_GPREL) + BCase(SHF_HEX_GPREL); break; case ELF::EM_MIPS: - BCase(SHF_MIPS_NODUPES) - BCase(SHF_MIPS_NAMES) - BCase(SHF_MIPS_LOCAL) - BCase(SHF_MIPS_NOSTRIP) - BCase(SHF_MIPS_GPREL) - BCase(SHF_MIPS_MERGE) - BCase(SHF_MIPS_ADDR) - BCase(SHF_MIPS_STRING) + BCase(SHF_MIPS_NODUPES); + BCase(SHF_MIPS_NAMES); + BCase(SHF_MIPS_LOCAL); + BCase(SHF_MIPS_NOSTRIP); + BCase(SHF_MIPS_GPREL); + BCase(SHF_MIPS_MERGE); + BCase(SHF_MIPS_ADDR); + BCase(SHF_MIPS_STRING); break; case ELF::EM_X86_64: - BCase(SHF_X86_64_LARGE) + BCase(SHF_X86_64_LARGE); break; default: // Nothing to do. @@ -457,25 +456,25 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO, void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration( IO &IO, ELFYAML::ELF_STT &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(STT_NOTYPE) - ECase(STT_OBJECT) - ECase(STT_FUNC) - ECase(STT_SECTION) - ECase(STT_FILE) - ECase(STT_COMMON) - ECase(STT_TLS) - ECase(STT_GNU_IFUNC) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(STT_NOTYPE); + ECase(STT_OBJECT); + ECase(STT_FUNC); + ECase(STT_SECTION); + ECase(STT_FILE); + ECase(STT_COMMON); + ECase(STT_TLS); + ECase(STT_GNU_IFUNC); #undef ECase } void ScalarEnumerationTraits<ELFYAML::ELF_STV>::enumeration( IO &IO, ELFYAML::ELF_STV &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(STV_DEFAULT) - ECase(STV_INTERNAL) - ECase(STV_HIDDEN) - ECase(STV_PROTECTED) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(STV_DEFAULT); + ECase(STV_INTERNAL); + ECase(STV_HIDDEN); + ECase(STV_PROTECTED); #undef ECase } @@ -483,13 +482,13 @@ void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO, ELFYAML::ELF_STO &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); assert(Object && "The IO context is not initialized"); -#define BCase(X) IO.bitSetCase(Value, #X, ELF::X); +#define BCase(X) IO.bitSetCase(Value, #X, ELF::X) switch (Object->Header.Machine) { case ELF::EM_MIPS: - BCase(STO_MIPS_OPTIONAL) - BCase(STO_MIPS_PLT) - BCase(STO_MIPS_PIC) - BCase(STO_MIPS_MICROMIPS) + BCase(STO_MIPS_OPTIONAL); + BCase(STO_MIPS_PLT); + BCase(STO_MIPS_PIC); + BCase(STO_MIPS_MICROMIPS); break; default: break; // Nothing to do @@ -500,11 +499,11 @@ void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO, void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration( IO &IO, ELFYAML::ELF_RSS &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X); - ECase(RSS_UNDEF) - ECase(RSS_GP) - ECase(RSS_GP0) - ECase(RSS_LOC) +#define ECase(X) IO.enumCase(Value, #X, ELF::X) + ECase(RSS_UNDEF); + ECase(RSS_GP); + ECase(RSS_GP0); + ECase(RSS_LOC); #undef ECase } @@ -515,89 +514,90 @@ void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration( #define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X); switch (Object->Header.Machine) { case ELF::EM_X86_64: -#include "llvm/Support/ELFRelocs/x86_64.def" +#include "llvm/BinaryFormat/ELFRelocs/x86_64.def" break; case ELF::EM_MIPS: -#include "llvm/Support/ELFRelocs/Mips.def" +#include "llvm/BinaryFormat/ELFRelocs/Mips.def" break; case ELF::EM_HEXAGON: -#include "llvm/Support/ELFRelocs/Hexagon.def" +#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def" break; case ELF::EM_386: case ELF::EM_IAMCU: -#include "llvm/Support/ELFRelocs/i386.def" +#include "llvm/BinaryFormat/ELFRelocs/i386.def" break; case ELF::EM_AARCH64: -#include "llvm/Support/ELFRelocs/AArch64.def" +#include "llvm/BinaryFormat/ELFRelocs/AArch64.def" break; case ELF::EM_ARM: -#include "llvm/Support/ELFRelocs/ARM.def" +#include "llvm/BinaryFormat/ELFRelocs/ARM.def" break; case ELF::EM_RISCV: -#include "llvm/Support/ELFRelocs/RISCV.def" +#include "llvm/BinaryFormat/ELFRelocs/RISCV.def" break; case ELF::EM_LANAI: -#include "llvm/Support/ELFRelocs/Lanai.def" +#include "llvm/BinaryFormat/ELFRelocs/Lanai.def" break; case ELF::EM_AMDGPU: -#include "llvm/Support/ELFRelocs/AMDGPU.def" +#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def" break; case ELF::EM_BPF: -#include "llvm/Support/ELFRelocs/BPF.def" +#include "llvm/BinaryFormat/ELFRelocs/BPF.def" break; default: llvm_unreachable("Unsupported architecture"); } #undef ELF_RELOC + IO.enumFallback<Hex32>(Value); } void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration( IO &IO, ELFYAML::MIPS_AFL_REG &Value) { -#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X); - ECase(REG_NONE) - ECase(REG_32) - ECase(REG_64) - ECase(REG_128) +#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X) + ECase(REG_NONE); + ECase(REG_32); + ECase(REG_64); + ECase(REG_128); #undef ECase } void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration( IO &IO, ELFYAML::MIPS_ABI_FP &Value) { -#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X); - ECase(FP_ANY) - ECase(FP_DOUBLE) - ECase(FP_SINGLE) - ECase(FP_SOFT) - ECase(FP_OLD_64) - ECase(FP_XX) - ECase(FP_64) - ECase(FP_64A) +#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X) + ECase(FP_ANY); + ECase(FP_DOUBLE); + ECase(FP_SINGLE); + ECase(FP_SOFT); + ECase(FP_OLD_64); + ECase(FP_XX); + ECase(FP_64); + ECase(FP_64A); #undef ECase } void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration( IO &IO, ELFYAML::MIPS_AFL_EXT &Value) { -#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X); - ECase(EXT_NONE) - ECase(EXT_XLR) - ECase(EXT_OCTEON2) - ECase(EXT_OCTEONP) - ECase(EXT_LOONGSON_3A) - ECase(EXT_OCTEON) - ECase(EXT_5900) - ECase(EXT_4650) - ECase(EXT_4010) - ECase(EXT_4100) - ECase(EXT_3900) - ECase(EXT_10000) - ECase(EXT_SB1) - ECase(EXT_4111) - ECase(EXT_4120) - ECase(EXT_5400) - ECase(EXT_5500) - ECase(EXT_LOONGSON_2E) - ECase(EXT_LOONGSON_2F) - ECase(EXT_OCTEON3) +#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X) + ECase(EXT_NONE); + ECase(EXT_XLR); + ECase(EXT_OCTEON2); + ECase(EXT_OCTEONP); + ECase(EXT_LOONGSON_3A); + ECase(EXT_OCTEON); + ECase(EXT_5900); + ECase(EXT_4650); + ECase(EXT_4010); + ECase(EXT_4100); + ECase(EXT_3900); + ECase(EXT_10000); + ECase(EXT_SB1); + ECase(EXT_4111); + ECase(EXT_4120); + ECase(EXT_5400); + ECase(EXT_5500); + ECase(EXT_LOONGSON_2E); + ECase(EXT_LOONGSON_2F); + ECase(EXT_OCTEON3); #undef ECase } @@ -614,27 +614,27 @@ void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration( void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset( IO &IO, ELFYAML::MIPS_AFL_ASE &Value) { -#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X); - BCase(DSP) - BCase(DSPR2) - BCase(EVA) - BCase(MCU) - BCase(MDMX) - BCase(MIPS3D) - BCase(MT) - BCase(SMARTMIPS) - BCase(VIRT) - BCase(MSA) - BCase(MIPS16) - BCase(MICROMIPS) - BCase(XPA) +#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X) + BCase(DSP); + BCase(DSPR2); + BCase(EVA); + BCase(MCU); + BCase(MDMX); + BCase(MIPS3D); + BCase(MT); + BCase(SMARTMIPS); + BCase(VIRT); + BCase(MSA); + BCase(MIPS16); + BCase(MICROMIPS); + BCase(XPA); #undef BCase } void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset( IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) { -#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X); - BCase(ODDSPREG) +#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X) + BCase(ODDSPREG); #undef BCase } @@ -650,6 +650,7 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO, } namespace { + struct NormalizedOther { NormalizedOther(IO &) : Visibility(ELFYAML::ELF_STV(0)), Other(ELFYAML::ELF_STO(0)) {} @@ -661,7 +662,8 @@ struct NormalizedOther { ELFYAML::ELF_STV Visibility; ELFYAML::ELF_STO Other; }; -} + +} // end anonymous namespace void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) { IO.mapOptional("Name", Symbol.Name, StringRef()); @@ -784,6 +786,7 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate( } namespace { + struct NormalizedMips64RelType { NormalizedMips64RelType(IO &) : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)), @@ -804,7 +807,8 @@ struct NormalizedMips64RelType { ELFYAML::ELF_REL Type3; ELFYAML::ELF_RSS SpecSym; }; -} + +} // end anonymous namespace void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO, ELFYAML::Relocation &Rel) { @@ -845,4 +849,5 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE) LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1) } // end namespace yaml + } // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/MachOYAML.cpp b/contrib/llvm/lib/ObjectYAML/MachOYAML.cpp index a033a79..ab452a7 100644 --- a/contrib/llvm/lib/ObjectYAML/MachOYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/MachOYAML.cpp @@ -12,16 +12,19 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/MachOYAML.h" -#include "llvm/Support/Casting.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/MachO.h" #include "llvm/Support/Format.h" #include "llvm/Support/Host.h" -#include "llvm/Support/MachO.h" - -#include <string.h> // For memcpy, memset and strnlen. +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include <cinttypes> +#include <cstdint> +#include <cstring> namespace llvm { -MachOYAML::LoadCommand::~LoadCommand() {} +MachOYAML::LoadCommand::~LoadCommand() = default; bool MachOYAML::LinkEditData::isEmpty() const { return 0 == @@ -33,7 +36,7 @@ bool MachOYAML::LinkEditData::isEmpty() const { namespace yaml { void ScalarTraits<char_16>::output(const char_16 &Val, void *, - llvm::raw_ostream &Out) { + raw_ostream &Out) { auto Len = strnlen(&Val[0], 16); Out << StringRef(&Val[0], Len); } @@ -51,8 +54,7 @@ StringRef ScalarTraits<char_16>::input(StringRef Scalar, void *, char_16 &Val) { bool ScalarTraits<char_16>::mustQuote(StringRef S) { return needsQuotes(S); } -void ScalarTraits<uuid_t>::output(const uuid_t &Val, void *, - llvm::raw_ostream &Out) { +void ScalarTraits<uuid_t>::output(const uuid_t &Val, void *, raw_ostream &Out) { for (int Idx = 0; Idx < 16; ++Idx) { Out << format("%02" PRIX32, Val[Idx]); if (Idx == 3 || Idx == 5 || Idx == 7 || Idx == 9) @@ -154,7 +156,7 @@ void MappingTraits<MachOYAML::LinkEditData>::mapping( IO.mapOptional("BindOpcodes", LinkEditData.BindOpcodes); IO.mapOptional("WeakBindOpcodes", LinkEditData.WeakBindOpcodes); IO.mapOptional("LazyBindOpcodes", LinkEditData.LazyBindOpcodes); - if(LinkEditData.ExportTrie.Children.size() > 0 || !IO.outputting()) + if (!LinkEditData.ExportTrie.Children.empty() || !IO.outputting()) IO.mapOptional("ExportTrie", LinkEditData.ExportTrie); IO.mapOptional("NameList", LinkEditData.NameList); IO.mapOptional("StringTable", LinkEditData.StringTable); @@ -230,6 +232,12 @@ void mapLoadCommandData<MachO::dylinker_command>( IO.mapOptional("PayloadString", LoadCommand.PayloadString); } +template <> +void mapLoadCommandData<MachO::build_version_command>( + IO &IO, MachOYAML::LoadCommand &LoadCommand) { + IO.mapOptional("Tools", LoadCommand.Tools); +} + void MappingTraits<MachOYAML::LoadCommand>::mapping( IO &IO, MachOYAML::LoadCommand &LoadCommand) { MachO::LoadCommandType TempCmd = static_cast<MachO::LoadCommandType>( @@ -246,7 +254,7 @@ void MappingTraits<MachOYAML::LoadCommand>::mapping( break; switch (LoadCommand.Data.load_command_data.cmd) { -#include "llvm/Support/MachO.def" +#include "llvm/BinaryFormat/MachO.def" } IO.mapOptional("PayloadBytes", LoadCommand.PayloadBytes); IO.mapOptional("ZeroPadBytes", LoadCommand.ZeroPadBytes, (uint64_t)0ull); @@ -282,6 +290,12 @@ void MappingTraits<MachOYAML::Section>::mapping(IO &IO, IO.mapOptional("reserved3", Section.reserved3); } +void MappingTraits<MachO::build_tool_version>::mapping( + IO &IO, MachO::build_tool_version &tool) { + IO.mapRequired("tool", tool.tool); + IO.mapRequired("version", tool.version); +} + void MappingTraits<MachO::dylib>::mapping(IO &IO, MachO::dylib &DylibStruct) { IO.mapRequired("name", DylibStruct.name); IO.mapRequired("timestamp", DylibStruct.timestamp); @@ -296,13 +310,11 @@ void MappingTraits<MachO::dylib_command>::mapping( void MappingTraits<MachO::dylinker_command>::mapping( IO &IO, MachO::dylinker_command &LoadCommand) { - IO.mapRequired("name", LoadCommand.name); } void MappingTraits<MachO::dysymtab_command>::mapping( IO &IO, MachO::dysymtab_command &LoadCommand) { - IO.mapRequired("ilocalsym", LoadCommand.ilocalsym); IO.mapRequired("nlocalsym", LoadCommand.nlocalsym); IO.mapRequired("iextdefsym", LoadCommand.iextdefsym); @@ -325,7 +337,6 @@ void MappingTraits<MachO::dysymtab_command>::mapping( void MappingTraits<MachO::encryption_info_command>::mapping( IO &IO, MachO::encryption_info_command &LoadCommand) { - IO.mapRequired("cryptoff", LoadCommand.cryptoff); IO.mapRequired("cryptsize", LoadCommand.cryptsize); IO.mapRequired("cryptid", LoadCommand.cryptid); @@ -333,7 +344,6 @@ void MappingTraits<MachO::encryption_info_command>::mapping( void MappingTraits<MachO::encryption_info_command_64>::mapping( IO &IO, MachO::encryption_info_command_64 &LoadCommand) { - IO.mapRequired("cryptoff", LoadCommand.cryptoff); IO.mapRequired("cryptsize", LoadCommand.cryptsize); IO.mapRequired("cryptid", LoadCommand.cryptid); @@ -342,14 +352,12 @@ void MappingTraits<MachO::encryption_info_command_64>::mapping( void MappingTraits<MachO::entry_point_command>::mapping( IO &IO, MachO::entry_point_command &LoadCommand) { - IO.mapRequired("entryoff", LoadCommand.entryoff); IO.mapRequired("stacksize", LoadCommand.stacksize); } void MappingTraits<MachO::fvmfile_command>::mapping( IO &IO, MachO::fvmfile_command &LoadCommand) { - IO.mapRequired("name", LoadCommand.name); IO.mapRequired("header_addr", LoadCommand.header_addr); } @@ -362,7 +370,6 @@ void MappingTraits<MachO::fvmlib>::mapping(IO &IO, MachO::fvmlib &FVMLib) { void MappingTraits<MachO::fvmlib_command>::mapping( IO &IO, MachO::fvmlib_command &LoadCommand) { - IO.mapRequired("fvmlib", LoadCommand.fvmlib); } @@ -371,20 +378,17 @@ void MappingTraits<MachO::ident_command>::mapping( void MappingTraits<MachO::linkedit_data_command>::mapping( IO &IO, MachO::linkedit_data_command &LoadCommand) { - IO.mapRequired("dataoff", LoadCommand.dataoff); IO.mapRequired("datasize", LoadCommand.datasize); } void MappingTraits<MachO::linker_option_command>::mapping( IO &IO, MachO::linker_option_command &LoadCommand) { - IO.mapRequired("count", LoadCommand.count); } void MappingTraits<MachO::prebind_cksum_command>::mapping( IO &IO, MachO::prebind_cksum_command &LoadCommand) { - IO.mapRequired("cksum", LoadCommand.cksum); } @@ -393,7 +397,6 @@ void MappingTraits<MachO::load_command>::mapping( void MappingTraits<MachO::prebound_dylib_command>::mapping( IO &IO, MachO::prebound_dylib_command &LoadCommand) { - IO.mapRequired("name", LoadCommand.name); IO.mapRequired("nmodules", LoadCommand.nmodules); IO.mapRequired("linked_modules", LoadCommand.linked_modules); @@ -401,7 +404,6 @@ void MappingTraits<MachO::prebound_dylib_command>::mapping( void MappingTraits<MachO::routines_command>::mapping( IO &IO, MachO::routines_command &LoadCommand) { - IO.mapRequired("init_address", LoadCommand.init_address); IO.mapRequired("init_module", LoadCommand.init_module); IO.mapRequired("reserved1", LoadCommand.reserved1); @@ -414,7 +416,6 @@ void MappingTraits<MachO::routines_command>::mapping( void MappingTraits<MachO::routines_command_64>::mapping( IO &IO, MachO::routines_command_64 &LoadCommand) { - IO.mapRequired("init_address", LoadCommand.init_address); IO.mapRequired("init_module", LoadCommand.init_module); IO.mapRequired("reserved1", LoadCommand.reserved1); @@ -427,7 +428,6 @@ void MappingTraits<MachO::routines_command_64>::mapping( void MappingTraits<MachO::rpath_command>::mapping( IO &IO, MachO::rpath_command &LoadCommand) { - IO.mapRequired("path", LoadCommand.path); } @@ -463,7 +463,6 @@ void MappingTraits<MachO::section_64>::mapping(IO &IO, void MappingTraits<MachO::segment_command>::mapping( IO &IO, MachO::segment_command &LoadCommand) { - IO.mapRequired("segname", LoadCommand.segname); IO.mapRequired("vmaddr", LoadCommand.vmaddr); IO.mapRequired("vmsize", LoadCommand.vmsize); @@ -477,7 +476,6 @@ void MappingTraits<MachO::segment_command>::mapping( void MappingTraits<MachO::segment_command_64>::mapping( IO &IO, MachO::segment_command_64 &LoadCommand) { - IO.mapRequired("segname", LoadCommand.segname); IO.mapRequired("vmaddr", LoadCommand.vmaddr); IO.mapRequired("vmsize", LoadCommand.vmsize); @@ -491,44 +489,37 @@ void MappingTraits<MachO::segment_command_64>::mapping( void MappingTraits<MachO::source_version_command>::mapping( IO &IO, MachO::source_version_command &LoadCommand) { - IO.mapRequired("version", LoadCommand.version); } void MappingTraits<MachO::sub_client_command>::mapping( IO &IO, MachO::sub_client_command &LoadCommand) { - IO.mapRequired("client", LoadCommand.client); } void MappingTraits<MachO::sub_framework_command>::mapping( IO &IO, MachO::sub_framework_command &LoadCommand) { - IO.mapRequired("umbrella", LoadCommand.umbrella); } void MappingTraits<MachO::sub_library_command>::mapping( IO &IO, MachO::sub_library_command &LoadCommand) { - IO.mapRequired("sub_library", LoadCommand.sub_library); } void MappingTraits<MachO::sub_umbrella_command>::mapping( IO &IO, MachO::sub_umbrella_command &LoadCommand) { - IO.mapRequired("sub_umbrella", LoadCommand.sub_umbrella); } void MappingTraits<MachO::symseg_command>::mapping( IO &IO, MachO::symseg_command &LoadCommand) { - IO.mapRequired("offset", LoadCommand.offset); IO.mapRequired("size", LoadCommand.size); } void MappingTraits<MachO::symtab_command>::mapping( IO &IO, MachO::symtab_command &LoadCommand) { - IO.mapRequired("symoff", LoadCommand.symoff); IO.mapRequired("nsyms", LoadCommand.nsyms); IO.mapRequired("stroff", LoadCommand.stroff); @@ -540,24 +531,36 @@ void MappingTraits<MachO::thread_command>::mapping( void MappingTraits<MachO::twolevel_hints_command>::mapping( IO &IO, MachO::twolevel_hints_command &LoadCommand) { - IO.mapRequired("offset", LoadCommand.offset); IO.mapRequired("nhints", LoadCommand.nhints); } void MappingTraits<MachO::uuid_command>::mapping( IO &IO, MachO::uuid_command &LoadCommand) { - IO.mapRequired("uuid", LoadCommand.uuid); } void MappingTraits<MachO::version_min_command>::mapping( IO &IO, MachO::version_min_command &LoadCommand) { - IO.mapRequired("version", LoadCommand.version); IO.mapRequired("sdk", LoadCommand.sdk); } -} // namespace llvm::yaml +void MappingTraits<MachO::note_command>::mapping( + IO &IO, MachO::note_command &LoadCommand) { + IO.mapRequired("data_owner", LoadCommand.data_owner); + IO.mapRequired("offset", LoadCommand.offset); + IO.mapRequired("size", LoadCommand.size); +} + +void MappingTraits<MachO::build_version_command>::mapping( + IO &IO, MachO::build_version_command &LoadCommand) { + IO.mapRequired("platform", LoadCommand.platform); + IO.mapRequired("minos", LoadCommand.minos); + IO.mapRequired("sdk", LoadCommand.sdk); + IO.mapRequired("ntools", LoadCommand.ntools); +} + +} // end namespace yaml -} // namespace llvm +} // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp b/contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp index cbbaac6..850c1a5 100644 --- a/contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/ObjectYAML.cpp @@ -11,8 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ObjectYAML/YAML.h" #include "llvm/ObjectYAML/ObjectYAML.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/YAMLParser.h" +#include "llvm/Support/YAMLTraits.h" +#include <string> using namespace llvm; using namespace yaml; @@ -43,6 +46,9 @@ void MappingTraits<YamlObjectFile>::mapping(IO &IO, ObjectFile.FatMachO.reset(new MachOYAML::UniversalBinary()); MappingTraits<MachOYAML::UniversalBinary>::mapping(IO, *ObjectFile.FatMachO); + } else if (IO.mapTag("!WASM")) { + ObjectFile.Wasm.reset(new WasmYAML::Object()); + MappingTraits<WasmYAML::Object>::mapping(IO, *ObjectFile.Wasm); } else { Input &In = (Input &)IO; std::string Tag = In.getCurrentNode()->getRawTag(); @@ -50,8 +56,8 @@ void MappingTraits<YamlObjectFile>::mapping(IO &IO, IO.setError("YAML Object File missing document type tag!"); else IO.setError( - llvm::Twine("YAML Object File unsupported document type tag '") + - llvm::Twine(Tag) + llvm::Twine("'!")); + Twine("YAML Object File unsupported document type tag '") + + Twine(Tag) + Twine("'!")); } } } diff --git a/contrib/llvm/lib/ObjectYAML/WasmYAML.cpp b/contrib/llvm/lib/ObjectYAML/WasmYAML.cpp new file mode 100644 index 0000000..6a68cd2 --- /dev/null +++ b/contrib/llvm/lib/ObjectYAML/WasmYAML.cpp @@ -0,0 +1,411 @@ +//===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of wasm. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/WasmYAML.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/YAMLTraits.h" + +namespace llvm { + +namespace WasmYAML { + +// Declared here rather than in the header to comply with: +// http://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers +Section::~Section() = default; + +} // end namespace WasmYAML + +namespace yaml { + +void MappingTraits<WasmYAML::FileHeader>::mapping( + IO &IO, WasmYAML::FileHeader &FileHdr) { + IO.mapRequired("Version", FileHdr.Version); +} + +void MappingTraits<WasmYAML::Object>::mapping(IO &IO, + WasmYAML::Object &Object) { + IO.setContext(&Object); + IO.mapTag("!WASM", true); + IO.mapRequired("FileHeader", Object.Header); + IO.mapOptional("Sections", Object.Sections); + IO.setContext(nullptr); +} + +static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) { + IO.mapRequired("Type", Section.Type); + IO.mapOptional("Relocations", Section.Relocations); +} + +static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Name", Section.Name); + IO.mapOptional("FunctionNames", Section.FunctionNames); +} + +static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Name", Section.Name); + IO.mapRequired("DataSize", Section.DataSize); + IO.mapRequired("DataAlignment", Section.DataAlignment); + IO.mapRequired("SymbolInfo", Section.SymbolInfos); +} + +static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Name", Section.Name); + IO.mapRequired("Payload", Section.Payload); +} + +static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Signatures", Section.Signatures); +} + +static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Imports", Section.Imports); +} + +static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("FunctionTypes", Section.FunctionTypes); +} + +static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Tables", Section.Tables); +} + +static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Memories", Section.Memories); +} + +static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Globals", Section.Globals); +} + +static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Exports", Section.Exports); +} + +static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("StartFunction", Section.StartFunction); +} + +static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Segments", Section.Segments); +} + +static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Functions", Section.Functions); +} + +static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) { + commonSectionMapping(IO, Section); + IO.mapRequired("Segments", Section.Segments); +} + +void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping( + IO &IO, std::unique_ptr<WasmYAML::Section> &Section) { + WasmYAML::SectionType SectionType; + if (IO.outputting()) + SectionType = Section->Type; + else + IO.mapRequired("Type", SectionType); + + switch (SectionType) { + case wasm::WASM_SEC_CUSTOM: { + StringRef SectionName; + if (IO.outputting()) { + auto CustomSection = cast<WasmYAML::CustomSection>(Section.get()); + SectionName = CustomSection->Name; + } else { + IO.mapRequired("Name", SectionName); + } + if (SectionName == "linking") { + if (!IO.outputting()) + Section.reset(new WasmYAML::LinkingSection()); + sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get())); + } else if (SectionName == "name") { + if (!IO.outputting()) + Section.reset(new WasmYAML::NameSection()); + sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get())); + } else { + if (!IO.outputting()) + Section.reset(new WasmYAML::CustomSection(SectionName)); + sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get())); + } + break; + } + case wasm::WASM_SEC_TYPE: + if (!IO.outputting()) + Section.reset(new WasmYAML::TypeSection()); + sectionMapping(IO, *cast<WasmYAML::TypeSection>(Section.get())); + break; + case wasm::WASM_SEC_IMPORT: + if (!IO.outputting()) + Section.reset(new WasmYAML::ImportSection()); + sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get())); + break; + case wasm::WASM_SEC_FUNCTION: + if (!IO.outputting()) + Section.reset(new WasmYAML::FunctionSection()); + sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get())); + break; + case wasm::WASM_SEC_TABLE: + if (!IO.outputting()) + Section.reset(new WasmYAML::TableSection()); + sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get())); + break; + case wasm::WASM_SEC_MEMORY: + if (!IO.outputting()) + Section.reset(new WasmYAML::MemorySection()); + sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get())); + break; + case wasm::WASM_SEC_GLOBAL: + if (!IO.outputting()) + Section.reset(new WasmYAML::GlobalSection()); + sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get())); + break; + case wasm::WASM_SEC_EXPORT: + if (!IO.outputting()) + Section.reset(new WasmYAML::ExportSection()); + sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get())); + break; + case wasm::WASM_SEC_START: + if (!IO.outputting()) + Section.reset(new WasmYAML::StartSection()); + sectionMapping(IO, *cast<WasmYAML::StartSection>(Section.get())); + break; + case wasm::WASM_SEC_ELEM: + if (!IO.outputting()) + Section.reset(new WasmYAML::ElemSection()); + sectionMapping(IO, *cast<WasmYAML::ElemSection>(Section.get())); + break; + case wasm::WASM_SEC_CODE: + if (!IO.outputting()) + Section.reset(new WasmYAML::CodeSection()); + sectionMapping(IO, *cast<WasmYAML::CodeSection>(Section.get())); + break; + case wasm::WASM_SEC_DATA: + if (!IO.outputting()) + Section.reset(new WasmYAML::DataSection()); + sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get())); + break; + default: + llvm_unreachable("Unknown section type"); + } +} + +void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration( + IO &IO, WasmYAML::SectionType &Type) { +#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X); + ECase(CUSTOM); + ECase(TYPE); + ECase(IMPORT); + ECase(FUNCTION); + ECase(TABLE); + ECase(MEMORY); + ECase(GLOBAL); + ECase(EXPORT); + ECase(START); + ECase(ELEM); + ECase(CODE); + ECase(DATA); +#undef ECase +} + +void MappingTraits<WasmYAML::Signature>::mapping( + IO &IO, WasmYAML::Signature &Signature) { + IO.mapOptional("Index", Signature.Index); + IO.mapRequired("ReturnType", Signature.ReturnType); + IO.mapRequired("ParamTypes", Signature.ParamTypes); +} + +void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) { + IO.mapRequired("ElemType", Table.ElemType); + IO.mapRequired("Limits", Table.TableLimits); +} + +void MappingTraits<WasmYAML::Function>::mapping(IO &IO, + WasmYAML::Function &Function) { + IO.mapRequired("Locals", Function.Locals); + IO.mapRequired("Body", Function.Body); +} + +void MappingTraits<WasmYAML::Relocation>::mapping( + IO &IO, WasmYAML::Relocation &Relocation) { + IO.mapRequired("Type", Relocation.Type); + IO.mapRequired("Index", Relocation.Index); + IO.mapRequired("Offset", Relocation.Offset); + IO.mapOptional("Addend", Relocation.Addend, 0); +} + +void MappingTraits<WasmYAML::NameEntry>::mapping( + IO &IO, WasmYAML::NameEntry &NameEntry) { + IO.mapRequired("Index", NameEntry.Index); + IO.mapRequired("Name", NameEntry.Name); +} + +void MappingTraits<WasmYAML::LocalDecl>::mapping( + IO &IO, WasmYAML::LocalDecl &LocalDecl) { + IO.mapRequired("Type", LocalDecl.Type); + IO.mapRequired("Count", LocalDecl.Count); +} + +void MappingTraits<WasmYAML::Limits>::mapping(IO &IO, + WasmYAML::Limits &Limits) { + if (!IO.outputting() || Limits.Flags) + IO.mapOptional("Flags", Limits.Flags); + IO.mapRequired("Initial", Limits.Initial); + if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) + IO.mapOptional("Maximum", Limits.Maximum); +} + +void MappingTraits<WasmYAML::ElemSegment>::mapping( + IO &IO, WasmYAML::ElemSegment &Segment) { + IO.mapRequired("Offset", Segment.Offset); + IO.mapRequired("Functions", Segment.Functions); +} + +void MappingTraits<WasmYAML::Import>::mapping(IO &IO, + WasmYAML::Import &Import) { + IO.mapRequired("Module", Import.Module); + IO.mapRequired("Field", Import.Field); + IO.mapRequired("Kind", Import.Kind); + if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) { + IO.mapRequired("SigIndex", Import.SigIndex); + } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) { + IO.mapRequired("GlobalType", Import.GlobalImport.Type); + IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable); + } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) { + IO.mapRequired("Table", Import.TableImport); + } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY ) { + IO.mapRequired("Memory", Import.Memory); + } else { + llvm_unreachable("unhandled import type"); + } +} + +void MappingTraits<WasmYAML::Export>::mapping(IO &IO, + WasmYAML::Export &Export) { + IO.mapRequired("Name", Export.Name); + IO.mapRequired("Kind", Export.Kind); + IO.mapRequired("Index", Export.Index); +} + +void MappingTraits<WasmYAML::Global>::mapping(IO &IO, + WasmYAML::Global &Global) { + IO.mapRequired("Type", Global.Type); + IO.mapRequired("Mutable", Global.Mutable); + IO.mapRequired("InitExpr", Global.InitExpr); +} + +void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO, + wasm::WasmInitExpr &Expr) { + WasmYAML::Opcode Op = Expr.Opcode; + IO.mapRequired("Opcode", Op); + Expr.Opcode = Op; + switch (Expr.Opcode) { + case wasm::WASM_OPCODE_I32_CONST: + IO.mapRequired("Value", Expr.Value.Int32); + break; + case wasm::WASM_OPCODE_I64_CONST: + IO.mapRequired("Value", Expr.Value.Int64); + break; + case wasm::WASM_OPCODE_F32_CONST: + IO.mapRequired("Value", Expr.Value.Float32); + break; + case wasm::WASM_OPCODE_F64_CONST: + IO.mapRequired("Value", Expr.Value.Float64); + break; + case wasm::WASM_OPCODE_GET_GLOBAL: + IO.mapRequired("Index", Expr.Value.Global); + break; + } +} + +void MappingTraits<WasmYAML::DataSegment>::mapping( + IO &IO, WasmYAML::DataSegment &Segment) { + IO.mapOptional("SectionOffset", Segment.SectionOffset); + IO.mapRequired("MemoryIndex", Segment.MemoryIndex); + IO.mapRequired("Offset", Segment.Offset); + IO.mapRequired("Content", Segment.Content); +} + +void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO, + WasmYAML::SymbolInfo &Info) { + IO.mapRequired("Name", Info.Name); + IO.mapRequired("Flags", Info.Flags); +} + +void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration( + IO &IO, WasmYAML::ValueType &Type) { +#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); + ECase(I32); + ECase(I64); + ECase(F32); + ECase(F64); + ECase(ANYFUNC); + ECase(FUNC); + ECase(NORESULT); +#undef ECase +} + +void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration( + IO &IO, WasmYAML::ExportKind &Kind) { +#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X); + ECase(FUNCTION); + ECase(TABLE); + ECase(MEMORY); + ECase(GLOBAL); +#undef ECase +} + +void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration( + IO &IO, WasmYAML::Opcode &Code) { +#define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X); + ECase(END); + ECase(I32_CONST); + ECase(I64_CONST); + ECase(F64_CONST); + ECase(F32_CONST); + ECase(GET_GLOBAL); +#undef ECase +} + +void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration( + IO &IO, WasmYAML::TableType &Type) { +#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); + ECase(ANYFUNC); +#undef ECase +} + +void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration( + IO &IO, WasmYAML::RelocType &Type) { +#define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name); +#include "llvm/BinaryFormat/WasmRelocs/WebAssembly.def" +#undef WASM_RELOC +} + +} // end namespace yaml + +} // end namespace llvm diff --git a/contrib/llvm/lib/ObjectYAML/YAML.cpp b/contrib/llvm/lib/ObjectYAML/YAML.cpp index 75cf1fb..67b5764 100644 --- a/contrib/llvm/lib/ObjectYAML/YAML.cpp +++ b/contrib/llvm/lib/ObjectYAML/YAML.cpp @@ -16,11 +16,12 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" #include <cctype> +#include <cstdint> using namespace llvm; void yaml::ScalarTraits<yaml::BinaryRef>::output( - const yaml::BinaryRef &Val, void *, llvm::raw_ostream &Out) { + const yaml::BinaryRef &Val, void *, raw_ostream &Out) { Val.writeAsHex(Out); } @@ -34,7 +35,7 @@ StringRef yaml::ScalarTraits<yaml::BinaryRef>::input(StringRef Scalar, void *, if (!isxdigit(Scalar[I])) return "BinaryRef hex string must contain only hex digits."; Val = yaml::BinaryRef(Scalar); - return StringRef(); + return {}; } void yaml::BinaryRef::writeAsBinary(raw_ostream &OS) const { |