Revert "[llvm-pdbutil] rewrite the "raw" output style."

This reverts commit 83ea17ebf2106859a51fbc2a86031b44d33696ad.

This is failing due to some strange template problems, so reverting
until it can be straightened out.

llvm-svn: 305505
This commit is contained in:
Zachary Turner 2017-06-15 20:55:51 +00:00
parent 60aac43813
commit da504b794c
43 changed files with 5184 additions and 3911 deletions

View File

@ -8,17 +8,48 @@
# Make sure that the PDB has module descriptors. foo.obj and bar.lib should be # Make sure that the PDB has module descriptors. foo.obj and bar.lib should be
# absolute paths, and bar.obj should be the relative path passed to llvm-lib. # absolute paths, and bar.obj should be the relative path passed to llvm-lib.
# CHECK: Modules # CHECK-LABEL: Modules [
# CHECK-NEXT: ============================================================ # CHECK-NEXT: {
# CHECK-NEXT: Mod 0000 | Name: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: # CHECK-NEXT: Name: {{.*pdb-lib.s.tmp[/\\]foo.obj}}
# CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`: # CHECK-NEXT: Debug Stream Index:
# CHECK-NEXT: debug stream: 9, # files: 0, has ec info: false # CHECK-NEXT: Object File Name: {{.*pdb-lib.s.tmp[/\\]foo.obj}}
# CHECK-NEXT: Mod 0001 | Name: `bar.obj`: # CHECK-NEXT: Num Files: 0
# CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`: # CHECK-NEXT: Source File Name Idx: 0
# CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false # CHECK-NEXT: Pdb File Name Idx: 0
# CHECK-NEXT: Mod 0002 | Name: `* Linker *`: # CHECK-NEXT: Line Info Byte Size: 0
# CHECK-NEXT: Obj: ``: # CHECK-NEXT: C13 Line Info Byte Size: 0
# CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false # CHECK-NEXT: Symbol Byte Size: 4
# CHECK-NEXT: Type Server Index: 0
# CHECK-NEXT: Has EC Info: No
# CHECK-NEXT: }
# CHECK-NEXT: {
# CHECK-NEXT: Name: bar.obj
# CHECK-NEXT: Debug Stream Index:
# CHECK-NEXT: Object File Name: {{.*pdb-lib.s.tmp[/\\]bar.lib}}
# CHECK-NEXT: Num Files: 0
# CHECK-NEXT: Source File Name Idx: 0
# CHECK-NEXT: Pdb File Name Idx: 0
# CHECK-NEXT: Line Info Byte Size: 0
# CHECK-NEXT: C13 Line Info Byte Size: 0
# CHECK-NEXT: Symbol Byte Size: 4
# CHECK-NEXT: Type Server Index: 0
# CHECK-NEXT: Has EC Info: No
# CHECK-NEXT: }
# CHECK-NEXT: {
# CHECK-NEXT: Name: * Linker *
# CHECK-NEXT: Debug Stream Index:
# CHECK-NEXT: Object File Name:
# CHECK-NEXT: Num Files: 0
# CHECK-NEXT: Source File Name Idx: 0
# CHECK-NEXT: Pdb File Name Idx: 0
# CHECK-NEXT: Line Info Byte Size: 0
# CHECK-NEXT: C13 Line Info Byte Size: 0
# CHECK-NEXT: Symbol Byte Size: 4
# CHECK-NEXT: Type Server Index: 0
# CHECK-NEXT: Has EC Info: No
# CHECK-NEXT: }
# CHECK-NEXT: ]
.def _main; .def _main;
.scl 2; .scl 2;

View File

@ -6,8 +6,8 @@
# RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \ # RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \
# RUN: -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s # RUN: -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s
# RUN: llvm-pdbutil raw -modules -section-map -section-contribs \ # RUN: llvm-pdbutil raw -modules -section-map -section-headers -section-contribs \
# RUN: -types -ids %t.pdb | FileCheck -check-prefix RAW %s # RUN: -tpi-records %t.pdb | FileCheck -check-prefix RAW %s
# CHECK: MSF: # CHECK: MSF:
# CHECK-NEXT: SuperBlock: # CHECK-NEXT: SuperBlock:
@ -115,85 +115,322 @@
# CHECK-NEXT: BuildInfo: # CHECK-NEXT: BuildInfo:
# CHECK-NEXT: ArgIndices: [ 4098, 4099, 4106, 4104, 4102 ] # CHECK-NEXT: ArgIndices: [ 4098, 4099, 4106, 4104, 4102 ]
RAW: Modules # RAW: Type Info Stream (TPI) {
RAW-NEXT: ============================================================ # RAW-NEXT: TPI Version: 20040203
RAW-NEXT: Mod 0000 | Name: `E:\src\llvmbuild\ninja\tools\lld\test\coff\Output\pdb.test.tmp1.obj`: # RAW-NEXT: Record count: 5
RAW-NEXT: Obj: `E:\src\llvmbuild\ninja\tools\lld\test\coff\Output\pdb.test.tmp1.obj`: # RAW-NEXT: Records [
RAW-NEXT: debug stream: 9, # files: 0, has ec info: false # RAW-NEXT: {
RAW-NEXT: Mod 0001 | Name: `E:\src\llvmbuild\ninja\tools\lld\test\coff\Output\pdb.test.tmp2.obj`: # RAW-NEXT: ArgList (0x1000) {
RAW-NEXT: Obj: `E:\src\llvmbuild\ninja\tools\lld\test\coff\Output\pdb.test.tmp2.obj`: # RAW-NEXT: TypeLeafKind: LF_ARGLIST (0x1201)
RAW-NEXT: debug stream: 10, # files: 0, has ec info: false # RAW-NEXT: NumArgs: 0
RAW-NEXT: Mod 0002 | Name: `* Linker *`: # RAW-NEXT: Arguments [
RAW-NEXT: Obj: ``: # RAW-NEXT: ]
RAW-NEXT: debug stream: 11, # files: 0, has ec info: false # RAW-NEXT: }
RAW: Types (TPI Stream) # RAW-NEXT: }
RAW-NEXT: ============================================================ # RAW-NEXT: {
RAW-NEXT: Showing 5 records # RAW-NEXT: Procedure (0x1001) {
RAW-NEXT: 0x1000 | LF_ARGLIST [size = 8] # RAW-NEXT: TypeLeafKind: LF_PROCEDURE (0x1008)
RAW-NEXT: 0x1001 | LF_PROCEDURE [size = 16] # RAW-NEXT: ReturnType: int (0x74)
RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1000 # RAW-NEXT: CallingConvention: NearC (0x0)
RAW-NEXT: calling conv = cdecl, options = None # RAW-NEXT: FunctionOptions [ (0x0)
RAW-NEXT: 0x1002 | LF_POINTER [size = 12] # RAW-NEXT: ]
RAW-NEXT: referent = 0x1001, mode = pointer, opts = None, kind = ptr64 # RAW-NEXT: NumParameters: 0
RAW-NEXT: 0x1003 | LF_ARGLIST [size = 12] # RAW-NEXT: ArgListType: () (0x1000)
RAW-NEXT: <no type>: `` # RAW-NEXT: }
RAW-NEXT: 0x1004 | LF_PROCEDURE [size = 16] # RAW-NEXT: }
RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1003 # RAW-NEXT: {
RAW-NEXT: calling conv = cdecl, options = None # RAW-NEXT: Pointer (0x1002) {
RAW: Types (IPI Stream) # RAW-NEXT: TypeLeafKind: LF_POINTER (0x1002)
RAW-NEXT: ============================================================ # RAW-NEXT: PointeeType: int () (0x1001)
RAW-NEXT: Showing 12 records # RAW-NEXT: PointerAttributes: 0x1000C
RAW-NEXT: 0x1000 | LF_FUNC_ID [size = 20] # RAW-NEXT: PtrType: Near64 (0xC)
RAW-NEXT: name = main, type = 0x1004, parent scope = <no type> # RAW-NEXT: PtrMode: Pointer (0x0)
RAW-NEXT: 0x1001 | LF_FUNC_ID [size = 16] # RAW-NEXT: IsFlat: 0
RAW-NEXT: name = foo, type = 0x1001, parent scope = <no type> # RAW-NEXT: IsConst: 0
RAW-NEXT: 0x1002 | LF_STRING_ID [size = 16] ID: <no type>, String: D:\b # RAW-NEXT: IsVolatile: 0
RAW-NEXT: 0x1003 | LF_STRING_ID [size = 36] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe # RAW-NEXT: IsUnaligned: 0
RAW-NEXT: 0x1004 | LF_STRING_ID [size = 260] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared" # RAW-NEXT: SizeOf: 8
RAW-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 12] # RAW-NEXT: }
RAW-NEXT: 0x1004: `-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"` # RAW-NEXT: }
RAW-NEXT: 0x1006 | LF_STRING_ID [size = 132] ID: 0x1005, String: -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X # RAW-NEXT: {
RAW-NEXT: 0x1007 | LF_STRING_ID [size = 24] ID: <no type>, String: ret42-main.c # RAW-NEXT: ArgList (0x1003) {
RAW-NEXT: 0x1008 | LF_STRING_ID [size = 24] ID: <no type>, String: D:\b\vc140.pdb # RAW-NEXT: TypeLeafKind: LF_ARGLIST (0x1201)
RAW-NEXT: 0x1009 | LF_BUILDINFO [size = 28] # RAW-NEXT: NumArgs: 1
RAW-NEXT: 0x1002: `D:\b` # RAW-NEXT: Arguments [
RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe` # RAW-NEXT: ArgType: 0x0
RAW-NEXT: 0x1007: `ret42-main.c` # RAW-NEXT: ]
RAW-NEXT: 0x1008: `D:\b\vc140.pdb` # RAW-NEXT: }
RAW-NEXT: 0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X` # RAW-NEXT: }
RAW-NEXT: 0x100A | LF_STRING_ID [size = 20] ID: <no type>, String: ret42-sub.c # RAW-NEXT: {
RAW-NEXT: 0x100B | LF_BUILDINFO [size = 28] # RAW-NEXT: Procedure (0x1004) {
RAW-NEXT: 0x1002: `D:\b` # RAW-NEXT: TypeLeafKind: LF_PROCEDURE (0x1008)
RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe` # RAW-NEXT: ReturnType: int (0x74)
RAW-NEXT: 0x100A: `ret42-sub.c` # RAW-NEXT: CallingConvention: NearC (0x0)
RAW-NEXT: 0x1008: `D:\b\vc140.pdb` # RAW-NEXT: FunctionOptions [ (0x0)
RAW-NEXT: 0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X` # RAW-NEXT: ]
RAW: Section Contributions # RAW-NEXT: NumParameters: 0
RAW-NEXT: ============================================================ # RAW-NEXT: ArgListType: (<no type>) (0x1003)
RAW-NEXT: SC | mod = 0, 65535:1288, size = 14, data crc = 0, reloc crc = 0 # RAW-NEXT: }
RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | # RAW-NEXT: }
RAW-NEXT: IMAGE_SCN_MEM_READ # RAW-NEXT: TypeIndexOffsets [
RAW-NEXT: SC | mod = 0, 65535:1312, size = 8, data crc = 0, reloc crc = 0 # RAW-NEXT: Index: 0x1000, Offset: 0
RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ # RAW-NEXT: ]
RAW-NEXT: SC | mod = 0, 65535:1320, size = 12, data crc = 0, reloc crc = 0 # RAW-NEXT: ]
RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ # RAW-NEXT: }
RAW-NEXT: SC | mod = 1, 65535:1144, size = 6, data crc = 0, reloc crc = 0 # RAW-NEXT: DBI Stream {
RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | # RAW-NEXT: Dbi Version: 20091201
RAW-NEXT: IMAGE_SCN_MEM_READ # RAW-NEXT: Age: 1
RAW: Section Map # RAW-NEXT: Incremental Linking: No
RAW-NEXT: ============================================================ # RAW-NEXT: Has CTypes: No
RAW-NEXT: Section 0000 | ovl = 0, group = 0, frame = 0, name = 1 # RAW-NEXT: Is Stripped: No
RAW-NEXT: class = 65535, offset = 0, size = 12 # RAW-NEXT: Machine Type: x86
RAW-NEXT: flags = read | 32 bit addr | selector # RAW-NEXT: Symbol Record Stream Index: 65535
RAW-NEXT: Section 0001 | ovl = 1, group = 0, frame = 0, name = 2 # RAW-NEXT: Public Symbol Stream Index: 65535
RAW-NEXT: class = 65535, offset = 0, size = 22 # RAW-NEXT: Global Symbol Stream Index: 65535
RAW-NEXT: flags = read | execute | 32 bit addr | selector # RAW-NEXT: Toolchain Version: 0.0
RAW-NEXT: Section 0002 | ovl = 2, group = 0, frame = 0, name = 3 # RAW-NEXT: mspdb00.dll version: 0.0.0
RAW-NEXT: class = 65535, offset = 0, size = 8 # RAW-NEXT: Modules [
RAW-NEXT: flags = read | 32 bit addr | selector # RAW-NEXT: {
RAW-NEXT: Section 0003 | ovl = 3, group = 0, frame = 0, name = 4 # RAW-NEXT: Name: {{.*}}tmp1.obj
RAW-NEXT: class = 65535, offset = 0, size = 119 # RAW-NEXT: Debug Stream Index: 9
RAW-NEXT: flags = read | 32 bit addr | selector # RAW-NEXT: Object File Name: {{.*}}tmp1.obj
RAW-NEXT: Section 0004 | ovl = 4, group = 0, frame = 0, name = 5 # RAW-NEXT: Num Files: 0
RAW-NEXT: class = 65535, offset = 0, size = 4294967295 # RAW-NEXT: Source File Name Idx: 0
RAW-NEXT: flags = 32 bit addr | absolute addr # RAW-NEXT: Pdb File Name Idx: 0
# RAW-NEXT: Line Info Byte Size: 0
# RAW-NEXT: C13 Line Info Byte Size: 0
# RAW-NEXT: Symbol Byte Size: 4
# RAW-NEXT: Type Server Index: 0
# RAW-NEXT: Has EC Info: No
# RAW-NEXT: }
# RAW-NEXT: {
# RAW-NEXT: Name: {{.*}}tmp2.obj
# RAW-NEXT: Debug Stream Index: 10
# RAW-NEXT: Object File Name: {{.*}}tmp2.obj
# RAW-NEXT: Num Files: 0
# RAW-NEXT: Source File Name Idx: 0
# RAW-NEXT: Pdb File Name Idx: 0
# RAW-NEXT: Line Info Byte Size: 0
# RAW-NEXT: C13 Line Info Byte Size: 0
# RAW-NEXT: Symbol Byte Size: 4
# RAW-NEXT: Type Server Index: 0
# RAW-NEXT: Has EC Info: No
# RAW-NEXT: }
# RAW-NEXT: {
# RAW-NEXT: Name: * Linker *
# RAW-NEXT: Debug Stream Index: 11
# RAW-NEXT: Object File Name:
# RAW-NEXT: Num Files: 0
# RAW-NEXT: Source File Name Idx: 0
# RAW-NEXT: Pdb File Name Idx: 0
# RAW-NEXT: Line Info Byte Size: 0
# RAW-NEXT: C13 Line Info Byte Size: 0
# RAW-NEXT: Symbol Byte Size: 4
# RAW-NEXT: Type Server Index: 0
# RAW-NEXT: Has EC Info: No
# RAW-NEXT: }
# RAW-NEXT: ]
# RAW-NEXT: }
# RAW-NEXT: Section Contributions [
# RAW-NEXT: Contribution {
# RAW-NEXT: ISect: 65535
# RAW-NEXT: Off: 1288
# RAW-NEXT: Size: 14
# RAW-NEXT: Characteristics [ (0x60500020)
# RAW-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000)
# RAW-NEXT: IMAGE_SCN_CNT_CODE (0x20)
# RAW-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
# RAW-NEXT: ]
# RAW-NEXT: Module {
# RAW-NEXT: Index: 0
# RAW-NEXT: Name: {{.*}}tmp1.obj
# RAW-NEXT: }
# RAW-NEXT: Data CRC: 0
# RAW-NEXT: Reloc CRC: 0
# RAW-NEXT: }
# RAW-NEXT: Contribution {
# RAW-NEXT: ISect: 65535
# RAW-NEXT: Off: 1312
# RAW-NEXT: Size: 8
# RAW-NEXT: Characteristics [ (0x40300040)
# RAW-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
# RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
# RAW-NEXT: ]
# RAW-NEXT: Module {
# RAW-NEXT: Index: 0
# RAW-NEXT: Name: {{.*}}tmp1.obj
# RAW-NEXT: }
# RAW-NEXT: Data CRC: 0
# RAW-NEXT: Reloc CRC: 0
# RAW-NEXT: }
# RAW-NEXT: Contribution {
# RAW-NEXT: ISect: 65535
# RAW-NEXT: Off: 1320
# RAW-NEXT: Size: 12
# RAW-NEXT: Characteristics [ (0x40300040)
# RAW-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
# RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
# RAW-NEXT: ]
# RAW-NEXT: Module {
# RAW-NEXT: Index: 0
# RAW-NEXT: Name: {{.*}}tmp1.obj
# RAW-NEXT: }
# RAW-NEXT: Data CRC: 0
# RAW-NEXT: Reloc CRC: 0
# RAW-NEXT: }
# RAW-NEXT: Contribution {
# RAW-NEXT: ISect: 65535
# RAW-NEXT: Off: 1144
# RAW-NEXT: Size: 6
# RAW-NEXT: Characteristics [ (0x60500020)
# RAW-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000)
# RAW-NEXT: IMAGE_SCN_CNT_CODE (0x20)
# RAW-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
# RAW-NEXT: ]
# RAW-NEXT: Module {
# RAW-NEXT: Index: 1
# RAW-NEXT: Name: {{.*}}tmp2.obj
# RAW-NEXT: }
# RAW-NEXT: Data CRC: 0
# RAW-NEXT: Reloc CRC: 0
# RAW-NEXT: }
# RAW-NEXT: ]
# RAW-NEXT: Section Map [
# RAW-NEXT: Entry {
# RAW-NEXT: Flags [ (0x109)
# RAW-NEXT: AddressIs32Bit (0x8)
# RAW-NEXT: IsSelector (0x100)
# RAW-NEXT: Read (0x1)
# RAW-NEXT: ]
# RAW-NEXT: Ovl: 0
# RAW-NEXT: Group: 0
# RAW-NEXT: Frame: 1
# RAW-NEXT: SecName: 65535
# RAW-NEXT: ClassName: 65535
# RAW-NEXT: Offset: 0
# RAW-NEXT: SecByteLength: 12
# RAW-NEXT: }
# RAW-NEXT: Entry {
# RAW-NEXT: Flags [ (0x10D)
# RAW-NEXT: AddressIs32Bit (0x8)
# RAW-NEXT: Execute (0x4)
# RAW-NEXT: IsSelector (0x100)
# RAW-NEXT: Read (0x1)
# RAW-NEXT: ]
# RAW-NEXT: Ovl: 0
# RAW-NEXT: Group: 0
# RAW-NEXT: Frame: 2
# RAW-NEXT: SecName: 65535
# RAW-NEXT: ClassName: 65535
# RAW-NEXT: Offset: 0
# RAW-NEXT: SecByteLength: 22
# RAW-NEXT: }
# RAW-NEXT: Entry {
# RAW-NEXT: Flags [ (0x109)
# RAW-NEXT: AddressIs32Bit (0x8)
# RAW-NEXT: IsSelector (0x100)
# RAW-NEXT: Read (0x1)
# RAW-NEXT: ]
# RAW-NEXT: Ovl: 0
# RAW-NEXT: Group: 0
# RAW-NEXT: Frame: 3
# RAW-NEXT: SecName: 65535
# RAW-NEXT: ClassName: 65535
# RAW-NEXT: Offset: 0
# RAW-NEXT: SecByteLength: 8
# RAW-NEXT: }
# RAW-NEXT: Entry {
# RAW-NEXT: Flags [ (0x109)
# RAW-NEXT: AddressIs32Bit (0x8)
# RAW-NEXT: IsSelector (0x100)
# RAW-NEXT: Read (0x1)
# RAW-NEXT: ]
# RAW-NEXT: Ovl: 0
# RAW-NEXT: Group: 0
# RAW-NEXT: Frame: 4
# RAW-NEXT: SecName: 65535
# RAW-NEXT: ClassName: 65535
# RAW-NEXT: Offset: 0
# RAW-NEXT: SecByteLength:
# RAW-NEXT: }
# RAW-NEXT: Entry {
# RAW-NEXT: Flags [ (0x208)
# RAW-NEXT: AddressIs32Bit (0x8)
# RAW-NEXT: IsAbsoluteAddress (0x200)
# RAW-NEXT: ]
# RAW-NEXT: Ovl: 0
# RAW-NEXT: Group: 0
# RAW-NEXT: Frame: 5
# RAW-NEXT: SecName: 65535
# RAW-NEXT: ClassName: 65535
# RAW-NEXT: Offset: 0
# RAW-NEXT: SecByteLength: 4294967295
# RAW-NEXT: }
# RAW-NEXT: ]
# RAW-NEXT: Section Headers [
# RAW-NEXT: {
# RAW-NEXT: Name: .pdata
# RAW-NEXT: Virtual Size: 12
# RAW-NEXT: Virtual Address: 4096
# RAW-NEXT: Size of Raw Data: 512
# RAW-NEXT: File Pointer to Raw Data: 1024
# RAW-NEXT: File Pointer to Relocations: 0
# RAW-NEXT: File Pointer to Linenumbers: 0
# RAW-NEXT: Number of Relocations: 0
# RAW-NEXT: Number of Linenumbers: 0
# RAW-NEXT: Characteristics [ (0x40000040)
# RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
# RAW-NEXT: ]
# RAW-NEXT: }
# RAW-NEXT: {
# RAW-NEXT: Name: .text
# RAW-NEXT: Virtual Size: 22
# RAW-NEXT: Virtual Address: 8192
# RAW-NEXT: Size of Raw Data: 512
# RAW-NEXT: File Pointer to Raw Data: 1536
# RAW-NEXT: File Pointer to Relocations: 0
# RAW-NEXT: File Pointer to Linenumbers: 0
# RAW-NEXT: Number of Relocations: 0
# RAW-NEXT: Number of Linenumbers: 0
# RAW-NEXT: Characteristics [ (0x60000020)
# RAW-NEXT: IMAGE_SCN_CNT_CODE (0x20)
# RAW-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
# RAW-NEXT: ]
# RAW-NEXT: }
# RAW-NEXT: {
# RAW-NEXT: Name: .xdata
# RAW-NEXT: Virtual Size: 8
# RAW-NEXT: Virtual Address: 12288
# RAW-NEXT: Size of Raw Data: 512
# RAW-NEXT: File Pointer to Raw Data: 2048
# RAW-NEXT: File Pointer to Relocations: 0
# RAW-NEXT: File Pointer to Linenumbers: 0
# RAW-NEXT: Number of Relocations: 0
# RAW-NEXT: Number of Linenumbers: 0
# RAW-NEXT: Characteristics [ (0x40000040)
# RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
# RAW-NEXT: ]
# RAW-NEXT: }
# RAW-NEXT: {
# RAW-NEXT: Name: .rdata
# RAW-NEXT: Virtual Size:
# RAW-NEXT: Virtual Address: 16384
# RAW-NEXT: Size of Raw Data: 512
# RAW-NEXT: File Pointer to Raw Data: 2560
# RAW-NEXT: File Pointer to Relocations: 0
# RAW-NEXT: File Pointer to Linenumbers: 0
# RAW-NEXT: Number of Relocations: 0
# RAW-NEXT: Number of Linenumbers: 0
# RAW-NEXT: Characteristics [ (0x40000040)
# RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
# RAW-NEXT: ]
# RAW-NEXT: }
# RAW-NEXT: ]

View File

@ -418,8 +418,6 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ProcSymFlags)
/// Corresponds to COMPILESYM2::Flags bitfield. /// Corresponds to COMPILESYM2::Flags bitfield.
enum class CompileSym2Flags : uint32_t { enum class CompileSym2Flags : uint32_t {
None = 0,
SourceLanguageMask = 0xFF,
EC = 1 << 8, EC = 1 << 8,
NoDbgInfo = 1 << 9, NoDbgInfo = 1 << 9,
LTCG = 1 << 10, LTCG = 1 << 10,
@ -434,8 +432,6 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym2Flags)
/// Corresponds to COMPILESYM3::Flags bitfield. /// Corresponds to COMPILESYM3::Flags bitfield.
enum class CompileSym3Flags : uint32_t { enum class CompileSym3Flags : uint32_t {
None = 0,
SourceLanguageMask = 0xFF,
EC = 1 << 8, EC = 1 << 8,
NoDbgInfo = 1 << 9, NoDbgInfo = 1 << 9,
LTCG = 1 << 10, LTCG = 1 << 10,
@ -452,7 +448,6 @@ enum class CompileSym3Flags : uint32_t {
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags) CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags)
enum class ExportFlags : uint16_t { enum class ExportFlags : uint16_t {
None = 0,
IsConstant = 1 << 0, IsConstant = 1 << 0,
IsData = 1 << 1, IsData = 1 << 1,
IsPrivate = 1 << 2, IsPrivate = 1 << 2,

View File

@ -12,10 +12,7 @@
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatProviders.h"
#include "llvm/Support/FormatVariadic.h"
namespace llvm { namespace llvm {
namespace codeview { namespace codeview {
@ -38,20 +35,6 @@ inline detail::GuidAdapter fmt_guid(ArrayRef<uint8_t> Item) {
return detail::GuidAdapter(Item); return detail::GuidAdapter(Item);
} }
} }
template <> struct format_provider<codeview::TypeIndex> {
public:
static void format(const codeview::TypeIndex &V, llvm::raw_ostream &Stream,
StringRef Style) {
if (V.isNoneType())
Stream << "<no type>";
else {
Stream << formatv("{0:X+4}", V.getIndex());
if (V.isSimple())
Stream << " (" << codeview::TypeIndex::simpleTypeName(V) << ")";
}
}
};
} }
#endif #endif

View File

@ -363,7 +363,7 @@ public:
: SymbolRecord(SymbolRecordKind::PublicSym32), : SymbolRecord(SymbolRecordKind::PublicSym32),
RecordOffset(RecordOffset) {} RecordOffset(RecordOffset) {}
TypeIndex Index; uint32_t Index;
uint32_t Offset; uint32_t Offset;
uint16_t Segment; uint16_t Segment;
StringRef Name; StringRef Name;
@ -379,7 +379,7 @@ public:
: SymbolRecord(SymbolRecordKind::RegisterSym), : SymbolRecord(SymbolRecordKind::RegisterSym),
RecordOffset(RecordOffset) {} RecordOffset(RecordOffset) {}
TypeIndex Index; uint32_t Index;
RegisterId Register; RegisterId Register;
StringRef Name; StringRef Name;
@ -679,7 +679,7 @@ public:
: SymbolRecord(SymbolRecordKind::FileStaticSym), : SymbolRecord(SymbolRecordKind::FileStaticSym),
RecordOffset(RecordOffset) {} RecordOffset(RecordOffset) {}
TypeIndex Index; uint32_t Index;
uint32_t ModFilenameOffset; uint32_t ModFilenameOffset;
LocalSymFlags Flags; LocalSymFlags Flags;
StringRef Name; StringRef Name;
@ -814,7 +814,7 @@ public:
uint32_t CodeOffset; uint32_t CodeOffset;
uint16_t Register; uint16_t Register;
FrameCookieKind CookieKind; uint8_t CookieKind;
uint8_t Flags; uint8_t Flags;
uint32_t RecordOffset; uint32_t RecordOffset;
@ -871,7 +871,7 @@ public:
uint32_t Offset; uint32_t Offset;
TypeIndex Type; TypeIndex Type;
RegisterId Register; uint16_t Register;
StringRef Name; StringRef Name;
uint32_t RecordOffset; uint32_t RecordOffset;

View File

@ -248,8 +248,6 @@ public:
return A.toArrayIndex() - B.toArrayIndex(); return A.toArrayIndex() - B.toArrayIndex();
} }
static StringRef simpleTypeName(TypeIndex TI);
private: private:
support::ulittle32_t Index; support::ulittle32_t Index;
}; };

View File

@ -40,10 +40,6 @@ public:
iterator_range<codeview::CVSymbolArray::Iterator> iterator_range<codeview::CVSymbolArray::Iterator>
symbols(bool *HadError) const; symbols(bool *HadError) const;
const codeview::CVSymbolArray &getSymbolArray() const {
return SymbolsSubstream;
}
llvm::iterator_range<DebugSubsectionIterator> subsections() const; llvm::iterator_range<DebugSubsectionIterator> subsections() const;
bool hasDebugSubsections() const; bool hasDebugSubsections() const;

View File

@ -35,7 +35,6 @@ public:
uint32_t getSymHash() const; uint32_t getSymHash() const;
uint32_t getAddrMap() const; uint32_t getAddrMap() const;
uint32_t getNumBuckets() const { return NumBuckets; } uint32_t getNumBuckets() const { return NumBuckets; }
Expected<const codeview::CVSymbolArray &> getSymbolArray() const;
iterator_range<codeview::CVSymbolArray::Iterator> iterator_range<codeview::CVSymbolArray::Iterator>
getSymbols(bool *HadError) const; getSymbols(bool *HadError) const;
FixedStreamArray<support::ulittle32_t> getHashBuckets() const { FixedStreamArray<support::ulittle32_t> getHashBuckets() const {

View File

@ -98,19 +98,15 @@ enum class DbgHeaderType : uint16_t {
}; };
enum class OMFSegDescFlags : uint16_t { enum class OMFSegDescFlags : uint16_t {
None = 0,
Read = 1 << 0, // Segment is readable. Read = 1 << 0, // Segment is readable.
Write = 1 << 1, // Segment is writable. Write = 1 << 1, // Segment is writable.
Execute = 1 << 2, // Segment is executable. Execute = 1 << 2, // Segment is executable.
AddressIs32Bit = 1 << 3, // Descriptor describes a 32-bit linear address. AddressIs32Bit = 1 << 3, // Descriptor describes a 32-bit linear address.
IsSelector = 1 << 8, // Frame represents a selector. IsSelector = 1 << 8, // Frame represents a selector.
IsAbsoluteAddress = 1 << 9, // Frame represents an absolute address. IsAbsoluteAddress = 1 << 9, // Frame represents an absolute address.
IsGroup = 1 << 10, // If set, descriptor represents a group. IsGroup = 1 << 10 // If set, descriptor represents a group.
LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ IsGroup)
}; };
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
} // end namespace pdb } // end namespace pdb
} // end namespace llvm } // end namespace llvm

View File

@ -27,10 +27,6 @@ public:
~SymbolStream(); ~SymbolStream();
Error reload(); Error reload();
const codeview::CVSymbolArray &getSymbolArray() const {
return SymbolRecords;
}
iterator_range<codeview::CVSymbolArray::Iterator> iterator_range<codeview::CVSymbolArray::Iterator>
getSymbols(bool *HadError) const; getSymbols(bool *HadError) const;

View File

@ -290,12 +290,6 @@ public:
return FixedStreamArrayIterator<T>(*this, size()); return FixedStreamArrayIterator<T>(*this, size());
} }
const T &front() const { return *begin(); }
const T &back() const {
FixedStreamArrayIterator<T> I = end();
return *(--I);
}
BinaryStreamRef getUnderlyingStream() const { return Stream; } BinaryStreamRef getUnderlyingStream() const { return Stream; }
private: private:

View File

@ -19,7 +19,6 @@
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h" #include "llvm/ADT/Twine.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/FormatVariadicDetails.h" #include "llvm/Support/FormatVariadicDetails.h"
#include "llvm/Support/NativeFormatting.h" #include "llvm/Support/NativeFormatting.h"
@ -151,19 +150,6 @@ public:
} }
}; };
template <typename T, llvm::support::endianness E, int alignment>
struct format_provider<
support::detail::packed_endian_specific_integral<T, E, alignment>> {
using Type =
support::detail::packed_endian_specific_integral<T, E, alignment>;
public:
static void format(const Type &V, llvm::raw_ostream &Stream,
StringRef Style) {
format_provider<T>::format(static_cast<T>(V), Stream, Style);
}
};
/// Implementation of format_provider<T> for integral pointer types. /// Implementation of format_provider<T> for integral pointer types.
/// ///
/// The options string of a pointer type has the grammar: /// The options string of a pointer type has the grammar:

View File

@ -212,7 +212,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
FileStaticSym &FileStatic) { FileStaticSym &FileStatic) {
DictScope S(W, "FileStatic"); DictScope S(W, "FileStatic");
printTypeIndex("Index", FileStatic.Index); W.printNumber("Index", FileStatic.Index);
W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset); W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset);
W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames()); W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames());
W.printString("Name", FileStatic.Name); W.printString("Name", FileStatic.Name);
@ -516,7 +516,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
RegisterSym &Register) { RegisterSym &Register) {
DictScope S(W, "RegisterSym"); DictScope S(W, "RegisterSym");
printTypeIndex("Type", Register.Index); W.printNumber("Type", Register.Index);
W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames()); W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames());
W.printString("Name", Register.Name); W.printString("Name", Register.Name);
return Error::success(); return Error::success();
@ -524,7 +524,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) { Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {
DictScope S(W, "PublicSym"); DictScope S(W, "PublicSym");
printTypeIndex("Type", Public.Index); W.printNumber("Type", Public.Index);
W.printNumber("Seg", Public.Segment); W.printNumber("Seg", Public.Segment);
W.printNumber("Off", Public.Offset); W.printNumber("Off", Public.Offset);
W.printString("Name", Public.Name); W.printString("Name", Public.Name);
@ -631,7 +631,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
W.printHex("Offset", RegRel.Offset); W.printHex("Offset", RegRel.Offset);
printTypeIndex("Type", RegRel.Type); printTypeIndex("Type", RegRel.Type);
W.printEnum("Register", uint16_t(RegRel.Register), getRegisterNames()); W.printHex("Register", RegRel.Register);
W.printString("VarName", RegRel.Name); W.printString("VarName", RegRel.Name);
return Error::success(); return Error::success();
} }

View File

@ -307,7 +307,7 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
error(IO.mapInteger(FrameCookie.CodeOffset)); error(IO.mapInteger(FrameCookie.CodeOffset));
error(IO.mapInteger(FrameCookie.Register)); error(IO.mapInteger(FrameCookie.Register));
error(IO.mapEnum(FrameCookie.CookieKind)); error(IO.mapInteger(FrameCookie.CookieKind));
error(IO.mapInteger(FrameCookie.Flags)); error(IO.mapInteger(FrameCookie.Flags));
return Error::success(); return Error::success();
@ -439,7 +439,7 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
error(IO.mapInteger(RegRel.Offset)); error(IO.mapInteger(RegRel.Offset));
error(IO.mapInteger(RegRel.Type)); error(IO.mapInteger(RegRel.Type));
error(IO.mapEnum(RegRel.Register)); error(IO.mapInteger(RegRel.Register));
error(IO.mapStringZ(RegRel.Name)); error(IO.mapStringZ(RegRel.Name));
return Error::success(); return Error::success();

View File

@ -12,6 +12,59 @@
using namespace llvm; using namespace llvm;
using namespace llvm::codeview; using namespace llvm::codeview;
namespace {
struct SimpleTypeEntry {
StringRef Name;
SimpleTypeKind Kind;
};
}
/// The names here all end in "*". If the simple type is a pointer type, we
/// return the whole name. Otherwise we lop off the last character in our
/// StringRef.
static const SimpleTypeEntry SimpleTypeNames[] = {
{"void*", SimpleTypeKind::Void},
{"<not translated>*", SimpleTypeKind::NotTranslated},
{"HRESULT*", SimpleTypeKind::HResult},
{"signed char*", SimpleTypeKind::SignedCharacter},
{"unsigned char*", SimpleTypeKind::UnsignedCharacter},
{"char*", SimpleTypeKind::NarrowCharacter},
{"wchar_t*", SimpleTypeKind::WideCharacter},
{"char16_t*", SimpleTypeKind::Character16},
{"char32_t*", SimpleTypeKind::Character32},
{"__int8*", SimpleTypeKind::SByte},
{"unsigned __int8*", SimpleTypeKind::Byte},
{"short*", SimpleTypeKind::Int16Short},
{"unsigned short*", SimpleTypeKind::UInt16Short},
{"__int16*", SimpleTypeKind::Int16},
{"unsigned __int16*", SimpleTypeKind::UInt16},
{"long*", SimpleTypeKind::Int32Long},
{"unsigned long*", SimpleTypeKind::UInt32Long},
{"int*", SimpleTypeKind::Int32},
{"unsigned*", SimpleTypeKind::UInt32},
{"__int64*", SimpleTypeKind::Int64Quad},
{"unsigned __int64*", SimpleTypeKind::UInt64Quad},
{"__int64*", SimpleTypeKind::Int64},
{"unsigned __int64*", SimpleTypeKind::UInt64},
{"__int128*", SimpleTypeKind::Int128},
{"unsigned __int128*", SimpleTypeKind::UInt128},
{"__half*", SimpleTypeKind::Float16},
{"float*", SimpleTypeKind::Float32},
{"float*", SimpleTypeKind::Float32PartialPrecision},
{"__float48*", SimpleTypeKind::Float48},
{"double*", SimpleTypeKind::Float64},
{"long double*", SimpleTypeKind::Float80},
{"__float128*", SimpleTypeKind::Float128},
{"_Complex float*", SimpleTypeKind::Complex32},
{"_Complex double*", SimpleTypeKind::Complex64},
{"_Complex long double*", SimpleTypeKind::Complex80},
{"_Complex __float128*", SimpleTypeKind::Complex128},
{"bool*", SimpleTypeKind::Boolean8},
{"__bool16*", SimpleTypeKind::Boolean16},
{"__bool32*", SimpleTypeKind::Boolean32},
{"__bool64*", SimpleTypeKind::Boolean64},
};
TypeDatabase::TypeDatabase(uint32_t Capacity) : TypeNameStorage(Allocator) { TypeDatabase::TypeDatabase(uint32_t Capacity) : TypeNameStorage(Allocator) {
CVUDTNames.resize(Capacity); CVUDTNames.resize(Capacity);
TypeRecords.resize(Capacity); TypeRecords.resize(Capacity);
@ -50,8 +103,22 @@ StringRef TypeDatabase::saveTypeName(StringRef TypeName) {
} }
StringRef TypeDatabase::getTypeName(TypeIndex Index) const { StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
if (Index.isNoneType() || Index.isSimple()) if (Index.isNoneType())
return TypeIndex::simpleTypeName(Index); return "<no type>";
if (Index.isSimple()) {
// This is a simple type.
for (const auto &SimpleTypeName : SimpleTypeNames) {
if (SimpleTypeName.Kind == Index.getSimpleKind()) {
if (Index.getSimpleMode() == SimpleTypeMode::Direct)
return SimpleTypeName.Name.drop_back(1);
// Otherwise, this is a pointer type. We gloss over the distinction
// between near, far, 64, 32, etc, and just give a pointer type.
return SimpleTypeName.Name;
}
}
return "<unknown simple type>";
}
if (contains(Index)) if (contains(Index))
return CVUDTNames[Index.toArrayIndex()]; return CVUDTNames[Index.toArrayIndex()];

View File

@ -15,88 +15,11 @@
using namespace llvm; using namespace llvm;
using namespace llvm::codeview; using namespace llvm::codeview;
namespace {
struct SimpleTypeEntry {
StringRef Name;
SimpleTypeKind Kind;
};
/// The names here all end in "*". If the simple type is a pointer type, we
/// return the whole name. Otherwise we lop off the last character in our
/// StringRef.
static const SimpleTypeEntry SimpleTypeNames[] = {
{"void*", SimpleTypeKind::Void},
{"<not translated>*", SimpleTypeKind::NotTranslated},
{"HRESULT*", SimpleTypeKind::HResult},
{"signed char*", SimpleTypeKind::SignedCharacter},
{"unsigned char*", SimpleTypeKind::UnsignedCharacter},
{"char*", SimpleTypeKind::NarrowCharacter},
{"wchar_t*", SimpleTypeKind::WideCharacter},
{"char16_t*", SimpleTypeKind::Character16},
{"char32_t*", SimpleTypeKind::Character32},
{"__int8*", SimpleTypeKind::SByte},
{"unsigned __int8*", SimpleTypeKind::Byte},
{"short*", SimpleTypeKind::Int16Short},
{"unsigned short*", SimpleTypeKind::UInt16Short},
{"__int16*", SimpleTypeKind::Int16},
{"unsigned __int16*", SimpleTypeKind::UInt16},
{"long*", SimpleTypeKind::Int32Long},
{"unsigned long*", SimpleTypeKind::UInt32Long},
{"int*", SimpleTypeKind::Int32},
{"unsigned*", SimpleTypeKind::UInt32},
{"__int64*", SimpleTypeKind::Int64Quad},
{"unsigned __int64*", SimpleTypeKind::UInt64Quad},
{"__int64*", SimpleTypeKind::Int64},
{"unsigned __int64*", SimpleTypeKind::UInt64},
{"__int128*", SimpleTypeKind::Int128},
{"unsigned __int128*", SimpleTypeKind::UInt128},
{"__half*", SimpleTypeKind::Float16},
{"float*", SimpleTypeKind::Float32},
{"float*", SimpleTypeKind::Float32PartialPrecision},
{"__float48*", SimpleTypeKind::Float48},
{"double*", SimpleTypeKind::Float64},
{"long double*", SimpleTypeKind::Float80},
{"__float128*", SimpleTypeKind::Float128},
{"_Complex float*", SimpleTypeKind::Complex32},
{"_Complex double*", SimpleTypeKind::Complex64},
{"_Complex long double*", SimpleTypeKind::Complex80},
{"_Complex __float128*", SimpleTypeKind::Complex128},
{"bool*", SimpleTypeKind::Boolean8},
{"__bool16*", SimpleTypeKind::Boolean16},
{"__bool32*", SimpleTypeKind::Boolean32},
{"__bool64*", SimpleTypeKind::Boolean64},
};
} // namespace
StringRef TypeIndex::simpleTypeName(TypeIndex TI) {
assert(TI.isNoneType() || TI.isSimple());
if (TI.isNoneType())
return "<no type>";
// This is a simple type.
for (const auto &SimpleTypeName : SimpleTypeNames) {
if (SimpleTypeName.Kind == TI.getSimpleKind()) {
if (TI.getSimpleMode() == SimpleTypeMode::Direct)
return SimpleTypeName.Name.drop_back(1);
// Otherwise, this is a pointer type. We gloss over the distinction
// between near, far, 64, 32, etc, and just give a pointer type.
return SimpleTypeName.Name;
}
}
return "<unknown simple type>";
}
void llvm::codeview::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, void llvm::codeview::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
TypeIndex TI, TypeCollection &Types) { TypeIndex TI, TypeCollection &Types) {
StringRef TypeName; StringRef TypeName;
if (!TI.isNoneType()) { if (!TI.isNoneType())
if (TI.isSimple())
TypeName = TypeIndex::simpleTypeName(TI);
else
TypeName = Types.getTypeName(TI); TypeName = Types.getTypeName(TI);
}
if (!TypeName.empty()) if (!TypeName.empty())
Printer.printHex(FieldName, TypeName, TI.getIndex()); Printer.printHex(FieldName, TypeName, TI.getIndex());
else else

View File

@ -130,13 +130,4 @@ PublicsStream::getSymbols(bool *HadError) const {
return SS.getSymbols(HadError); return SS.getSymbols(HadError);
} }
Expected<const codeview::CVSymbolArray &>
PublicsStream::getSymbolArray() const {
auto SymbolS = Pdb.getPDBSymbolStream();
if (!SymbolS)
return SymbolS.takeError();
return SymbolS->getSymbolArray();
}
Error PublicsStream::commit() { return Error::success(); } Error PublicsStream::commit() { return Error::success(); }

View File

@ -35,7 +35,6 @@ LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false) LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind) LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags) LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags) LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
@ -150,15 +149,6 @@ void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
} }
} }
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 llvm {
namespace CodeViewYAML { namespace CodeViewYAML {
namespace detail { namespace detail {

View File

@ -0,0 +1,74 @@
RUN: llvm-pdbutil pdb2yaml -tpi-stream %p/Inputs/big-read.pdb > %t.yaml
RUN: FileCheck -check-prefix=YAML %s < %t.yaml
RUN: llvm-pdbutil yaml2pdb %t.yaml -pdb %t.pdb
RUN: llvm-pdbutil raw -tpi-records %t.pdb | FileCheck %s --check-prefix=PDB
Only verify the beginning of the type stream.
YAML: TpiStream:
YAML-NEXT: Version: VC80
YAML-NEXT: Records:
YAML-NEXT: - Kind: LF_ARGLIST
YAML-NEXT: ArgList:
YAML-NEXT: ArgIndices: [ ]
YAML-NEXT: - Kind: LF_PROCEDURE
YAML-NEXT: Procedure:
YAML-NEXT: ReturnType: 3
YAML-NEXT: CallConv: NearC
YAML-NEXT: Options: [ None ]
YAML-NEXT: ParameterCount: 0
YAML-NEXT: ArgumentList: 4096
YAML-NEXT: - Kind: LF_PROCEDURE
YAML-NEXT: Procedure:
YAML-NEXT: ReturnType: 116
YAML-NEXT: CallConv: NearC
YAML-NEXT: Options: [ None ]
YAML-NEXT: ParameterCount: 0
YAML-NEXT: ArgumentList: 4096
This test is mostly checking to make sure we include the type index offset
table, and eventually hash codes. The type index offsets should be similar to
what are already present in big-read.pdb.
PDB: Type Info Stream (TPI) {
PDB-NEXT: TPI Version: 20040203
PDB-NEXT: Record count: 728
PDB-NEXT: Records [
PDB-NEXT: {
PDB-NEXT: ArgList (0x1000) {
PDB-NEXT: TypeLeafKind: LF_ARGLIST (0x1201)
PDB-NEXT: NumArgs: 0
PDB-NEXT: Arguments [
PDB-NEXT: ]
PDB-NEXT: }
PDB-NEXT: }
PDB-NEXT: {
PDB-NEXT: Procedure (0x1001) {
PDB-NEXT: TypeLeafKind: LF_PROCEDURE (0x1008)
PDB-NEXT: ReturnType: void (0x3)
PDB-NEXT: CallingConvention: NearC (0x0)
PDB-NEXT: FunctionOptions [ (0x0)
PDB-NEXT: ]
PDB-NEXT: NumParameters: 0
PDB-NEXT: ArgListType: () (0x1000)
PDB-NEXT: }
PDB-NEXT: }
PDB-NEXT: {
PDB-NEXT: Procedure (0x1002) {
PDB-NEXT: TypeLeafKind: LF_PROCEDURE (0x1008)
PDB-NEXT: ReturnType: int (0x74)
PDB-NEXT: CallingConvention: NearC (0x0)
PDB-NEXT: FunctionOptions [ (0x0)
PDB-NEXT: ]
PDB-NEXT: NumParameters: 0
PDB-NEXT: ArgListType: () (0x1000)
PDB-NEXT: }
PDB-NEXT: }
...
PDB: TypeIndexOffsets [
PDB-NEXT: Index: 0x1000, Offset: 0
PDB-NEXT: Index: 0x106c, Offset: 8,116
PDB-NEXT: Index: 0x1118, Offset: 16,372
PDB-NEXT: Index: 0x11df, Offset: 24,564
PDB-NEXT: Index: 0x128e, Offset: 32,752
PDB-NEXT: ]

View File

@ -1,5 +1,6 @@
; RUN: llvm-pdbutil yaml2pdb -pdb=%t.pdb %p/Inputs/debug-subsections.yaml ; RUN: llvm-pdbutil yaml2pdb -pdb=%t.pdb %p/Inputs/debug-subsections.yaml
; RUN: llvm-pdbutil pdb2yaml -all -no-file-headers %t.pdb | FileCheck --check-prefix=YAML %s ; RUN: llvm-pdbutil pdb2yaml -all -no-file-headers %t.pdb | FileCheck --check-prefix=YAML %s
; RUN: llvm-pdbutil raw -subsections=all %t.pdb | FileCheck --check-prefix=RAW %s
YAML: Modules: YAML: Modules:
YAML-NEXT: - Module: Foo.obj YAML-NEXT: - Module: Foo.obj
@ -64,3 +65,146 @@ YAML-NEXT: Sites:
YAML-NEXT: - FileName: 'f:\dd\externalapis\windows\10\sdk\inc\winerror.h' YAML-NEXT: - FileName: 'f:\dd\externalapis\windows\10\sdk\inc\winerror.h'
YAML-NEXT: LineNum: 26950 YAML-NEXT: LineNum: 26950
YAML-NEXT: Inlinee: 22767 YAML-NEXT: Inlinee: 22767
RAW: DBI Stream {
RAW: Modules [
RAW-NEXT: {
RAW-NEXT: Name: Foo.obj
RAW: Subsections [
RAW-NEXT: CrossModuleExports [
RAW-NEXT: Export {
RAW-NEXT: Local: 0x12F4
RAW-NEXT: Global: 0x2443
RAW-NEXT: }
RAW-NEXT: Export {
RAW-NEXT: Local: 0x80001083
RAW-NEXT: Global: 0x23A3
RAW-NEXT: }
RAW-NEXT: ]
RAW-NEXT: ]
RAW-NEXT: }
RAW-NEXT: {
RAW-NEXT: Name: Bar.obj
RAW: Subsections [
RAW-NEXT: CrossModuleExports [
RAW-NEXT: Export {
RAW-NEXT: Local: 0x10A9
RAW-NEXT: Global: 0x17D1
RAW-NEXT: }
RAW-NEXT: Export {
RAW-NEXT: Local: 0x10C9
RAW-NEXT: Global: 0x1245
RAW-NEXT: }
RAW-NEXT: ]
RAW-NEXT: CrossModuleImports [
RAW-NEXT: ModuleImport {
RAW-NEXT: Module: Foo.obj
RAW-NEXT: Imports: [0x12F4, 0x80001083]
RAW-NEXT: }
RAW-NEXT: ]
RAW-NEXT: ]
RAW-NEXT: }
RAW-NEXT: {
RAW-NEXT: Name: d:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj
RAW: Subsections [
RAW-NEXT: FileChecksums {
RAW-NEXT: Checksum {
RAW-NEXT: FileName: d:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp
RAW-NEXT: Kind: MD5 (0x1)
RAW-NEXT: Checksum (
RAW-NEXT: 0000: A0A5BD0D 3ECD93FC 29D19DE8 26FBF4BC |....>...)...&...|
RAW-NEXT: )
RAW-NEXT: }
RAW-NEXT: Checksum {
RAW-NEXT: FileName: f:\dd\externalapis\windows\10\sdk\inc\winerror.h
RAW-NEXT: Kind: MD5 (0x1)
RAW-NEXT: Checksum (
RAW-NEXT: 0000: 1154D69F 5B265019 6E1FC34F 4134E56B |.T..[&P.n..OA4.k|
RAW-NEXT: )
RAW-NEXT: }
RAW-NEXT: }
RAW-NEXT: Lines {
RAW-NEXT: RelocSegment: 1
RAW-NEXT: RelocOffset: 100016
RAW-NEXT: CodeSize: 10
RAW-NEXT: HasColumns: No
RAW-NEXT: FileEntry {
RAW-NEXT: FileName: d:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp
RAW-NEXT: Line {
RAW-NEXT: Offset: 0
RAW-NEXT: LineNumberStart: 5
RAW-NEXT: EndDelta: 0
RAW-NEXT: IsStatement: Yes
RAW-NEXT: }
RAW-NEXT: Line {
RAW-NEXT: Offset: 3
RAW-NEXT: LineNumberStart: 6
RAW-NEXT: EndDelta: 0
RAW-NEXT: IsStatement: Yes
RAW-NEXT: }
RAW-NEXT: Line {
RAW-NEXT: Offset: 8
RAW-NEXT: LineNumberStart: 7
RAW-NEXT: EndDelta: 0
RAW-NEXT: IsStatement: Yes
RAW-NEXT: }
RAW-NEXT: }
RAW-NEXT: }
RAW-NEXT: InlineeLines {
RAW-NEXT: HasExtraFiles: No
RAW-NEXT: Lines [
RAW-NEXT: Inlinee {
RAW-NEXT: FileName: f:\dd\externalapis\windows\10\sdk\inc\winerror.h
RAW-NEXT: Function {
RAW-NEXT: Index: 0x58ef (unknown function)
RAW-NEXT: }
RAW-NEXT: SourceLine: 26950
RAW-NEXT: }
RAW-NEXT: ]
RAW-NEXT: }
RAW-NEXT: ]
RAW-NEXT: }
RAW-NEXT: {
RAW-NEXT: Name: ObjFileSubsections
RAW-NEXT: Debug Stream Index: 11
RAW-NEXT: Object File Name: ObjFileSubsections
RAW-NEXT: Num Files: 0
RAW-NEXT: Source File Name Idx: 0
RAW-NEXT: Pdb File Name Idx: 0
RAW-NEXT: Line Info Byte Size: 0
RAW-NEXT: C13 Line Info Byte Size: 116
RAW-NEXT: Symbol Byte Size: 4
RAW-NEXT: Type Server Index: 0
RAW-NEXT: Has EC Info: No
RAW-NEXT: Subsections [
RAW-NEXT: String Table [
RAW-NEXT: String1
RAW-NEXT: String2
RAW-NEXT: String3
RAW-NEXT: ]
RAW-NEXT: Symbols [
RAW-NEXT: {
RAW-NEXT: ObjectName {
RAW-NEXT: Signature: 0x0
RAW-NEXT: ObjectName: ObjFileSubsections
RAW-NEXT: }
RAW-NEXT: }
RAW-NEXT: ]
RAW-NEXT: FrameData [
RAW-NEXT: Frame {
RAW-NEXT: Rva: 6
RAW-NEXT: CodeSize: 1
RAW-NEXT: LocalSize: 2
RAW-NEXT: ParamsSize: 4
RAW-NEXT: MaxStackSize: 3
RAW-NEXT: FrameFunc: MyFunc
RAW-NEXT: PrologSize: 5
RAW-NEXT: SavedRegsSize: 7
RAW-NEXT: Flags: 0
RAW-NEXT: }
RAW-NEXT: ]
RAW-NEXT: ]
RAW-NEXT: }
RAW-NEXT: ]
RAW-NEXT: }

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +1,65 @@
; RUN: llvm-pdbutil yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge-ids-and-types-1.yaml ; RUN: llvm-pdbutil yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge-ids-and-types-1.yaml
; RUN: llvm-pdbutil yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge-ids-and-types-2.yaml ; RUN: llvm-pdbutil yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge-ids-and-types-2.yaml
; RUN: llvm-pdbutil merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb ; RUN: llvm-pdbutil merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb
; RUN: llvm-pdbutil raw -types %t.3.pdb | FileCheck -check-prefix=TPI-TYPES %s ; RUN: llvm-pdbutil raw -tpi-records %t.3.pdb | FileCheck -check-prefix=TPI-TYPES %s
; RUN: llvm-pdbutil raw -ids %t.3.pdb | FileCheck -check-prefix=IPI-TYPES %s ; RUN: llvm-pdbutil raw -tpi-records %t.3.pdb | FileCheck -check-prefix=INTMAIN %s
; RUN: llvm-pdbutil raw -tpi-records %t.3.pdb | FileCheck -check-prefix=VOIDMAIN %s
; RUN: llvm-pdbutil raw -ipi-records %t.3.pdb | FileCheck -check-prefix=IPI-TYPES %s
; RUN: llvm-pdbutil raw -ipi-records %t.3.pdb | FileCheck -check-prefix=IPI-NAMES %s
; RUN: llvm-pdbutil raw -ipi-records %t.3.pdb | FileCheck -check-prefix=IPI-UDT %s
TPI-TYPES: Types (TPI Stream) TPI-TYPES: Type Info Stream (TPI)
TPI-TYPES-NEXT: ============================================================ TPI-TYPES: Record count: 9
TPI-TYPES-NEXT: Showing 9 records TPI-TYPES-DAG: TypeLeafKind: LF_POINTER
TPI-TYPES-NEXT: 0x1000 | LF_POINTER [size = 12] TPI-TYPES-DAG: TypeLeafKind: LF_FIELDLIST
TPI-TYPES-NEXT: referent = 0x0470 (char*), mode = pointer, opts = None, kind = ptr32 TPI-TYPES-DAG: TypeLeafKind: LF_ARGLIST
TPI-TYPES-NEXT: 0x1001 | LF_FIELDLIST [size = 24] TPI-TYPES-DAG: TypeLeafKind: LF_STRUCTURE
TPI-TYPES-NEXT: - LF_MEMBER [name = `FooMember`, Type = 0x0403 (void*), offset = 0, attrs = public] TPI-TYPES-DAG: TypeLeafKind: LF_MEMBER
TPI-TYPES-NEXT: 0x1002 | LF_ARGLIST [size = 16] TPI-TYPES-DAG: TypeLeafKind: LF_POINTER
TPI-TYPES-NEXT: 0x0074 (int): `int` TPI-TYPES-DAG: TypeLeafKind: LF_ARGLIST
TPI-TYPES-NEXT: 0x1000: `char**` TPI-TYPES-DAG: TypeLeafKind: LF_MFUNCTION
TPI-TYPES-NEXT: 0x1003 | LF_STRUCTURE [size = 36] TPI-TYPES-DAG: TypeLeafKind: LF_PROCEDURE
TPI-TYPES-NEXT: class name: `FooBar` TPI-TYPES-DAG: TypeLeafKind: LF_PROCEDURE
TPI-TYPES-NEXT: unique name: `FooBar` TPI-TYPES-DAG: TypeLeafKind: LF_ARGLIST
TPI-TYPES-NEXT: vtable: <no type>, base list: <no type>, field list: 0x1001
TPI-TYPES-NEXT: options: has unique name
TPI-TYPES-NEXT: 0x1004 | LF_POINTER [size = 12]
TPI-TYPES-NEXT: referent = 0x1003, mode = pointer, opts = None, kind = ptr32
TPI-TYPES-NEXT: 0x1005 | LF_ARGLIST [size = 12]
TPI-TYPES-NEXT: 0x0074 (int): `int`
TPI-TYPES-NEXT: 0x1006 | LF_MFUNCTION [size = 28]
TPI-TYPES-NEXT: return type = 1, # args = 0x1005, param list = 0x0003 (void)
TPI-TYPES-NEXT: class type = 0x1003, this type = 0x1004, this adjust = 0
TPI-TYPES-NEXT: calling conv = thiscall, options = constructor
TPI-TYPES-NEXT: 0x1007 | LF_PROCEDURE [size = 16]
TPI-TYPES-NEXT: return type = 0x0074 (int), # args = 2, param list = 0x1002
TPI-TYPES-NEXT: calling conv = cdecl, options = None
TPI-TYPES-NEXT: 0x1008 | LF_PROCEDURE [size = 16]
TPI-TYPES-NEXT: return type = 0x0003 (void), # args = 2, param list = 0x1002
TPI-TYPES-NEXT: calling conv = cdecl, options = None
IPI-TYPES: Types (IPI Stream) ; Both procedures should use the same arglist even though they have a different
IPI-TYPES-NEXT: ============================================================ ; return type.
IPI-TYPES-NEXT: Showing 6 records INTMAIN: ArgList ([[ID:.*]])
IPI-TYPES-NEXT: 0x1000 | LF_FUNC_ID [size = 20] INTMAIN-NEXT: TypeLeafKind: LF_ARGLIST
IPI-TYPES-NEXT: name = main, type = 0x1007, parent scope = <no type> INTMAIN-NEXT: NumArgs: 2
IPI-TYPES-NEXT: 0x1001 | LF_MFUNC_ID [size = 24] INTMAIN-NEXT: Arguments [
IPI-TYPES-NEXT: name = FooMethod, type = 0x1006, class type = 0x1003 INTMAIN-NEXT: ArgType: int
IPI-TYPES-NEXT: 0x1002 | LF_UDT_MOD_SRC_LINE [size = 20] INTMAIN-NEXT: ArgType: char**
IPI-TYPES-NEXT: udt = 0x1003, mod = 0, file = 0, line = 0 INTMAIN: TypeLeafKind: LF_PROCEDURE
IPI-TYPES-NEXT: 0x1003 | LF_FUNC_ID [size = 20] INTMAIN: ReturnType: int
IPI-TYPES-NEXT: name = main2, type = 0x1007, parent scope = <no type> INTMAIN: NumParameters: 2
IPI-TYPES-NEXT: 0x1004 | LF_FUNC_ID [size = 16] INTMAIN-NEXT: ArgListType: (int, char**) ([[ID]])
IPI-TYPES-NEXT: name = foo, type = 0x1008, parent scope = <no type>
IPI-TYPES-NEXT: 0x1005 | LF_MFUNC_ID [size = 24] VOIDMAIN: ArgList ([[ID:.*]])
IPI-TYPES-NEXT: name = FooMethod2, type = 0x1006, class type = 0x1003 VOIDMAIN-NEXT: TypeLeafKind: LF_ARGLIST
VOIDMAIN-NEXT: NumArgs: 2
VOIDMAIN-NEXT: Arguments [
VOIDMAIN-NEXT: ArgType: int
VOIDMAIN-NEXT: ArgType: char**
VOIDMAIN: TypeLeafKind: LF_PROCEDURE
VOIDMAIN: ReturnType: void
VOIDMAIN: NumParameters: 2
VOIDMAIN-NEXT: ArgListType: (int, char**) ([[ID]])
IPI-TYPES: Type Info Stream (IPI)
IPI-TYPES: Record count: 6
IPI-TYPES-DAG: TypeLeafKind: LF_FUNC_ID
IPI-TYPES-DAG: TypeLeafKind: LF_MFUNC_ID
IPI-TYPES-DAG: TypeLeafKind: LF_UDT_MOD_SRC_LINE
IPI-TYPES-DAG: TypeLeafKind: LF_FUNC_ID
IPI-TYPES-DAG: TypeLeafKind: LF_FUNC_ID
IPI-TYPES-DAG: TypeLeafKind: LF_MFUNC_ID
IPI-NAMES-DAG: Name: main
IPI-NAMES-DAG: Name: FooMethod
IPI-NAMES-DAG: Name: main2
IPI-NAMES-DAG: Name: foo
IPI-NAMES-DAG: Name: FooMethod2
IPI-UDT: TypeLeafKind: LF_UDT_MOD_SRC_LINE
IPI-UDT-NEXT: UDT: FooBar

View File

@ -1,24 +1,31 @@
; RUN: llvm-pdbutil yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge-ids-1.yaml ; RUN: llvm-pdbutil yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge-ids-1.yaml
; RUN: llvm-pdbutil yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge-ids-2.yaml ; RUN: llvm-pdbutil yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge-ids-2.yaml
; RUN: llvm-pdbutil merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb ; RUN: llvm-pdbutil merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb
; RUN: llvm-pdbutil raw -ids %t.3.pdb | FileCheck -check-prefix=MERGED %s ; RUN: llvm-pdbutil raw -ipi-records %t.3.pdb | FileCheck -check-prefix=MERGED %s
; RUN: llvm-pdbutil raw -types %t.3.pdb | FileCheck -check-prefix=TPI-EMPTY %s ; RUN: llvm-pdbutil raw -ipi-records %t.3.pdb | FileCheck -check-prefix=SUBSTRS %s
; RUN: llvm-pdbutil raw -tpi-records %t.3.pdb | FileCheck -check-prefix=TPI-EMPTY %s
MERGED: Types (IPI Stream) MERGED: Type Info Stream (IPI)
MERGED-NEXT: ============================================================ MERGED: Record count: 8
MERGED-NEXT: Showing 8 records MERGED-DAG: StringData: One
MERGED-NEXT: 0x1000 | LF_STRING_ID [size = 12] ID: <no type>, String: One MERGED-DAG: StringData: Two
MERGED-NEXT: 0x1001 | LF_STRING_ID [size = 12] ID: <no type>, String: Two MERGED-DAG: StringData: SubOne
MERGED-NEXT: 0x1002 | LF_STRING_ID [size = 20] ID: <no type>, String: OnlyInFirst MERGED-DAG: StringData: SubTwo
MERGED-NEXT: 0x1003 | LF_STRING_ID [size = 16] ID: <no type>, String: SubOne MERGED-DAG: StringData: Main
MERGED-NEXT: 0x1004 | LF_STRING_ID [size = 16] ID: <no type>, String: SubTwo MERGED-DAG: TypeLeafKind: LF_SUBSTR_LIST
MERGED-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 16] MERGED-DAG: StringData: OnlyInFirst
MERGED-NEXT: 0x1003: `SubOne` MERGED-DAG: StringData: OnlyInSecond
MERGED-NEXT: 0x1004: `SubTwo`
MERGED-NEXT: 0x1006 | LF_STRING_ID [size = 16] ID: 0x1005, String: Main
MERGED-NEXT: 0x1007 | LF_STRING_ID [size = 24] ID: <no type>, String: OnlyInSecond
TPI-EMPTY: Types (TPI Stream) SUBSTRS: StringList
TPI-EMPTY-NEXT: ============================================================ SUBSTRS: TypeLeafKind: LF_SUBSTR_LIST
TPI-EMPTY-NEXT: Showing 0 records SUBSTRS-NEXT: NumStrings: 2
SUBSTRS-NEXT: Strings [
SUBSTRS-NEXT: SubOne
SUBSTRS-NEXT: SubTwo
SUBSTRS: StringId
SUBSTRS-NEXT: TypeLeafKind: LF_STRING_ID
SUBSTRS-NEXT: Id: "SubOne" "SubTwo"
SUBSTRS-NEXT: StringData: Main
TPI-EMPTY: Record count: 0

View File

@ -1,36 +1,24 @@
+; RUN: llvm-pdbutil yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge-types-1.yaml ; RUN: llvm-pdbutil yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge-types-1.yaml
; RUN: llvm-pdbutil yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge-types-2.yaml ; RUN: llvm-pdbutil yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge-types-2.yaml
; RUN: llvm-pdbutil merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb ; RUN: llvm-pdbutil merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb
; RUN: llvm-pdbutil raw -types %t.3.pdb | FileCheck -check-prefix=MERGED %s ; RUN: llvm-pdbutil raw -tpi-records %t.3.pdb | FileCheck -check-prefix=MERGED %s
; RUN: llvm-pdbutil raw -tpi-records %t.3.pdb | FileCheck -check-prefix=ARGLIST %s
MERGED: Types (TPI Stream) MERGED: Type Info Stream (TPI)
MERGED-NEXT: ============================================================ MERGED: Record count: 9
MERGED-NEXT: Showing 9 records MERGED-DAG: PointeeType: unsigned
MERGED-NEXT: 0x1000 | LF_POINTER [size = 12] MERGED-DAG: PointeeType: unsigned*
MERGED-NEXT: referent = 0x0075 (unsigned), mode = pointer, opts = None, kind = ptr32 MERGED-DAG: PointeeType: unsigned**
MERGED-NEXT: 0x1001 | LF_POINTER [size = 12] MERGED-DAG: PointeeType: __int64
MERGED-NEXT: referent = 0x0076 (__int64), mode = pointer, opts = None, kind = ptr32 MERGED-DAG: PointeeType: __int64*
MERGED-NEXT: 0x1002 | LF_STRUCTURE [size = 48] MERGED-DAG: Name: OnlyInMerge1
MERGED-NEXT: class name: `OnlyInMerge1` MERGED-DAG: Name: OnlyInMerge2
MERGED-NEXT: unique name: `OnlyInMerge1` MERGED-DAG: TypeLeafKind: LF_ARGLIST
MERGED-NEXT: vtable: <no type>, base list: <no type>, field list: <no type>
MERGED-NEXT: options: forward ref | has unique name ARGLIST: TypeLeafKind: LF_ARGLIST
MERGED-NEXT: 0x1003 | LF_POINTER [size = 12] ARGLIST-NEXT: NumArgs: 3
MERGED-NEXT: referent = 0x1000, mode = pointer, opts = None, kind = ptr32 ARGLIST-NEXT: Arguments [
MERGED-NEXT: 0x1004 | LF_POINTER [size = 12] ARGLIST-NEXT: ArgType: unsigned
MERGED-NEXT: referent = 0x1003, mode = pointer, opts = None, kind = ptr32 ARGLIST-NEXT: ArgType: unsigned*
MERGED-NEXT: 0x1005 | LF_POINTER [size = 12] ARGLIST-NEXT: ArgType: unsigned**
MERGED-NEXT: referent = 0x1001, mode = pointer, opts = None, kind = ptr32
MERGED-NEXT: 0x1006 | LF_ARGLIST [size = 20]
MERGED-NEXT: 0x0075 (unsigned): `unsigned`
MERGED-NEXT: 0x1000: `unsigned*`
MERGED-NEXT: 0x1003: `unsigned**`
MERGED-NEXT: 0x1007 | LF_PROCEDURE [size = 16]
MERGED-NEXT: return type = 0x0075 (unsigned), # args = 0, param list = 0x1006
MERGED-NEXT: calling conv = cdecl, options = None
MERGED-NEXT: 0x1008 | LF_STRUCTURE [size = 48]
MERGED-NEXT: class name: `OnlyInMerge2`
MERGED-NEXT: unique name: `OnlyInMerge2`
MERGED-NEXT: vtable: <no type>, base list: <no type>, field list: <no type>
MERGED-NEXT: options: forward ref | has unique name

View File

@ -4,26 +4,32 @@
; RUN: not llvm-pdbutil raw -block-data=0a1 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s ; RUN: not llvm-pdbutil raw -block-data=0a1 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s
; RUN: not llvm-pdbutil raw -block-data=0- %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s ; RUN: not llvm-pdbutil raw -block-data=0- %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s
BLOCK0: MSF Blocks BLOCK0: Block Data {
BLOCK0-NEXT: ============================================================
BLOCK0-NEXT: Block 0 ( BLOCK0-NEXT: Block 0 (
BLOCK0-NEXT: 0000: 4D696372 6F736F66 7420432F 432B2B20 4D534620 372E3030 0D0A1A44 53000000 |Microsoft C/C++ MSF 7.00...DS...| BLOCK0-NEXT: 0000: 4D696372 6F736F66 7420432F 432B2B20 |Microsoft C/C++ |
BLOCK0-NEXT: 0020: 00100000 02000000 19000000 88000000 00000000 18000000 00000000 00000000 |................................| BLOCK0-NEXT: 0010: 4D534620 372E3030 0D0A1A44 53000000 |MSF 7.00...DS...|
BLOCK0-NEXT: 0040: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| BLOCK0-NEXT: 0020: 00100000 02000000 19000000 88000000 |................|
BLOCK0-NEXT: 0060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| BLOCK0-NEXT: 0030: 00000000 18000000 00000000 00000000 |................|
BLOCK0-NOT: Block 1 ( BLOCK0: 0FE0: 00000000 00000000 00000000 00000000 |................|
BLOCK0-NEXT: 0FF0: 00000000 00000000 00000000 00000000 |................|
BLOCK0-NEXT: )
BLOCK0-NEXT: }
BLOCK01: MSF Blocks BLOCK01: Block Data {
BLOCK01-NEXT: ============================================================
BLOCK01-NEXT: Block 0 ( BLOCK01-NEXT: Block 0 (
BLOCK01-NEXT: 0000: 4D696372 6F736F66 7420432F 432B2B20 4D534620 372E3030 0D0A1A44 53000000 |Microsoft C/C++ MSF 7.00...DS...| BLOCK01-NEXT: 0000: 4D696372 6F736F66 7420432F 432B2B20 |Microsoft C/C++ |
BLOCK01-NEXT: 0020: 00100000 02000000 19000000 88000000 00000000 18000000 00000000 00000000 |................................| BLOCK01-NEXT: 0010: 4D534620 372E3030 0D0A1A44 53000000 |MSF 7.00...DS...|
BLOCK01-NEXT: 0040: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| BLOCK01-NEXT: 0020: 00100000 02000000 19000000 88000000 |................|
BLOCK01-NEXT: 0060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 |................................| BLOCK01-NEXT: 0030: 00000000 18000000 00000000 00000000 |................|
BLOCK01: Block 1 ( BLOCK01: 0FE0: 00000000 00000000 00000000 00000000 |................|
BLOCK01-NEXT: 0000: C0FCFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................................| BLOCK01-NEXT: 0FF0: 00000000 00000000 00000000 00000000 |................|
BLOCK01-NEXT: 0020: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................................| BLOCK01-NEXT: )
BLOCK01-NEXT: 0040: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................................| BLOCK01-NEXT: Block 1 (
BLOCK01-NOT: Block 2 ( BLOCK01-NEXT: 0000: C0FCFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
BLOCK01-NEXT: 0010: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
BLOCK01: 0FE0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
BLOCK01-NEXT: 0FF0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
BLOCK01-NEXT: )
BLOCK01-NEXT: }
BADSYNTAX: Argument '{{.*}}' invalid format. BADSYNTAX: Argument '{{.*}}' invalid format.

View File

@ -1,28 +1,23 @@
; RUN: llvm-pdbutil raw -stream-data=1 %p/Inputs/empty.pdb | FileCheck --check-prefix=STREAM %s ; RUN: llvm-pdbutil raw -stream-data=1 %p/Inputs/empty.pdb | FileCheck --check-prefix=STREAM1 %s
; RUN: llvm-pdbutil raw -stream-data=100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=INVALIDSTREAM %s ; RUN: not llvm-pdbutil raw -stream-data=100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=INVALIDSTREAM %s
; RUN: llvm-pdbutil raw -stream-data=1,100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BOTH %s
STREAM: Stream Data STREAM1: Stream Data {
STREAM-NEXT: ============================================================ STREAM1-NEXT: Stream {
STREAM-NEXT: Stream 1 (118 bytes): PDB Stream STREAM1-NEXT: Index: 1
STREAM-NEXT: Data ( STREAM1-NEXT: Type: PDB Stream
STREAM-NEXT: 0000: 942E3101 E207E554 01000000 0B355641 86A0A249 896F9988 FAE52FF0 22000000 |..1....T.....5VA...I.o..../."...| STREAM1-NEXT: Size: 118
STREAM-NEXT: 0020: 2F4C696E 6B496E66 6F002F6E 616D6573 002F7372 632F6865 61646572 626C6F63 |/LinkInfo./names./src/headerbloc| STREAM1-NEXT: Blocks: [19]
STREAM-NEXT: 0040: 6B000300 00000600 00000100 00001A00 00000000 00001100 00000900 00000A00 |k...............................| STREAM1-NEXT: Data (
STREAM-NEXT: 0060: 00000D00 00000000 00000500 00000000 00004191 3201 |..................A.2.| STREAM1-NEXT: 0000: 942E3101 E207E554 01000000 0B355641 |..1....T.....5VA|
STREAM-NEXT: ) STREAM1-NEXT: 0010: 86A0A249 896F9988 FAE52FF0 22000000 |...I.o..../."...|
STREAM1-NEXT: 0020: 2F4C696E 6B496E66 6F002F6E 616D6573 |/LinkInfo./names|
STREAM1-NEXT: 0030: 002F7372 632F6865 61646572 626C6F63 |./src/headerbloc|
STREAM1-NEXT: 0040: 6B000300 00000600 00000100 00001A00 |k...............|
STREAM1-NEXT: 0050: 00000000 00001100 00000900 00000A00 |................|
STREAM1-NEXT: 0060: 00000D00 00000000 00000500 00000000 |................|
STREAM1-NEXT: 0070: 00004191 3201 |..A.2.|
STREAM1-NEXT: )
STREAM1-NEXT: }
STREAM1-NEXT: }
INVALIDSTREAM: Stream Data INVALIDSTREAM: Native PDB Error: The specified stream could not be loaded.
INVALIDSTREAM-NEXT: ============================================================
INVALIDSTREAM-NEXT: Stream 100: Not present
BOTH: Stream Data
BOTH-NEXT: ============================================================
BOTH-NEXT: Stream 1 (118 bytes): PDB Stream
BOTH-NEXT: Data (
BOTH-NEXT: 0000: 942E3101 E207E554 01000000 0B355641 86A0A249 896F9988 FAE52FF0 22000000 |..1....T.....5VA...I.o..../."...|
BOTH-NEXT: 0020: 2F4C696E 6B496E66 6F002F6E 616D6573 002F7372 632F6865 61646572 626C6F63 |/LinkInfo./names./src/headerbloc|
BOTH-NEXT: 0040: 6B000300 00000600 00000100 00001A00 00000000 00001100 00000900 00000A00 |k...............................|
BOTH-NEXT: 0060: 00000D00 00000000 00000500 00000000 00004191 3201 |..................A.2.|
BOTH-NEXT: )
BOTH-NEXT: Stream 100: Not present

View File

@ -3,33 +3,48 @@ RUN: -pdb-stream -string-table -tpi-stream -stream-directory \
RUN: -stream-metadata %p/Inputs/empty.pdb > %t.1 RUN: -stream-metadata %p/Inputs/empty.pdb > %t.1
RUN: llvm-pdbutil yaml2pdb -pdb=%t.2 %t.1 RUN: llvm-pdbutil yaml2pdb -pdb=%t.2 %t.1
RUN: llvm-pdbutil raw -summary -string-table -types %p/Inputs/empty.pdb | FileCheck %s RUN: llvm-pdbutil raw -headers -string-table -tpi-records %p/Inputs/empty.pdb | FileCheck %s
RUN: llvm-pdbutil raw -summary -string-table -types %t.2 | FileCheck %s RUN: llvm-pdbutil raw -headers -string-table -tpi-records %t.2 | FileCheck %s
CHECK: FileHeaders {
CHECK: Summary
CHECK-NEXT: ============================================================
CHECK-NEXT: BlockSize: 4096 CHECK-NEXT: BlockSize: 4096
CHECK-NEXT: Number of blocks: CHECK-NEXT: FreeBlockMap:
CHECK-NEXT: Number of streams: CHECK-NEXT: NumBlocks:
CHECK-NEXT: Signature: 1424295906 CHECK-NEXT: NumDirectoryBytes:
CHECK-NEXT: Unknown1: 0
CHECK-NEXT: BlockMapAddr:
CHECK-NEXT: NumDirectoryBlocks: 1
CHECK-NEXT: DirectoryBlocks:
CHECK-NEXT: NumStreams:
CHECK-NEXT: }
CHECK: String Table {
CHECK-DAG: 'd:\src\llvm\test\debuginfo\pdb\inputs\predefined c++ attributes (compiler internal)'
CHECK-DAG: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
CHECK-DAG: '$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = '
CHECK-NEXT: }
CHECK: PDB Stream {
CHECK-NEXT: Version: 20000404
CHECK-NEXT: Signature: 0x54E507E2
CHECK-NEXT: Age: 1 CHECK-NEXT: Age: 1
CHECK-NEXT: GUID: {0B355641-86A0-A249-896F-9988FAE52FF0} CHECK-NEXT: Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
CHECK-NEXT: Features: 0x1 CHECK-NEXT: Features: 0x1
CHECK-NEXT: Has Debug Info: true CHECK-NEXT: Named Streams {
CHECK-NEXT: Has Types: true CHECK: /names:
CHECK-NEXT: Has IDs: true CHECK: }
CHECK-NEXT: Has Globals: CHECK-NEXT: }
CHECK-NEXT: Has Publics: CHECK: Type Info Stream (TPI) {
CHECK-NEXT: Is incrementally linked: true CHECK-NEXT: TPI Version: 20040203
CHECK-NEXT: Has conflicting types: false CHECK-NEXT: Record count: 75
CHECK-NEXT: Is stripped: false CHECK: DBI Stream {
CHECK: String Table CHECK-NEXT: Dbi Version: 19990903
CHECK-NEXT: ============================================================ CHECK-NEXT: Age: 1
CHECK-NEXT: ID | String CHECK-NEXT: Incremental Linking: Yes
CHECK-NEXT: {{.*}} | 'd:\src\llvm\test\debuginfo\pdb\inputs\predefined c++ attributes (compiler internal)' CHECK-NEXT: Has CTypes: No
CHECK-NEXT: {{.*}} | 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp' CHECK-NEXT: Is Stripped: No
CHECK-NEXT: {{.*}} | '$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = ' CHECK-NEXT: Machine Type: x86
CHECK: Types (TPI Stream) CHECK-NEXT: Symbol Record Stream Index:
CHECK-NEXT: ============================================================ CHECK-NEXT: Public Symbol Stream Index:
CHECK-NEXT: Showing 75 records CHECK-NEXT: Global Symbol Stream Index:
CHECK-NEXT: Toolchain Version: 12.0
CHECK-NEXT: mspdb120.dll version: 12.0.31101
CHECK-NEXT: }

View File

@ -0,0 +1,47 @@
; RUN: llvm-pdbutil raw -stream-data=8 %p/Inputs/LoadAddressTest.pdb \
; RUN: | FileCheck %s -check-prefix=FULL_STREAM
; RUN: llvm-pdbutil raw -stream-data=8:4 %p/Inputs/LoadAddressTest.pdb \
; RUN: | FileCheck %s -check-prefix=OFFSET_STREAM
; RUN: llvm-pdbutil raw -stream-data=8:4@24 %p/Inputs/LoadAddressTest.pdb \
; RUN: | FileCheck %s -check-prefix=OFFSET_AND_LENGTH
FULL_STREAM: Stream Data {
FULL_STREAM-NEXT: Stream {
FULL_STREAM-NEXT: Index: 8
FULL_STREAM-NEXT: Type: Public Symbol Records
FULL_STREAM-NEXT: Size: 40
FULL_STREAM-NEXT: Blocks:
FULL_STREAM-NEXT: Data (
FULL_STREAM-NEXT: 0000: 12000E11 02000000 10000000 01005F6D |.............._m|
FULL_STREAM-NEXT: 0010: 61696E00 12002511 00000000 88000000 |ain...%.........|
FULL_STREAM-NEXT: 0020: 01006D61 696E0000 |..main..|
FULL_STREAM-NEXT: )
FULL_STREAM-NEXT: }
FULL_STREAM-NEXT: }
OFFSET_STREAM: Stream Data {
OFFSET_STREAM-NEXT: Stream {
OFFSET_STREAM-NEXT: Index: 8
OFFSET_STREAM-NEXT: Type: Public Symbol Records
OFFSET_STREAM-NEXT: Size: 40
OFFSET_STREAM-NEXT: Blocks:
OFFSET_STREAM-NEXT: Data (
OFFSET_STREAM-NEXT: 0004: 02000000 10000000 01005F6D 61696E00 |.........._main.|
OFFSET_STREAM-NEXT: 0014: 12002511 00000000 88000000 01006D61 |..%...........ma|
OFFSET_STREAM-NEXT: 0024: 696E0000 |in..|
OFFSET_STREAM-NEXT: )
OFFSET_STREAM-NEXT: }
OFFSET_STREAM-NEXT:}
OFFSET_AND_LENGTH: Stream Data {
OFFSET_AND_LENGTH-NEXT: Stream {
OFFSET_AND_LENGTH-NEXT: Index: 8
OFFSET_AND_LENGTH-NEXT: Type: Public Symbol Records
OFFSET_AND_LENGTH-NEXT: Size: 40
OFFSET_AND_LENGTH-NEXT: Blocks:
OFFSET_AND_LENGTH-NEXT: Data (
OFFSET_AND_LENGTH-NEXT: 0004: 02000000 10000000 01005F6D 61696E00 |.........._main.|
OFFSET_AND_LENGTH-NEXT: 0014: 12002511 00000000 |..%.....|
OFFSET_AND_LENGTH-NEXT: )
OFFSET_AND_LENGTH-NEXT: }
OFFSET_AND_LENGTH-NEXT:}

View File

@ -12,10 +12,8 @@ add_llvm_tool(llvm-pdbutil
CompactTypeDumpVisitor.cpp CompactTypeDumpVisitor.cpp
Diff.cpp Diff.cpp
llvm-pdbutil.cpp llvm-pdbutil.cpp
FormatUtil.cpp
LinePrinter.cpp LinePrinter.cpp
MinimalSymbolDumper.cpp LLVMOutputStyle.cpp
MinimalTypeDumper.cpp
PdbYaml.cpp PdbYaml.cpp
PrettyBuiltinDumper.cpp PrettyBuiltinDumper.cpp
PrettyClassDefinitionDumper.cpp PrettyClassDefinitionDumper.cpp
@ -27,7 +25,6 @@ add_llvm_tool(llvm-pdbutil
PrettyTypeDumper.cpp PrettyTypeDumper.cpp
PrettyTypedefDumper.cpp PrettyTypedefDumper.cpp
PrettyVariableDumper.cpp PrettyVariableDumper.cpp
RawOutputStyle.cpp
StreamUtil.cpp StreamUtil.cpp
YAMLOutputStyle.cpp YAMLOutputStyle.cpp
) )

View File

@ -1,49 +0,0 @@
//===- FormatUtil.cpp ----------------------------------------- *- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "FormatUtil.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace llvm::pdb;
std::string llvm::pdb::typesetItemList(ArrayRef<std::string> Opts,
uint32_t GroupSize, uint32_t IndentLevel,
StringRef Sep) {
std::string Result;
while (!Opts.empty()) {
ArrayRef<std::string> ThisGroup;
ThisGroup = Opts.take_front(GroupSize);
Opts = Opts.drop_front(ThisGroup.size());
Result += join(ThisGroup, Sep);
if (!Opts.empty()) {
Result += Sep;
Result += "\n";
Result += formatv("{0}", fmt_repeat(' ', IndentLevel));
}
}
return Result;
}
std::string llvm::pdb::typesetStringList(uint32_t IndentLevel,
ArrayRef<StringRef> Strings) {
std::string Result = "[";
for (const auto &S : Strings) {
Result += formatv("\n{0}{1}", fmt_repeat(' ', IndentLevel), S);
}
Result += "]";
return Result;
}
std::string llvm::pdb::formatSegmentOffset(uint16_t Segment, uint32_t Offset) {
return formatv("{0:4}:{1:4}", Segment, Offset);
}

View File

@ -1,92 +0,0 @@
//===- FormatUtil.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_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H
#define LLVM_TOOLS_LLVMPDBUTIL_FORMAT_UTIL_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatVariadic.h"
#include <string>
#include <type_traits>
namespace llvm {
namespace pdb {
#define PUSH_MASKED_FLAG(Enum, Mask, TheOpt, Value, Text) \
if (Enum::TheOpt == (Value & Mask)) \
Opts.push_back(Text);
#define PUSH_FLAG(Enum, TheOpt, Value, Text) \
PUSH_MASKED_FLAG(Enum, Enum::TheOpt, TheOpt, Value, Text)
#define RETURN_CASE(Enum, X, Ret) \
case Enum::X: \
return Ret;
template <typename T> static std::string formatUnknownEnum(T Value) {
return formatv("unknown ({0})",
static_cast<typename std::underlying_type<T>::type>(Value))
.str();
}
std::string formatSegmentOffset(uint16_t Segment, uint32_t Offset);
std::string typesetItemList(ArrayRef<std::string> Opts, uint32_t IndentLevel,
uint32_t GroupSize, StringRef Sep);
std::string typesetStringList(uint32_t IndentLevel,
ArrayRef<StringRef> Strings);
/// Returns the number of digits in the given integer.
inline int NumDigits(uint64_t N) {
if (N < 10ULL)
return 1;
if (N < 100ULL)
return 2;
if (N < 1000ULL)
return 3;
if (N < 10000ULL)
return 4;
if (N < 100000ULL)
return 5;
if (N < 1000000ULL)
return 6;
if (N < 10000000ULL)
return 7;
if (N < 100000000ULL)
return 8;
if (N < 1000000000ULL)
return 9;
if (N < 10000000000ULL)
return 10;
if (N < 100000000000ULL)
return 11;
if (N < 1000000000000ULL)
return 12;
if (N < 10000000000000ULL)
return 13;
if (N < 100000000000000ULL)
return 14;
if (N < 1000000000000000ULL)
return 15;
if (N < 10000000000000000ULL)
return 16;
if (N < 100000000000000000ULL)
return 17;
if (N < 1000000000000000000ULL)
return 18;
if (N < 10000000000000000000ULL)
return 19;
return 20;
}
}
} // namespace llvm
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
//===- RawOutputStyle.h -------------------------------------- *- C++ --*-===// //===- LLVMOutputStyle.h -------------------------------------- *- C++ --*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -7,15 +7,15 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVMPDBDUMP_RAWOUTPUTSTYLE_H #ifndef LLVM_TOOLS_LLVMPDBDUMP_LLVMOUTPUTSTYLE_H
#define LLVM_TOOLS_LLVMPDBDUMP_RAWOUTPUTSTYLE_H #define LLVM_TOOLS_LLVMPDBDUMP_LLVMOUTPUTSTYLE_H
#include "LinePrinter.h"
#include "OutputStyle.h" #include "OutputStyle.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h" #include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/Support/ScopedPrinter.h"
#include <string> #include <string>
@ -27,9 +27,9 @@ class LazyRandomTypeCollection;
} }
namespace pdb { namespace pdb {
class RawOutputStyle : public OutputStyle { class LLVMOutputStyle : public OutputStyle {
public: public:
RawOutputStyle(PDBFile &File); LLVMOutputStyle(PDBFile &File);
Error dump() override; Error dump() override;
@ -37,25 +37,34 @@ private:
Expected<codeview::LazyRandomTypeCollection &> Expected<codeview::LazyRandomTypeCollection &>
initializeTypeDatabase(uint32_t SN); initializeTypeDatabase(uint32_t SN);
Error dumpFileSummary(); Error dumpFileHeaders();
Error dumpStreamSummary(); Error dumpStreamSummary();
Error dumpFreePageMap();
Error dumpBlockRanges(); Error dumpBlockRanges();
Error dumpGlobalsStream();
Error dumpStreamBytes(); Error dumpStreamBytes();
Error dumpStreamBlocks();
Error dumpStringTable(); Error dumpStringTable();
Error dumpInfoStream();
Error dumpTpiStream(uint32_t StreamIdx); Error dumpTpiStream(uint32_t StreamIdx);
Error dumpModules(); Error dumpDbiStream();
Error dumpModuleSyms();
Error dumpPublics();
Error dumpSectionContribs(); Error dumpSectionContribs();
Error dumpSectionMap(); Error dumpSectionMap();
Error dumpPublicsStream();
Error dumpSectionHeaders();
Error dumpFpoStream();
void dumpBitVector(StringRef Name, const BitVector &V);
void flush();
PDBFile &File; PDBFile &File;
LinePrinter P; ScopedPrinter P;
std::unique_ptr<codeview::LazyRandomTypeCollection> TpiTypes; std::unique_ptr<codeview::LazyRandomTypeCollection> TpiTypes;
std::unique_ptr<codeview::LazyRandomTypeCollection> IpiTypes; std::unique_ptr<codeview::LazyRandomTypeCollection> IpiTypes;
SmallVector<std::string, 32> StreamPurposes; SmallVector<std::string, 32> StreamPurposes;
}; };
} // namespace pdb }
} // namespace llvm }
#endif #endif

View File

@ -13,7 +13,6 @@
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/PDB/UDTLayout.h" #include "llvm/DebugInfo/PDB/UDTLayout.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Regex.h" #include "llvm/Support/Regex.h"
#include <algorithm> #include <algorithm>
@ -61,16 +60,10 @@ LinePrinter::LinePrinter(int Indent, bool UseColor, llvm::raw_ostream &Stream)
opts::pretty::IncludeCompilands.end()); opts::pretty::IncludeCompilands.end());
} }
void LinePrinter::Indent(uint32_t Amount) { void LinePrinter::Indent() { CurrentIndent += IndentSpaces; }
if (Amount == 0)
Amount = IndentSpaces;
CurrentIndent += Amount;
}
void LinePrinter::Unindent(uint32_t Amount) { void LinePrinter::Unindent() {
if (Amount == 0) CurrentIndent = std::max(0, CurrentIndent - IndentSpaces);
Amount = IndentSpaces;
CurrentIndent = std::max<int>(0, CurrentIndent - Amount);
} }
void LinePrinter::NewLine() { void LinePrinter::NewLine() {
@ -78,13 +71,6 @@ void LinePrinter::NewLine() {
OS.indent(CurrentIndent); OS.indent(CurrentIndent);
} }
void LinePrinter::print(const Twine &T) { OS << T; }
void LinePrinter::printLine(const Twine &T) {
NewLine();
OS << T;
}
bool LinePrinter::IsClassExcluded(const ClassLayout &Class) { bool LinePrinter::IsClassExcluded(const ClassLayout &Class) {
if (IsTypeExcluded(Class.getName(), Class.getSize())) if (IsTypeExcluded(Class.getName(), Class.getSize()))
return true; return true;
@ -93,19 +79,6 @@ bool LinePrinter::IsClassExcluded(const ClassLayout &Class) {
return false; return false;
} }
void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
uint32_t StartOffset) {
NewLine();
OS << Label << " (";
if (!Data.empty()) {
OS << "\n";
OS << format_bytes_with_ascii(Data, StartOffset, 32, 4,
CurrentIndent + IndentSpaces, true);
NewLine();
}
OS << ")";
}
bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size) { bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size) {
if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters)) if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters))
return true; return true;

View File

@ -10,12 +10,10 @@
#ifndef LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H #ifndef LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H
#define LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H #define LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h" #include "llvm/ADT/Twine.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Regex.h"
#include <list> #include <list>
@ -30,22 +28,10 @@ class LinePrinter {
public: public:
LinePrinter(int Indent, bool UseColor, raw_ostream &Stream); LinePrinter(int Indent, bool UseColor, raw_ostream &Stream);
void Indent(uint32_t Amount = 0); void Indent();
void Unindent(uint32_t Amount = 0); void Unindent();
void NewLine(); void NewLine();
void printLine(const Twine &T);
void print(const Twine &T);
template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) {
printLine(formatv(Fmt, std::forward<Ts>(Items)...));
}
template <typename... Ts> void format(const char *Fmt, Ts &&... Items) {
print(formatv(Fmt, std::forward<Ts>(Items)...));
}
void formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
uint32_t StartOffset);
bool hasColor() const { return UseColor; } bool hasColor() const { return UseColor; }
raw_ostream &getStream() { return OS; } raw_ostream &getStream() { return OS; }
int getIndentLevel() const { return CurrentIndent; } int getIndentLevel() const { return CurrentIndent; }
@ -77,17 +63,6 @@ private:
std::list<Regex> IncludeSymbolFilters; std::list<Regex> IncludeSymbolFilters;
}; };
struct AutoIndent {
explicit AutoIndent(LinePrinter &L, uint32_t Amount = 0)
: L(L), Amount(Amount) {
L.Indent(Amount);
}
~AutoIndent() { L.Unindent(Amount); }
LinePrinter &L;
uint32_t Amount = 0;
};
template <class T> template <class T>
inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) { inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) {
Printer.getStream() << Item; Printer.getStream() << Item;

View File

@ -1,749 +0,0 @@
//===- MinimalSymbolDumper.cpp -------------------------------- *- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MinimalSymbolDumper.h"
#include "FormatUtil.h"
#include "LinePrinter.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::pdb;
static StringRef getSymbolKindName(SymbolKind K) {
switch (K) {
#define SYMBOL_RECORD(EnumName, value, name) \
case EnumName: \
return #EnumName;
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
default:
llvm_unreachable("Unknown symbol kind!");
}
return "";
}
static std::string formatLocalSymFlags(uint32_t IndentLevel,
LocalSymFlags Flags) {
std::vector<std::string> Opts;
if (Flags == LocalSymFlags::None)
return "none";
PUSH_FLAG(LocalSymFlags, IsParameter, Flags, "param");
PUSH_FLAG(LocalSymFlags, IsAddressTaken, Flags, "address is taken");
PUSH_FLAG(LocalSymFlags, IsCompilerGenerated, Flags, "compiler generated");
PUSH_FLAG(LocalSymFlags, IsAggregate, Flags, "aggregate");
PUSH_FLAG(LocalSymFlags, IsAggregated, Flags, "aggregated");
PUSH_FLAG(LocalSymFlags, IsAliased, Flags, "aliased");
PUSH_FLAG(LocalSymFlags, IsAlias, Flags, "alias");
PUSH_FLAG(LocalSymFlags, IsReturnValue, Flags, "return val");
PUSH_FLAG(LocalSymFlags, IsOptimizedOut, Flags, "optimized away");
PUSH_FLAG(LocalSymFlags, IsEnregisteredGlobal, Flags, "enreg global");
PUSH_FLAG(LocalSymFlags, IsEnregisteredStatic, Flags, "enreg static");
return typesetItemList(Opts, 4, IndentLevel, " | ");
}
static std::string formatExportFlags(uint32_t IndentLevel, ExportFlags Flags) {
std::vector<std::string> Opts;
if (Flags == ExportFlags::None)
return "none";
PUSH_FLAG(ExportFlags, IsConstant, Flags, "constant");
PUSH_FLAG(ExportFlags, IsData, Flags, "data");
PUSH_FLAG(ExportFlags, IsPrivate, Flags, "private");
PUSH_FLAG(ExportFlags, HasNoName, Flags, "no name");
PUSH_FLAG(ExportFlags, HasExplicitOrdinal, Flags, "explicit ord");
PUSH_FLAG(ExportFlags, IsForwarder, Flags, "forwarder");
return typesetItemList(Opts, 4, IndentLevel, " | ");
}
static std::string formatCompileSym2Flags(uint32_t IndentLevel,
CompileSym2Flags Flags) {
std::vector<std::string> Opts;
Flags &= ~CompileSym2Flags::SourceLanguageMask;
if (Flags == CompileSym2Flags::None)
return "none";
PUSH_FLAG(CompileSym2Flags, EC, Flags, "edit and continue");
PUSH_FLAG(CompileSym2Flags, NoDbgInfo, Flags, "no dbg info");
PUSH_FLAG(CompileSym2Flags, LTCG, Flags, "ltcg");
PUSH_FLAG(CompileSym2Flags, NoDataAlign, Flags, "no data align");
PUSH_FLAG(CompileSym2Flags, ManagedPresent, Flags, "has managed code");
PUSH_FLAG(CompileSym2Flags, SecurityChecks, Flags, "security checks");
PUSH_FLAG(CompileSym2Flags, HotPatch, Flags, "hot patchable");
PUSH_FLAG(CompileSym2Flags, CVTCIL, Flags, "cvtcil");
PUSH_FLAG(CompileSym2Flags, MSILModule, Flags, "msil module");
return typesetItemList(Opts, 4, IndentLevel, " | ");
}
static std::string formatCompileSym3Flags(uint32_t IndentLevel,
CompileSym3Flags Flags) {
std::vector<std::string> Opts;
Flags &= ~CompileSym3Flags::SourceLanguageMask;
if (Flags == CompileSym3Flags::None)
return "none";
PUSH_FLAG(CompileSym3Flags, EC, Flags, "edit and continue");
PUSH_FLAG(CompileSym3Flags, NoDbgInfo, Flags, "no dbg info");
PUSH_FLAG(CompileSym3Flags, LTCG, Flags, "ltcg");
PUSH_FLAG(CompileSym3Flags, NoDataAlign, Flags, "no data align");
PUSH_FLAG(CompileSym3Flags, ManagedPresent, Flags, "has managed code");
PUSH_FLAG(CompileSym3Flags, SecurityChecks, Flags, "security checks");
PUSH_FLAG(CompileSym3Flags, HotPatch, Flags, "hot patchable");
PUSH_FLAG(CompileSym3Flags, CVTCIL, Flags, "cvtcil");
PUSH_FLAG(CompileSym3Flags, MSILModule, Flags, "msil module");
PUSH_FLAG(CompileSym3Flags, Sdl, Flags, "sdl");
PUSH_FLAG(CompileSym3Flags, PGO, Flags, "pgo");
PUSH_FLAG(CompileSym3Flags, Exp, Flags, "exp");
return typesetItemList(Opts, 4, IndentLevel, " | ");
}
static std::string formatFrameProcedureOptions(uint32_t IndentLevel,
FrameProcedureOptions FPO) {
std::vector<std::string> Opts;
if (FPO == FrameProcedureOptions::None)
return "none";
PUSH_FLAG(FrameProcedureOptions, HasAlloca, FPO, "has alloca");
PUSH_FLAG(FrameProcedureOptions, HasSetJmp, FPO, "has setjmp");
PUSH_FLAG(FrameProcedureOptions, HasLongJmp, FPO, "has longjmp");
PUSH_FLAG(FrameProcedureOptions, HasInlineAssembly, FPO, "has inline asm");
PUSH_FLAG(FrameProcedureOptions, HasExceptionHandling, FPO, "has eh");
PUSH_FLAG(FrameProcedureOptions, MarkedInline, FPO, "marked inline");
PUSH_FLAG(FrameProcedureOptions, HasStructuredExceptionHandling, FPO,
"has seh");
PUSH_FLAG(FrameProcedureOptions, Naked, FPO, "naked");
PUSH_FLAG(FrameProcedureOptions, SecurityChecks, FPO, "secure checks");
PUSH_FLAG(FrameProcedureOptions, AsynchronousExceptionHandling, FPO,
"has async eh");
PUSH_FLAG(FrameProcedureOptions, NoStackOrderingForSecurityChecks, FPO,
"no stack order");
PUSH_FLAG(FrameProcedureOptions, Inlined, FPO, "inlined");
PUSH_FLAG(FrameProcedureOptions, StrictSecurityChecks, FPO,
"strict secure checks");
PUSH_FLAG(FrameProcedureOptions, SafeBuffers, FPO, "safe buffers");
PUSH_FLAG(FrameProcedureOptions, ProfileGuidedOptimization, FPO, "pgo");
PUSH_FLAG(FrameProcedureOptions, ValidProfileCounts, FPO,
"has profile counts");
PUSH_FLAG(FrameProcedureOptions, OptimizedForSpeed, FPO, "opt speed");
PUSH_FLAG(FrameProcedureOptions, GuardCfg, FPO, "guard cfg");
PUSH_FLAG(FrameProcedureOptions, GuardCfw, FPO, "guard cfw");
return typesetItemList(Opts, 4, IndentLevel, " | ");
}
static std::string formatProcSymFlags(uint32_t IndentLevel,
ProcSymFlags Flags) {
std::vector<std::string> Opts;
if (Flags == ProcSymFlags::None)
return "none";
PUSH_FLAG(ProcSymFlags, HasFP, Flags, "has fp");
PUSH_FLAG(ProcSymFlags, HasIRET, Flags, "has iret");
PUSH_FLAG(ProcSymFlags, HasFRET, Flags, "has fret");
PUSH_FLAG(ProcSymFlags, IsNoReturn, Flags, "noreturn");
PUSH_FLAG(ProcSymFlags, IsUnreachable, Flags, "unreachable");
PUSH_FLAG(ProcSymFlags, HasCustomCallingConv, Flags, "custom calling conv");
PUSH_FLAG(ProcSymFlags, IsNoInline, Flags, "noinline");
PUSH_FLAG(ProcSymFlags, HasOptimizedDebugInfo, Flags, "opt debuginfo");
return typesetItemList(Opts, 4, IndentLevel, " | ");
}
static std::string formatThunkOrdinal(ThunkOrdinal Ordinal) {
switch (Ordinal) {
RETURN_CASE(ThunkOrdinal, Standard, "thunk");
RETURN_CASE(ThunkOrdinal, ThisAdjustor, "this adjustor");
RETURN_CASE(ThunkOrdinal, Vcall, "vcall");
RETURN_CASE(ThunkOrdinal, Pcode, "pcode");
RETURN_CASE(ThunkOrdinal, UnknownLoad, "unknown load");
RETURN_CASE(ThunkOrdinal, TrampIncremental, "tramp incremental");
RETURN_CASE(ThunkOrdinal, BranchIsland, "branch island");
}
return formatUnknownEnum(Ordinal);
}
static std::string formatTrampolineType(TrampolineType Tramp) {
switch (Tramp) {
RETURN_CASE(TrampolineType, TrampIncremental, "tramp incremental");
RETURN_CASE(TrampolineType, BranchIsland, "branch island");
}
return formatUnknownEnum(Tramp);
}
static std::string formatSourceLanguage(SourceLanguage Lang) {
switch (Lang) {
RETURN_CASE(SourceLanguage, C, "c");
RETURN_CASE(SourceLanguage, Cpp, "c++");
RETURN_CASE(SourceLanguage, Fortran, "fortran");
RETURN_CASE(SourceLanguage, Masm, "masm");
RETURN_CASE(SourceLanguage, Pascal, "pascal");
RETURN_CASE(SourceLanguage, Basic, "basic");
RETURN_CASE(SourceLanguage, Cobol, "cobol");
RETURN_CASE(SourceLanguage, Link, "link");
RETURN_CASE(SourceLanguage, VB, "vb");
RETURN_CASE(SourceLanguage, Cvtres, "cvtres");
RETURN_CASE(SourceLanguage, Cvtpgd, "cvtpgd");
RETURN_CASE(SourceLanguage, CSharp, "c#");
RETURN_CASE(SourceLanguage, ILAsm, "il asm");
RETURN_CASE(SourceLanguage, Java, "java");
RETURN_CASE(SourceLanguage, JScript, "javascript");
RETURN_CASE(SourceLanguage, MSIL, "msil");
RETURN_CASE(SourceLanguage, HLSL, "hlsl");
}
return formatUnknownEnum(Lang);
}
static std::string formatMachineType(CPUType Cpu) {
switch (Cpu) {
RETURN_CASE(CPUType, Intel8080, "intel 8080");
RETURN_CASE(CPUType, Intel8086, "intel 8086");
RETURN_CASE(CPUType, Intel80286, "intel 80286");
RETURN_CASE(CPUType, Intel80386, "intel 80386");
RETURN_CASE(CPUType, Intel80486, "intel 80486");
RETURN_CASE(CPUType, Pentium, "intel pentium");
RETURN_CASE(CPUType, PentiumPro, "intel pentium pro");
RETURN_CASE(CPUType, Pentium3, "intel pentium 3");
RETURN_CASE(CPUType, MIPS, "mips");
RETURN_CASE(CPUType, MIPS16, "mips-16");
RETURN_CASE(CPUType, MIPS32, "mips-32");
RETURN_CASE(CPUType, MIPS64, "mips-64");
RETURN_CASE(CPUType, MIPSI, "mips i");
RETURN_CASE(CPUType, MIPSII, "mips ii");
RETURN_CASE(CPUType, MIPSIII, "mips iii");
RETURN_CASE(CPUType, MIPSIV, "mips iv");
RETURN_CASE(CPUType, MIPSV, "mips v");
RETURN_CASE(CPUType, M68000, "motorola 68000");
RETURN_CASE(CPUType, M68010, "motorola 68010");
RETURN_CASE(CPUType, M68020, "motorola 68020");
RETURN_CASE(CPUType, M68030, "motorola 68030");
RETURN_CASE(CPUType, M68040, "motorola 68040");
RETURN_CASE(CPUType, Alpha, "alpha");
RETURN_CASE(CPUType, Alpha21164, "alpha 21164");
RETURN_CASE(CPUType, Alpha21164A, "alpha 21164a");
RETURN_CASE(CPUType, Alpha21264, "alpha 21264");
RETURN_CASE(CPUType, Alpha21364, "alpha 21364");
RETURN_CASE(CPUType, PPC601, "powerpc 601");
RETURN_CASE(CPUType, PPC603, "powerpc 603");
RETURN_CASE(CPUType, PPC604, "powerpc 604");
RETURN_CASE(CPUType, PPC620, "powerpc 620");
RETURN_CASE(CPUType, PPCFP, "powerpc fp");
RETURN_CASE(CPUType, PPCBE, "powerpc be");
RETURN_CASE(CPUType, SH3, "sh3");
RETURN_CASE(CPUType, SH3E, "sh3e");
RETURN_CASE(CPUType, SH3DSP, "sh3 dsp");
RETURN_CASE(CPUType, SH4, "sh4");
RETURN_CASE(CPUType, SHMedia, "shmedia");
RETURN_CASE(CPUType, ARM3, "arm 3");
RETURN_CASE(CPUType, ARM4, "arm 4");
RETURN_CASE(CPUType, ARM4T, "arm 4t");
RETURN_CASE(CPUType, ARM5, "arm 5");
RETURN_CASE(CPUType, ARM5T, "arm 5t");
RETURN_CASE(CPUType, ARM6, "arm 6");
RETURN_CASE(CPUType, ARM_XMAC, "arm xmac");
RETURN_CASE(CPUType, ARM_WMMX, "arm wmmx");
RETURN_CASE(CPUType, ARM7, "arm 7");
RETURN_CASE(CPUType, Omni, "omni");
RETURN_CASE(CPUType, Ia64, "intel itanium ia64");
RETURN_CASE(CPUType, Ia64_2, "intel itanium ia64 2");
RETURN_CASE(CPUType, CEE, "cee");
RETURN_CASE(CPUType, AM33, "am33");
RETURN_CASE(CPUType, M32R, "m32r");
RETURN_CASE(CPUType, TriCore, "tri-core");
RETURN_CASE(CPUType, X64, "intel x86-x64");
RETURN_CASE(CPUType, EBC, "ebc");
RETURN_CASE(CPUType, Thumb, "thumb");
RETURN_CASE(CPUType, ARMNT, "arm nt");
RETURN_CASE(CPUType, D3D11_Shader, "d3d11 shader");
}
return formatUnknownEnum(Cpu);
}
static std::string formatCookieKind(FrameCookieKind Kind) {
switch (Kind) {
RETURN_CASE(FrameCookieKind, Copy, "copy");
RETURN_CASE(FrameCookieKind, XorStackPointer, "xor stack ptr");
RETURN_CASE(FrameCookieKind, XorFramePointer, "xor frame ptr");
RETURN_CASE(FrameCookieKind, XorR13, "xor rot13");
}
return formatUnknownEnum(Kind);
}
static std::string formatRegisterId(RegisterId Id) {
switch (Id) {
RETURN_CASE(RegisterId, VFrame, "vframe");
RETURN_CASE(RegisterId, AL, "al");
RETURN_CASE(RegisterId, CL, "cl");
RETURN_CASE(RegisterId, DL, "dl");
RETURN_CASE(RegisterId, BL, "bl");
RETURN_CASE(RegisterId, AH, "ah");
RETURN_CASE(RegisterId, CH, "ch");
RETURN_CASE(RegisterId, DH, "dh");
RETURN_CASE(RegisterId, BH, "bh");
RETURN_CASE(RegisterId, AX, "ax");
RETURN_CASE(RegisterId, CX, "cx");
RETURN_CASE(RegisterId, DX, "dx");
RETURN_CASE(RegisterId, BX, "bx");
RETURN_CASE(RegisterId, SP, "sp");
RETURN_CASE(RegisterId, BP, "bp");
RETURN_CASE(RegisterId, SI, "si");
RETURN_CASE(RegisterId, DI, "di");
RETURN_CASE(RegisterId, EAX, "eax");
RETURN_CASE(RegisterId, ECX, "ecx");
RETURN_CASE(RegisterId, EDX, "edx");
RETURN_CASE(RegisterId, EBX, "ebx");
RETURN_CASE(RegisterId, ESP, "esp");
RETURN_CASE(RegisterId, EBP, "ebp");
RETURN_CASE(RegisterId, ESI, "esi");
RETURN_CASE(RegisterId, EDI, "edi");
RETURN_CASE(RegisterId, ES, "es");
RETURN_CASE(RegisterId, CS, "cs");
RETURN_CASE(RegisterId, SS, "ss");
RETURN_CASE(RegisterId, DS, "ds");
RETURN_CASE(RegisterId, FS, "fs");
RETURN_CASE(RegisterId, GS, "gs");
RETURN_CASE(RegisterId, IP, "ip");
RETURN_CASE(RegisterId, RAX, "rax");
RETURN_CASE(RegisterId, RBX, "rbx");
RETURN_CASE(RegisterId, RCX, "rcx");
RETURN_CASE(RegisterId, RDX, "rdx");
RETURN_CASE(RegisterId, RSI, "rsi");
RETURN_CASE(RegisterId, RDI, "rdi");
RETURN_CASE(RegisterId, RBP, "rbp");
RETURN_CASE(RegisterId, RSP, "rsp");
RETURN_CASE(RegisterId, R8, "r8");
RETURN_CASE(RegisterId, R9, "r9");
RETURN_CASE(RegisterId, R10, "r10");
RETURN_CASE(RegisterId, R11, "r11");
RETURN_CASE(RegisterId, R12, "r12");
RETURN_CASE(RegisterId, R13, "r13");
RETURN_CASE(RegisterId, R14, "r14");
RETURN_CASE(RegisterId, R15, "r15");
default:
return formatUnknownEnum(Id);
}
}
static std::string formatRange(LocalVariableAddrRange Range) {
return formatv("[{0},+{1})",
formatSegmentOffset(Range.ISectStart, Range.OffsetStart),
Range.Range)
.str();
}
static std::string formatGaps(uint32_t IndentLevel,
ArrayRef<LocalVariableAddrGap> Gaps) {
std::vector<std::string> GapStrs;
for (const auto &G : Gaps) {
GapStrs.push_back(formatv("({0},{1})", G.GapStartOffset, G.Range).str());
}
return typesetItemList(GapStrs, 7, IndentLevel, ", ");
}
Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record) {
// formatLine puts the newline at the beginning, so we use formatLine here
// to start a new line, and then individual visit methods use format to
// append to the existing line.
P.formatLine("- {0} [size = {1}]", getSymbolKindName(Record.Type),
Record.length());
P.Indent();
return Error::success();
}
Error MinimalSymbolDumper::visitSymbolEnd(CVSymbol &Record) {
P.Unindent();
return Error::success();
}
std::string MinimalSymbolDumper::typeIndex(TypeIndex TI) const {
if (TI.isSimple())
return formatv("{0}", TI).str();
StringRef Name = Types.getTypeName(TI);
if (Name.size() > 32) {
Name = Name.take_front(32);
return formatv("{0} ({1}...)", TI, Name);
} else
return formatv("{0} ({1})", TI, Name);
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
P.format(" `{0}`", Block.Name);
AutoIndent Indent(P);
P.formatLine("parent = {0}, addr = {1}", Block.Parent,
formatSegmentOffset(Block.Segment, Block.CodeOffset));
P.formatLine("code size = {0}, end = {1}", Block.CodeSize, Block.End);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
P.format(" `{0}`", Thunk.Name);
AutoIndent Indent(P);
P.formatLine("parent = {0}, addr = {1}", Thunk.Parent,
formatSegmentOffset(Thunk.Segment, Thunk.Offset));
P.formatLine("kind = {0}, size = {1}, end = {2}, next = {3}",
formatThunkOrdinal(Thunk.Thunk), Thunk.Length, Thunk.End,
Thunk.Next);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
TrampolineSym &Tramp) {
AutoIndent Indent(P);
P.formatLine("type = {0}, size = {1}, source = {2}, target = {3}",
formatTrampolineType(Tramp.Type), Tramp.Size,
formatSegmentOffset(Tramp.ThunkSection, Tramp.ThunkOffset),
formatSegmentOffset(Tramp.TargetSection, Tramp.ThunkOffset));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
SectionSym &Section) {
P.format(" `{0}`", Section.Name);
AutoIndent Indent(P);
P.formatLine("length = {0}, alignment = {1}, rva = {2}, section # = {3}, "
"characteristics = {4}",
Section.Length, Section.Alignment, Section.Rva,
Section.SectionNumber, Section.Characteristics);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CoffGroupSym &CG) {
P.format(" `{0}`", CG.Name);
AutoIndent Indent(P);
P.formatLine("length = {0}, addr = {1}, characteristics = {2}", CG.Size,
formatSegmentOffset(CG.Segment, CG.Offset), CG.Characteristics);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
BPRelativeSym &BPRel) {
P.format(" `{0}`", BPRel.Name);
AutoIndent Indent(P);
P.formatLine("type = {0}, offset = {1}", typeIndex(BPRel.Type), BPRel.Offset);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
BuildInfoSym &BuildInfo) {
P.format(" BuildId = `{0}`", BuildInfo.BuildId);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
CallSiteInfoSym &CSI) {
AutoIndent Indent(P);
P.formatLine("type = {0}, addr = {1}", typeIndex(CSI.Type),
formatSegmentOffset(CSI.Segment, CSI.CodeOffset));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
EnvBlockSym &EnvBlock) {
for (const auto &Entry : EnvBlock.Fields) {
P.formatLine("- {0}", Entry);
}
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FileStaticSym &FS) {
P.format(" `{0}`", FS.Name);
AutoIndent Indent(P);
P.formatLine("type = {0}, file name offset = {1}, flags = {2}",
typeIndex(FS.Index), FS.ModFilenameOffset,
formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
P.format(" `{0}`", Export.Name);
AutoIndent Indent(P);
P.formatLine("ordinal = {0}, flags = {1}", Export.Ordinal,
formatExportFlags(P.getIndentLevel() + 9, Export.Flags));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
Compile2Sym &Compile2) {
AutoIndent Indent(P);
SourceLanguage Lang = static_cast<SourceLanguage>(
Compile2.Flags & CompileSym2Flags::SourceLanguageMask);
P.formatLine("machine = {0}, ver = {1}, language = {2}",
formatMachineType(Compile2.Machine), Compile2.Version,
formatSourceLanguage(Lang));
P.formatLine("frontend = {0}.{1}.{2}, backend = {3}.{4}.{5}",
Compile2.VersionFrontendMajor, Compile2.VersionFrontendMinor,
Compile2.VersionFrontendBuild, Compile2.VersionBackendMajor,
Compile2.VersionBackendMinor, Compile2.VersionBackendBuild);
P.formatLine("flags = {0}",
formatCompileSym2Flags(P.getIndentLevel() + 9, Compile2.Flags));
P.formatLine(
"extra strings = {0}",
typesetStringList(P.getIndentLevel() + 9 + 2, Compile2.ExtraStrings));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
Compile3Sym &Compile3) {
AutoIndent Indent(P);
SourceLanguage Lang = static_cast<SourceLanguage>(
Compile3.Flags & CompileSym3Flags::SourceLanguageMask);
P.formatLine("machine = {0}, Ver = {1}, language = {2}",
formatMachineType(Compile3.Machine), Compile3.Version,
formatSourceLanguage(Lang));
P.formatLine("frontend = {0}.{1}.{2}.{3}, backend = {4}.{5}.{6}.{7}",
Compile3.VersionFrontendMajor, Compile3.VersionFrontendMinor,
Compile3.VersionFrontendBuild, Compile3.VersionFrontendQFE,
Compile3.VersionBackendMajor, Compile3.VersionBackendMinor,
Compile3.VersionBackendBuild, Compile3.VersionBackendQFE);
P.formatLine("flags = {0}",
formatCompileSym3Flags(P.getIndentLevel() + 9, Compile3.Flags));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
ConstantSym &Constant) {
P.format(" `{0}`", Constant.Name);
AutoIndent Indent(P);
P.formatLine("type = {0}, value = {1}", typeIndex(Constant.Type),
Constant.Value.toString(10));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
P.format(" `{0}`", Data.Name);
AutoIndent Indent(P);
P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type),
formatSegmentOffset(Data.Segment, Data.DataOffset));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(
CVSymbol &CVR, DefRangeFramePointerRelFullScopeSym &Def) {
P.format(" offset = {0}", Def.Offset);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
DefRangeFramePointerRelSym &Def) {
AutoIndent Indent(P);
P.formatLine("offset = {0}, range = {1}", Def.Offset, formatRange(Def.Range));
P.formatLine("gaps = {2}", Def.Offset,
formatGaps(P.getIndentLevel() + 9, Def.Gaps));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
DefRangeRegisterRelSym &Def) {
AutoIndent Indent(P);
P.formatLine("register = {0}, base ptr = {1}, offset in parent = {2}, has "
"spilled udt = {3}",
uint16_t(Def.Hdr.Register), int32_t(Def.Hdr.BasePointerOffset),
Def.offsetInParent(), Def.hasSpilledUDTMember());
P.formatLine("range = {0}, gaps = {1}", formatRange(Def.Range),
formatGaps(P.getIndentLevel() + 9, Def.Gaps));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(
CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
AutoIndent Indent(P);
P.formatLine("register = {0}, may have no name = {1}, range start = "
"{2}, length = {3}",
uint16_t(DefRangeRegister.Hdr.Register),
uint16_t(DefRangeRegister.Hdr.MayHaveNoName),
formatSegmentOffset(DefRangeRegister.Range.ISectStart,
DefRangeRegister.Range.OffsetStart),
DefRangeRegister.Range.Range);
P.formatLine("gaps = [{0}]",
formatGaps(P.getIndentLevel() + 9, DefRangeRegister.Gaps));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
DefRangeSubfieldRegisterSym &Def) {
AutoIndent Indent(P);
bool NoName = !!(Def.Hdr.MayHaveNoName == 0);
P.formatLine("register = {0}, may have no name = {1}, offset in parent = {2}",
uint16_t(Def.Hdr.Register), NoName,
uint32_t(Def.Hdr.OffsetInParent));
P.formatLine("range = {0}, gaps = {1}", formatRange(Def.Range),
formatGaps(P.getIndentLevel() + 9, Def.Gaps));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
DefRangeSubfieldSym &Def) {
AutoIndent Indent(P);
P.formatLine("program = {0}, offset in parent = {1}, range = {2}",
Def.Program, Def.OffsetInParent, formatRange(Def.Range));
P.formatLine("gaps = {0}", formatGaps(P.getIndentLevel() + 9, Def.Gaps));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DefRangeSym &Def) {
AutoIndent Indent(P);
P.formatLine("program = {0}, range = {1}", Def.Program,
formatRange(Def.Range));
P.formatLine("gaps = {0}", formatGaps(P.getIndentLevel() + 9, Def.Gaps));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameCookieSym &FC) {
AutoIndent Indent(P);
P.formatLine("code offset = {0}, Register = {1}, kind = {2}, flags = {3}",
FC.CodeOffset, FC.Register, formatCookieKind(FC.CookieKind),
FC.Flags);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameProcSym &FP) {
AutoIndent Indent(P);
P.formatLine("size = {0}, padding size = {1}, offset to padding = {2}",
FP.TotalFrameBytes, FP.PaddingFrameBytes, FP.OffsetToPadding);
P.formatLine("bytes of callee saved registers = {0}, exception handler addr "
"= {1}",
FP.BytesOfCalleeSavedRegisters,
formatSegmentOffset(FP.SectionIdOfExceptionHandler,
FP.OffsetOfExceptionHandler));
P.formatLine("flags = {0}",
formatFrameProcedureOptions(P.getIndentLevel() + 9, FP.Flags));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
HeapAllocationSiteSym &HAS) {
AutoIndent Indent(P);
P.formatLine("type = {0}, addr = {1} call size = {2}", typeIndex(HAS.Type),
formatSegmentOffset(HAS.Segment, HAS.CodeOffset),
HAS.CallInstructionSize);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, InlineSiteSym &IS) {
AutoIndent Indent(P);
auto Bytes = makeArrayRef(IS.AnnotationData);
StringRef Annotations(reinterpret_cast<const char *>(Bytes.begin()),
Bytes.size());
P.formatLine("inlinee = {0}, parent = {1}, end = {2}", typeIndex(IS.Inlinee),
IS.Parent, IS.End);
P.formatLine("annotations = {0}", toHex(Annotations));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
RegisterSym &Register) {
P.format(" `{0}`", Register.Name);
AutoIndent Indent(P);
P.formatLine("register = {0}, type = {1}",
formatRegisterId(Register.Register), typeIndex(Register.Index));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
PublicSym32 &Public) {
P.format(" `{0}`", Public.Name);
AutoIndent Indent(P);
P.formatLine("type = {0}, addr = {1}", typeIndex(Public.Index),
formatSegmentOffset(Public.Segment, Public.Offset));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcRefSym &PR) {
P.format(" `{0}`", PR.Name);
AutoIndent Indent(P);
P.formatLine("module = {0}, sum name = {1}, offset = {2}", PR.Module,
PR.SumName, PR.SymOffset);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
P.format(" `{0}` (addr = {1})", Label.Name,
formatSegmentOffset(Label.Segment, Label.CodeOffset));
AutoIndent Indent(P);
P.formatLine("flags = {0}",
formatProcSymFlags(P.getIndentLevel() + 9, Label.Flags));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
P.format(" `{0}`", Local.Name);
AutoIndent Indent(P);
std::string FlagStr =
formatLocalSymFlags(P.getIndentLevel() + 9, Local.Flags);
P.formatLine("type={0}, flags = {1}", typeIndex(Local.Type), FlagStr);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
ObjNameSym &ObjName) {
P.format(" sig={0}, `{1}`", ObjName.Signature, ObjName.Name);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
P.format(" `{0}`", Proc.Name);
AutoIndent Indent(P);
P.formatLine("parent = {0}, addr = {1}, code size = {2}, end = {3}",
Proc.Parent, formatSegmentOffset(Proc.Segment, Proc.CodeOffset),
Proc.CodeSize, Proc.End);
P.formatLine("debug start = {0}, debug end = {1}, flags = {2}", Proc.DbgStart,
Proc.DbgEnd,
formatProcSymFlags(P.getIndentLevel() + 9, Proc.Flags));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
ScopeEndSym &ScopeEnd) {
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
AutoIndent Indent(P);
for (const auto &I : Caller.Indices) {
P.formatLine("callee: {0}", typeIndex(I));
}
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
RegRelativeSym &RegRel) {
P.format(" `{0}`", RegRel.Name);
AutoIndent Indent(P);
P.formatLine("type = {0}, register = {1}, offset = {2}",
typeIndex(RegRel.Type), formatRegisterId(RegRel.Register),
RegRel.Offset);
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
ThreadLocalDataSym &Data) {
P.format(" `{0}`", Data.Name);
AutoIndent Indent(P);
P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type),
formatSegmentOffset(Data.Segment, Data.DataOffset));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
P.format(" `{0}`", UDT.Name);
AutoIndent Indent(P);
P.formatLine("original type = {0}", UDT.Type);
return Error::success();
}

View File

@ -1,47 +0,0 @@
//===- MinimalSymbolDumper.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_TOOLS_LLVMPDBUTIL_MINIMAL_SYMBOL_DUMPER_H
#define LLVM_TOOLS_LLVMPDBUTIL_MINIMAL_SYMBOL_DUMPER_H
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
namespace llvm {
namespace codeview {
class LazyRandomTypeCollection;
}
namespace pdb {
class LinePrinter;
class MinimalSymbolDumper : public codeview::SymbolVisitorCallbacks {
public:
MinimalSymbolDumper(LinePrinter &P, bool RecordBytes,
codeview::LazyRandomTypeCollection &Types)
: P(P), Types(Types) {}
Error visitSymbolBegin(codeview::CVSymbol &Record) override;
Error visitSymbolEnd(codeview::CVSymbol &Record) override;
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
virtual Error visitKnownRecord(codeview::CVSymbol &CVR, \
codeview::Name &Record) override;
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
private:
std::string typeIndex(codeview::TypeIndex TI) const;
LinePrinter &P;
codeview::LazyRandomTypeCollection &Types;
};
} // namespace pdb
} // namespace llvm
#endif

View File

@ -1,532 +0,0 @@
//===- MinimalTypeDumper.cpp ---------------------------------- *- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MinimalTypeDumper.h"
#include "FormatUtil.h"
#include "LinePrinter.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::pdb;
static StringRef getLeafTypeName(TypeLeafKind K) {
switch (K) {
#define TYPE_RECORD(EnumName, value, name) \
case EnumName: \
return #EnumName;
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
default:
llvm_unreachable("Unknown type leaf kind!");
}
return "";
}
static std::string formatClassOptions(uint32_t IndentLevel,
ClassOptions Options) {
std::vector<std::string> Opts;
PUSH_FLAG(ClassOptions, HasConstructorOrDestructor, Options,
"has ctor / dtor");
PUSH_FLAG(ClassOptions, ContainsNestedClass, Options,
"contains nested class");
PUSH_FLAG(ClassOptions, HasConversionOperator, Options,
"conversion operator");
PUSH_FLAG(ClassOptions, ForwardReference, Options, "forward ref");
PUSH_FLAG(ClassOptions, HasUniqueName, Options, "has unique name");
PUSH_FLAG(ClassOptions, Intrinsic, Options, "intrin");
PUSH_FLAG(ClassOptions, Nested, Options, "is nested");
PUSH_FLAG(ClassOptions, HasOverloadedOperator, Options,
"overloaded operator");
PUSH_FLAG(ClassOptions, HasOverloadedAssignmentOperator, Options,
"overloaded operator=");
PUSH_FLAG(ClassOptions, Packed, Options, "packed");
PUSH_FLAG(ClassOptions, Scoped, Options, "scoped");
PUSH_FLAG(ClassOptions, Sealed, Options, "sealed");
return typesetItemList(Opts, 4, IndentLevel, " | ");
}
static std::string pointerOptions(PointerOptions Options) {
std::vector<std::string> Opts;
PUSH_FLAG(PointerOptions, Flat32, Options, "flat32");
PUSH_FLAG(PointerOptions, Volatile, Options, "volatile");
PUSH_FLAG(PointerOptions, Const, Options, "const");
PUSH_FLAG(PointerOptions, Unaligned, Options, "unaligned");
PUSH_FLAG(PointerOptions, Restrict, Options, "restrict");
PUSH_FLAG(PointerOptions, WinRTSmartPointer, Options, "winrt");
if (Opts.empty())
return "None";
return join(Opts, " | ");
}
static std::string modifierOptions(ModifierOptions Options) {
std::vector<std::string> Opts;
PUSH_FLAG(ModifierOptions, Const, Options, "const");
PUSH_FLAG(ModifierOptions, Volatile, Options, "volatile");
PUSH_FLAG(ModifierOptions, Unaligned, Options, "unaligned");
if (Opts.empty())
return "None";
return join(Opts, " | ");
}
static std::string formatCallingConvention(CallingConvention Convention) {
switch (Convention) {
RETURN_CASE(CallingConvention, AlphaCall, "alphacall");
RETURN_CASE(CallingConvention, AM33Call, "am33call");
RETURN_CASE(CallingConvention, ArmCall, "armcall");
RETURN_CASE(CallingConvention, ClrCall, "clrcall");
RETURN_CASE(CallingConvention, FarC, "far cdecl");
RETURN_CASE(CallingConvention, FarFast, "far fastcall");
RETURN_CASE(CallingConvention, FarPascal, "far pascal");
RETURN_CASE(CallingConvention, FarStdCall, "far stdcall");
RETURN_CASE(CallingConvention, FarSysCall, "far syscall");
RETURN_CASE(CallingConvention, Generic, "generic");
RETURN_CASE(CallingConvention, Inline, "inline");
RETURN_CASE(CallingConvention, M32RCall, "m32rcall");
RETURN_CASE(CallingConvention, MipsCall, "mipscall");
RETURN_CASE(CallingConvention, NearC, "cdecl");
RETURN_CASE(CallingConvention, NearFast, "fastcall");
RETURN_CASE(CallingConvention, NearPascal, "pascal");
RETURN_CASE(CallingConvention, NearStdCall, "stdcall");
RETURN_CASE(CallingConvention, NearSysCall, "near syscall");
RETURN_CASE(CallingConvention, NearVector, "vectorcall");
RETURN_CASE(CallingConvention, PpcCall, "ppccall");
RETURN_CASE(CallingConvention, SHCall, "shcall");
RETURN_CASE(CallingConvention, SH5Call, "sh5call");
RETURN_CASE(CallingConvention, ThisCall, "thiscall");
RETURN_CASE(CallingConvention, TriCall, "tricall");
}
return formatUnknownEnum(Convention);
}
static std::string formatPointerMode(PointerMode Mode) {
switch (Mode) {
RETURN_CASE(PointerMode, LValueReference, "ref");
RETURN_CASE(PointerMode, Pointer, "pointer");
RETURN_CASE(PointerMode, PointerToDataMember, "data member pointer");
RETURN_CASE(PointerMode, PointerToMemberFunction, "member fn pointer");
RETURN_CASE(PointerMode, RValueReference, "rvalue ref");
}
return formatUnknownEnum(Mode);
}
static std::string memberAccess(MemberAccess Access) {
switch (Access) {
RETURN_CASE(MemberAccess, None, "");
RETURN_CASE(MemberAccess, Private, "private");
RETURN_CASE(MemberAccess, Protected, "protected");
RETURN_CASE(MemberAccess, Public, "public");
}
return formatUnknownEnum(Access);
}
static std::string methodKind(MethodKind Kind) {
switch (Kind) {
RETURN_CASE(MethodKind, Vanilla, "");
RETURN_CASE(MethodKind, Virtual, "virtual");
RETURN_CASE(MethodKind, Static, "static");
RETURN_CASE(MethodKind, Friend, "friend");
RETURN_CASE(MethodKind, IntroducingVirtual, "intro virtual");
RETURN_CASE(MethodKind, PureVirtual, "pure virtual");
RETURN_CASE(MethodKind, PureIntroducingVirtual, "pure intro virtual");
}
return formatUnknownEnum(Kind);
}
static std::string pointerKind(PointerKind Kind) {
switch (Kind) {
RETURN_CASE(PointerKind, Near16, "ptr16");
RETURN_CASE(PointerKind, Far16, "far ptr16");
RETURN_CASE(PointerKind, Huge16, "huge ptr16");
RETURN_CASE(PointerKind, BasedOnSegment, "segment based");
RETURN_CASE(PointerKind, BasedOnValue, "value based");
RETURN_CASE(PointerKind, BasedOnSegmentValue, "segment value based");
RETURN_CASE(PointerKind, BasedOnAddress, "address based");
RETURN_CASE(PointerKind, BasedOnSegmentAddress, "segment address based");
RETURN_CASE(PointerKind, BasedOnType, "type based");
RETURN_CASE(PointerKind, BasedOnSelf, "self based");
RETURN_CASE(PointerKind, Near32, "ptr32");
RETURN_CASE(PointerKind, Far32, "far ptr32");
RETURN_CASE(PointerKind, Near64, "ptr64");
}
return formatUnknownEnum(Kind);
}
static std::string memberAttributes(const MemberAttributes &Attrs) {
std::vector<std::string> Opts;
std::string Access = memberAccess(Attrs.getAccess());
std::string Kind = methodKind(Attrs.getMethodKind());
if (!Access.empty())
Opts.push_back(Access);
if (!Kind.empty())
Opts.push_back(Kind);
MethodOptions Flags = Attrs.getFlags();
PUSH_FLAG(MethodOptions, Pseudo, Flags, "pseudo");
PUSH_FLAG(MethodOptions, NoInherit, Flags, "noinherit");
PUSH_FLAG(MethodOptions, NoConstruct, Flags, "noconstruct");
PUSH_FLAG(MethodOptions, CompilerGenerated, Flags, "compiler-generated");
PUSH_FLAG(MethodOptions, Sealed, Flags, "sealed");
return join(Opts, " ");
}
static std::string formatPointerAttrs(const PointerRecord &Record) {
PointerMode Mode = Record.getMode();
PointerOptions Opts = Record.getOptions();
PointerKind Kind = Record.getPointerKind();
return formatv("mode = {0}, opts = {1}, kind = {2}", formatPointerMode(Mode),
pointerOptions(Opts), pointerKind(Kind));
}
static std::string formatFunctionOptions(FunctionOptions Options) {
std::vector<std::string> Opts;
PUSH_FLAG(FunctionOptions, CxxReturnUdt, Options, "returns cxx udt");
PUSH_FLAG(FunctionOptions, ConstructorWithVirtualBases, Options,
"constructor with virtual bases");
PUSH_FLAG(FunctionOptions, Constructor, Options, "constructor");
if (Opts.empty())
return "None";
return join(Opts, " | ");
}
Error MinimalTypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
// formatLine puts the newline at the beginning, so we use formatLine here
// to start a new line, and then individual visit methods use format to
// append to the existing line.
P.formatLine("{0} | {1} [size = {2}]",
fmt_align(Index, AlignStyle::Right, Width),
getLeafTypeName(Record.Type), Record.length());
P.Indent(Width + 3);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitTypeEnd(CVType &Record) {
P.Unindent(Width + 3);
if (RecordBytes) {
AutoIndent Indent(P, 9);
P.formatBinary("Bytes", Record.RecordData, 0);
}
return Error::success();
}
Error MinimalTypeDumpVisitor::visitMemberBegin(CVMemberRecord &Record) {
P.formatLine("- {0}", getLeafTypeName(Record.Kind));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitMemberEnd(CVMemberRecord &Record) {
if (RecordBytes) {
AutoIndent Indent(P, 2);
P.formatBinary("Bytes", Record.Data, 0);
}
return Error::success();
}
StringRef MinimalTypeDumpVisitor::getTypeName(TypeIndex TI) const {
if (TI.isNoneType())
return "";
return Types.getTypeName(TI);
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
FieldListRecord &FieldList) {
if (auto EC = codeview::visitMemberRecordStream(FieldList.Data, *this))
return EC;
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
StringIdRecord &String) {
P.format(" ID: {0}, String: {1}", String.getId(), String.getString());
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
ArgListRecord &Args) {
auto Indices = Args.getIndices();
if (Indices.empty())
return Error::success();
auto Max = std::max_element(Indices.begin(), Indices.end());
uint32_t W = NumDigits(Max->getIndex()) + 2;
for (auto I : Indices)
P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
getTypeName(I));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
StringListRecord &Strings) {
auto Indices = Strings.getIndices();
if (Indices.empty())
return Error::success();
auto Max = std::max_element(Indices.begin(), Indices.end());
uint32_t W = NumDigits(Max->getIndex()) + 2;
for (auto I : Indices)
P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
getTypeName(I));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
ClassRecord &Class) {
P.formatLine("class name: `{0}`", Class.Name);
if (Class.hasUniqueName())
P.formatLine("unique name: `{0}`", Class.UniqueName);
P.formatLine("vtable: {0}, base list: {1}, field list: {2}",
Class.VTableShape, Class.DerivationList, Class.FieldList);
P.formatLine("options: {0}",
formatClassOptions(P.getIndentLevel(), Class.Options));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
UnionRecord &Union) {
P.formatLine("class name: `{0}`", Union.Name);
if (Union.hasUniqueName())
P.formatLine("unique name: `{0}`", Union.UniqueName);
P.formatLine("field list: {0}", Union.FieldList);
P.formatLine("options: {0}",
formatClassOptions(P.getIndentLevel(), Union.Options));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
P.formatLine("name: `{0}`", Enum.Name);
if (Enum.hasUniqueName())
P.formatLine("unique name: `{0}`", Enum.UniqueName);
P.formatLine("field list: {0}, underlying type: {1}", Enum.FieldList,
Enum.UnderlyingType);
P.formatLine("options: {0}",
formatClassOptions(P.getIndentLevel(), Enum.Options));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
if (AT.Name.empty()) {
P.formatLine("size: {0}, index type: {1}, element type: {2}", AT.Size,
AT.IndexType, AT.ElementType);
} else {
P.formatLine("name: {0}, size: {1}, index type: {2}, element type: {3}",
AT.Name, AT.Size, AT.IndexType, AT.ElementType);
}
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
VFTableRecord &VFT) {
P.formatLine("offset: {0}, complete class: {1}, overridden vftable: {2}",
VFT.VFPtrOffset, VFT.CompleteClass, VFT.OverriddenVFTable);
P.formatLine("method names: ");
if (!VFT.MethodNames.empty()) {
std::string Sep =
formatv("\n{0}",
fmt_repeat(' ', P.getIndentLevel() + strlen("method names: ")))
.str();
P.print(join(VFT.MethodNames, Sep));
}
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
MemberFuncIdRecord &Id) {
P.formatLine("name = {0}, type = {1}, class type = {2}", Id.Name,
Id.FunctionType, Id.ClassType);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
ProcedureRecord &Proc) {
P.formatLine("return type = {0}, # args = {1}, param list = {2}",
Proc.ReturnType, Proc.ParameterCount, Proc.ArgumentList);
P.formatLine("calling conv = {0}, options = {1}",
formatCallingConvention(Proc.CallConv),
formatFunctionOptions(Proc.Options));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
MemberFunctionRecord &MF) {
P.formatLine("return type = {0}, # args = {1}, param list = {2}",
MF.ParameterCount, MF.ArgumentList, MF.ReturnType);
P.formatLine("class type = {0}, this type = {1}, this adjust = {2}",
MF.ClassType, MF.ThisType, MF.ThisPointerAdjustment);
P.formatLine("calling conv = {0}, options = {1}",
formatCallingConvention(MF.CallConv),
formatFunctionOptions(MF.Options));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
FuncIdRecord &Func) {
P.formatLine("name = {0}, type = {1}, parent scope = {2}", Func.Name,
Func.FunctionType, Func.ParentScope);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
TypeServer2Record &TS) {
P.formatLine("name = {0}, age = {1}, guid = {2}", TS.Name, TS.Age,
fmt_guid(TS.Guid));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
PointerRecord &Ptr) {
P.formatLine("referent = {0}, {1}", Ptr.ReferentType,
formatPointerAttrs(Ptr));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
ModifierRecord &Mod) {
P.formatLine("referent = {0}, modifiers = {1}", Mod.ModifiedType,
modifierOptions(Mod.Modifiers));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
VFTableShapeRecord &Shape) {
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
UdtModSourceLineRecord &U) {
P.formatLine("udt = {0}, mod = {1}, file = {2}, line = {3}", U.UDT, U.Module,
U.SourceFile.getIndex(), U.LineNumber);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
UdtSourceLineRecord &U) {
P.formatLine("udt = {0}, file = {1}, line = {2}", U.UDT,
U.SourceFile.getIndex(), U.LineNumber);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
BitFieldRecord &BF) {
P.formatLine("type = {0}, bit offset = {1}, # bits = {2}", BF.Type,
BF.BitOffset, BF.BitSize);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(
CVType &CVR, MethodOverloadListRecord &Overloads) {
for (auto &M : Overloads.Methods)
P.formatLine("- Method [type = {0}, vftable offset = {1}, attrs = {2}]",
M.Type, M.VFTableOffset, memberAttributes(M.Attrs));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
BuildInfoRecord &BI) {
auto Indices = BI.ArgIndices;
if (Indices.empty())
return Error::success();
auto Max = std::max_element(Indices.begin(), Indices.end());
uint32_t W = NumDigits(Max->getIndex()) + 2;
for (auto I : Indices)
P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
getTypeName(I));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &R) {
std::string Type = (R.Mode == LabelType::Far) ? "far" : "near";
P.format(" type = {0}", Type);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
NestedTypeRecord &Nested) {
P.format(" [name = `{0}`, parent = {1}]", Nested.Name, Nested.Type);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
OneMethodRecord &Method) {
P.format(" [name = `{0}`]", Method.Name);
AutoIndent Indent(P);
P.formatLine("type = {0}, vftable offset = {1}, attrs = {2}", Method.Type,
Method.VFTableOffset, memberAttributes(Method.Attrs));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
OverloadedMethodRecord &Method) {
P.format(" [name = `{0}`, # overloads = {1}, overload list = {2}]",
Method.Name, Method.NumOverloads, Method.MethodList);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
DataMemberRecord &Field) {
P.format(" [name = `{0}`, Type = {1}, offset = {2}, attrs = {3}]", Field.Name,
Field.Type, Field.FieldOffset, memberAttributes(Field.Attrs));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
StaticDataMemberRecord &Field) {
P.format(" [name = `{0}`, type = {1}, attrs = {2}]", Field.Name, Field.Type,
memberAttributes(Field.Attrs));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
EnumeratorRecord &Enum) {
P.format(" [{0} = {1}]", Enum.Name,
Enum.Value.toString(10, Enum.Value.isSigned()));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
BaseClassRecord &Base) {
AutoIndent Indent(P);
P.formatLine("type = {0}, offset = {1}, attrs = {2}", Base.Type, Base.Offset,
memberAttributes(Base.Attrs));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
VirtualBaseClassRecord &Base) {
AutoIndent Indent(P);
P.formatLine(
"base = {0}, vbptr = {1}, vbptr offset = {2}, vtable index = {3}",
Base.BaseType, Base.VBPtrType, Base.VBPtrOffset, Base.VTableIndex);
P.formatLine("attrs = {0}", memberAttributes(Base.Attrs));
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
ListContinuationRecord &Cont) {
P.format(" continuation = {0}", Cont.ContinuationIndex);
return Error::success();
}
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
VFPtrRecord &VFP) {
P.format(" type = {0}", VFP.Type);
return Error::success();
}

View File

@ -1,56 +0,0 @@
//===- MinimalTypeDumper.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_TOOLS_LLVMPDBUTIL_MINIMAL_TYPE_DUMPER_H
#define LLVM_TOOLS_LLVMPDBUTIL_MINIMAL_TYPE_DUMPER_H
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
namespace llvm {
namespace codeview {
class LazyRandomTypeCollection;
}
namespace pdb {
class LinePrinter;
class MinimalTypeDumpVisitor : public codeview::TypeVisitorCallbacks {
public:
MinimalTypeDumpVisitor(LinePrinter &P, uint32_t Width, bool RecordBytes,
codeview::LazyRandomTypeCollection &Types)
: P(P), Width(Width), RecordBytes(RecordBytes), Types(Types) {}
Error visitTypeBegin(codeview::CVType &Record,
codeview::TypeIndex Index) override;
Error visitTypeEnd(codeview::CVType &Record) override;
Error visitMemberBegin(codeview::CVMemberRecord &Record) override;
Error visitMemberEnd(codeview::CVMemberRecord &Record) override;
#define TYPE_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(codeview::CVType &CVR, \
codeview::Name##Record &Record) override;
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
Error visitKnownMember(codeview::CVMemberRecord &CVR, \
codeview::Name##Record &Record) override;
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
StringRef getTypeName(codeview::TypeIndex TI) const;
LinePrinter &P;
uint32_t Width;
bool RecordBytes = false;
codeview::LazyRandomTypeCollection &Types;
};
} // namespace pdb
} // namespace llvm
#endif

View File

@ -1,668 +0,0 @@
//===- RawOutputStyle.cpp ------------------------------------ *- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "RawOutputStyle.h"
#include "CompactTypeDumpVisitor.h"
#include "FormatUtil.h"
#include "MinimalSymbolDumper.h"
#include "MinimalTypeDumper.h"
#include "StreamUtil.h"
#include "llvm-pdbutil.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.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/DebugSubsectionVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/EnumTables.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
#include <unordered_map>
using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
RawOutputStyle::RawOutputStyle(PDBFile &File)
: File(File), P(2, false, outs()) {}
Error RawOutputStyle::dump() {
if (opts::raw::DumpSummary) {
if (auto EC = dumpFileSummary())
return EC;
P.NewLine();
}
if (opts::raw::DumpStreams) {
if (auto EC = dumpStreamSummary())
return EC;
P.NewLine();
}
if (opts::raw::DumpBlockRange.hasValue()) {
if (auto EC = dumpBlockRanges())
return EC;
P.NewLine();
}
if (!opts::raw::DumpStreamData.empty()) {
if (auto EC = dumpStreamBytes())
return EC;
P.NewLine();
}
if (opts::raw::DumpStringTable) {
if (auto EC = dumpStringTable())
return EC;
P.NewLine();
}
if (opts::raw::DumpModules) {
if (auto EC = dumpModules())
return EC;
}
if (opts::raw::DumpTypes) {
if (auto EC = dumpTpiStream(StreamTPI))
return EC;
}
if (opts::raw::DumpIds) {
if (auto EC = dumpTpiStream(StreamIPI))
return EC;
}
if (opts::raw::DumpPublics) {
if (auto EC = dumpPublics())
return EC;
}
if (opts::raw::DumpSymbols) {
if (auto EC = dumpModuleSyms())
return EC;
}
if (opts::raw::DumpSectionContribs) {
if (auto EC = dumpSectionContribs())
return EC;
}
if (opts::raw::DumpSectionMap) {
if (auto EC = dumpSectionMap())
return EC;
}
return Error::success();
}
static void printHeader(LinePrinter &P, const Twine &S) {
P.NewLine();
P.formatLine("{0,=60}", S);
P.formatLine("{0}", fmt_repeat('=', 60));
}
Error RawOutputStyle::dumpFileSummary() {
printHeader(P, "Summary");
ExitOnError Err("Invalid PDB Format");
AutoIndent Indent(P);
P.formatLine("Block Size: {0}", File.getBlockSize());
P.formatLine("Number of blocks: {0}", File.getBlockCount());
P.formatLine("Number of streams: {0}", File.getNumStreams());
auto &PS = Err(File.getPDBInfoStream());
P.formatLine("Signature: {0}", PS.getSignature());
P.formatLine("Age: {0}", PS.getAge());
P.formatLine("GUID: {0}", fmt_guid(PS.getGuid().Guid));
P.formatLine("Features: {0:x+}", static_cast<uint32_t>(PS.getFeatures()));
P.formatLine("Has Debug Info: {0}", File.hasPDBDbiStream());
P.formatLine("Has Types: {0}", File.hasPDBTpiStream());
P.formatLine("Has IDs: {0}", File.hasPDBIpiStream());
P.formatLine("Has Globals: {0}", File.hasPDBGlobalsStream());
P.formatLine("Has Publics: {0}", File.hasPDBPublicsStream());
if (File.hasPDBDbiStream()) {
auto &DBI = Err(File.getPDBDbiStream());
P.formatLine("Is incrementally linked: {0}", DBI.isIncrementallyLinked());
P.formatLine("Has conflicting types: {0}", DBI.hasCTypes());
P.formatLine("Is stripped: {0}", DBI.isStripped());
}
return Error::success();
}
Error RawOutputStyle::dumpStreamSummary() {
printHeader(P, "Streams");
if (StreamPurposes.empty())
discoverStreamPurposes(File, StreamPurposes);
AutoIndent Indent(P);
uint32_t StreamCount = File.getNumStreams();
for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
P.formatLine(
"Stream {0}: [{1}] ({2} bytes)",
fmt_align(StreamIdx, AlignStyle::Right, NumDigits(StreamCount)),
StreamPurposes[StreamIdx], File.getStreamByteSize(StreamIdx));
}
return Error::success();
}
Error RawOutputStyle::dumpBlockRanges() {
printHeader(P, "MSF Blocks");
auto &R = *opts::raw::DumpBlockRange;
uint32_t Max = R.Max.getValueOr(R.Min);
AutoIndent Indent(P);
if (Max < R.Min)
return make_error<StringError>(
"Invalid block range specified. Max < Min",
std::make_error_code(std::errc::bad_address));
if (Max >= File.getBlockCount())
return make_error<StringError>(
"Invalid block range specified. Requested block out of bounds",
std::make_error_code(std::errc::bad_address));
for (uint32_t I = R.Min; I <= Max; ++I) {
auto ExpectedData = File.getBlockData(I, File.getBlockSize());
if (!ExpectedData)
return ExpectedData.takeError();
std::string Label = formatv("Block {0}", I).str();
P.formatBinary(Label, *ExpectedData, 0);
}
return Error::success();
}
static Error parseStreamSpec(StringRef Str, uint32_t &SI, uint32_t &Offset,
uint32_t &Size) {
if (Str.consumeInteger(0, SI))
return make_error<RawError>(raw_error_code::invalid_format,
"Invalid Stream Specification");
if (Str.consume_front(":")) {
if (Str.consumeInteger(0, Offset))
return make_error<RawError>(raw_error_code::invalid_format,
"Invalid Stream Specification");
}
if (Str.consume_front("@")) {
if (Str.consumeInteger(0, Size))
return make_error<RawError>(raw_error_code::invalid_format,
"Invalid Stream Specification");
}
if (!Str.empty())
return make_error<RawError>(raw_error_code::invalid_format,
"Invalid Stream Specification");
return Error::success();
}
Error RawOutputStyle::dumpStreamBytes() {
if (StreamPurposes.empty())
discoverStreamPurposes(File, StreamPurposes);
printHeader(P, "Stream Data");
ExitOnError Err("Unexpected error reading stream data");
for (auto &Str : opts::raw::DumpStreamData) {
uint32_t SI = 0;
uint32_t Begin = 0;
uint32_t Size = 0;
uint32_t End = 0;
if (auto EC = parseStreamSpec(Str, SI, Begin, Size))
return EC;
AutoIndent Indent(P);
if (SI >= File.getNumStreams()) {
P.formatLine("Stream {0}: Not present", SI);
continue;
}
auto S = MappedBlockStream::createIndexedStream(
File.getMsfLayout(), File.getMsfBuffer(), SI, File.getAllocator());
if (!S) {
P.NewLine();
P.formatLine("Stream {0}: Not present", SI);
continue;
}
if (Size == 0)
End = S->getLength();
else
End = std::min(Begin + Size, S->getLength());
P.formatLine("Stream {0} ({1:N} bytes): {2}", SI, S->getLength(),
StreamPurposes[SI]);
AutoIndent Indent2(P);
BinaryStreamReader R(*S);
ArrayRef<uint8_t> StreamData;
Err(R.readBytes(StreamData, S->getLength()));
Size = End - Begin;
StreamData = StreamData.slice(Begin, Size);
P.formatBinary("Data", StreamData, Begin);
}
return Error::success();
}
Error RawOutputStyle::dumpModules() {
printHeader(P, "Modules");
AutoIndent Indent(P);
if (!File.hasPDBDbiStream()) {
P.formatLine("DBI Stream not present");
return Error::success();
}
ExitOnError Err("Unexpected error processing symbols");
auto &Stream = Err(File.getPDBDbiStream());
const DbiModuleList &Modules = Stream.modules();
uint32_t Count = Modules.getModuleCount();
uint32_t Digits = NumDigits(Count);
for (uint32_t I = 0; I < Count; ++I) {
auto Modi = Modules.getModuleDescriptor(I);
P.formatLine("Mod {0:4} | Name: `{1}`: ",
fmt_align(I, AlignStyle::Right, Digits), Modi.getModuleName());
P.formatLine(" Obj: `{0}`: ", Modi.getObjFileName());
P.formatLine(" debug stream: {0}, # files: {1}, has ec info: {2}",
Modi.getModuleStreamIndex(), Modi.getNumberOfFiles(),
Modi.hasECInfo());
if (opts::raw::DumpModuleFiles) {
P.formatLine(" contributing source files:");
for (const auto &F : Modules.source_files(I)) {
P.formatLine(" - {0}", F);
}
}
}
return Error::success();
}
Error RawOutputStyle::dumpStringTable() {
printHeader(P, "String Table");
AutoIndent Indent(P);
auto IS = File.getStringTable();
if (!IS) {
P.formatLine("Not present in file");
consumeError(IS.takeError());
return Error::success();
}
if (IS->name_ids().empty()) {
P.formatLine("Empty");
return Error::success();
}
auto MaxID = std::max_element(IS->name_ids().begin(), IS->name_ids().end());
uint32_t Digits = NumDigits(*MaxID);
P.formatLine("{0} | {1}", fmt_align("ID", AlignStyle::Right, Digits),
"String");
std::vector<uint32_t> SortedIDs(IS->name_ids().begin(), IS->name_ids().end());
std::sort(SortedIDs.begin(), SortedIDs.end());
for (uint32_t I : SortedIDs) {
auto ES = IS->getStringForID(I);
llvm::SmallString<32> Str;
if (!ES) {
consumeError(ES.takeError());
Str = "Error reading string";
} else if (!ES->empty()) {
Str.append("'");
Str.append(*ES);
Str.append("'");
}
if (!Str.empty())
P.formatLine("{0} | {1}", fmt_align(I, AlignStyle::Right, Digits), Str);
}
return Error::success();
}
Error RawOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
bool Present = false;
bool DumpBytes = false;
if (StreamIdx == StreamTPI) {
printHeader(P, "Types (TPI Stream)");
Present = File.hasPDBTpiStream();
DumpBytes = opts::raw::DumpTypeData;
} else if (StreamIdx == StreamIPI) {
printHeader(P, "Types (IPI Stream)");
Present = File.hasPDBIpiStream();
DumpBytes = opts::raw::DumpIdData;
}
AutoIndent Indent(P);
if (!Present) {
P.formatLine("Stream not present");
return Error::success();
}
ExitOnError Err("Unexpected error processing types");
auto &Stream = Err((StreamIdx == StreamTPI) ? File.getPDBTpiStream()
: File.getPDBIpiStream());
auto &Types = Err(initializeTypeDatabase(StreamIdx));
P.formatLine("Showing {0:N} records", Stream.getNumTypeRecords());
uint32_t Width =
NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
MinimalTypeDumpVisitor V(P, Width + 2, DumpBytes, Types);
Optional<TypeIndex> I = Types.getFirst();
if (auto EC = codeview::visitTypeStream(Types, V)) {
P.formatLine("An error occurred dumping type records: {0}",
toString(std::move(EC)));
}
return Error::success();
}
Expected<codeview::LazyRandomTypeCollection &>
RawOutputStyle::initializeTypeDatabase(uint32_t SN) {
auto &TypeCollection = (SN == StreamTPI) ? TpiTypes : IpiTypes;
auto Tpi =
(SN == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream();
if (!Tpi)
return Tpi.takeError();
if (!TypeCollection) {
auto &Types = Tpi->typeArray();
uint32_t Count = Tpi->getNumTypeRecords();
auto Offsets = Tpi->getTypeIndexOffsets();
TypeCollection =
llvm::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets);
}
return *TypeCollection;
}
Error RawOutputStyle::dumpModuleSyms() {
printHeader(P, "Symbols");
AutoIndent Indent(P);
if (!File.hasPDBDbiStream()) {
P.formatLine("DBI Stream not present");
return Error::success();
}
ExitOnError Err("Unexpected error processing symbols");
auto &Stream = Err(File.getPDBDbiStream());
auto &Types = Err(initializeTypeDatabase(StreamTPI));
const DbiModuleList &Modules = Stream.modules();
uint32_t Count = Modules.getModuleCount();
uint32_t Digits = NumDigits(Count);
for (uint32_t I = 0; I < Count; ++I) {
auto Modi = Modules.getModuleDescriptor(I);
P.formatLine("Mod {0:4} | `{1}`: ", fmt_align(I, AlignStyle::Right, Digits),
Modi.getModuleName());
uint16_t ModiStream = Modi.getModuleStreamIndex();
if (ModiStream == kInvalidStreamIndex) {
P.formatLine(" <symbols not present>");
continue;
}
auto ModStreamData = MappedBlockStream::createIndexedStream(
File.getMsfLayout(), File.getMsfBuffer(), ModiStream,
File.getAllocator());
ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
if (auto EC = ModS.reload()) {
P.formatLine("Error loading module stream {0}. {1}", I,
toString(std::move(EC)));
continue;
}
SymbolVisitorCallbackPipeline Pipeline;
SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
MinimalSymbolDumper Dumper(P, opts::raw::DumpSymRecordBytes, Types);
Pipeline.addCallbackToPipeline(Deserializer);
Pipeline.addCallbackToPipeline(Dumper);
CVSymbolVisitor Visitor(Pipeline);
if (auto EC = Visitor.visitSymbolStream(ModS.getSymbolArray())) {
P.formatLine("Error while processing symbol records. {0}",
toString(std::move(EC)));
continue;
}
}
return Error::success();
}
Error RawOutputStyle::dumpPublics() {
printHeader(P, "Public Symbols");
AutoIndent Indent(P);
if (!File.hasPDBPublicsStream()) {
P.formatLine("Publics stream not present");
return Error::success();
}
ExitOnError Err("Error dumping publics stream");
auto &Types = Err(initializeTypeDatabase(StreamTPI));
auto &Publics = Err(File.getPDBPublicsStream());
SymbolVisitorCallbackPipeline Pipeline;
SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
MinimalSymbolDumper Dumper(P, opts::raw::DumpSymRecordBytes, Types);
Pipeline.addCallbackToPipeline(Deserializer);
Pipeline.addCallbackToPipeline(Dumper);
CVSymbolVisitor Visitor(Pipeline);
auto ExpectedSymbols = Publics.getSymbolArray();
if (!ExpectedSymbols) {
P.formatLine("Could not read public symbol record stream");
return Error::success();
}
if (auto EC = Visitor.visitSymbolStream(*ExpectedSymbols))
P.formatLine("Error while processing public symbol records. {0}",
toString(std::move(EC)));
return Error::success();
}
static std::string formatSectionCharacteristics(uint32_t IndentLevel,
uint32_t C) {
using SC = COFF::SectionCharacteristics;
std::vector<std::string> Opts;
if (C == COFF::SC_Invalid)
return "invalid";
if (C == 0)
return "none";
PUSH_FLAG(SC, IMAGE_SCN_TYPE_NOLOAD, C, "IMAGE_SCN_TYPE_NOLOAD");
PUSH_FLAG(SC, IMAGE_SCN_TYPE_NO_PAD, C, "IMAGE_SCN_TYPE_NO_PAD");
PUSH_FLAG(SC, IMAGE_SCN_CNT_CODE, C, "IMAGE_SCN_CNT_CODE");
PUSH_FLAG(SC, IMAGE_SCN_CNT_INITIALIZED_DATA, C,
"IMAGE_SCN_CNT_INITIALIZED_DATA");
PUSH_FLAG(SC, IMAGE_SCN_CNT_UNINITIALIZED_DATA, C,
"IMAGE_SCN_CNT_UNINITIALIZED_DATA");
PUSH_FLAG(SC, IMAGE_SCN_LNK_OTHER, C, "IMAGE_SCN_LNK_OTHER");
PUSH_FLAG(SC, IMAGE_SCN_LNK_INFO, C, "IMAGE_SCN_LNK_INFO");
PUSH_FLAG(SC, IMAGE_SCN_LNK_REMOVE, C, "IMAGE_SCN_LNK_REMOVE");
PUSH_FLAG(SC, IMAGE_SCN_LNK_COMDAT, C, "IMAGE_SCN_LNK_COMDAT");
PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
PUSH_FLAG(SC, IMAGE_SCN_MEM_PURGEABLE, C, "IMAGE_SCN_MEM_PURGEABLE");
PUSH_FLAG(SC, IMAGE_SCN_MEM_16BIT, C, "IMAGE_SCN_MEM_16BIT");
PUSH_FLAG(SC, IMAGE_SCN_MEM_LOCKED, C, "IMAGE_SCN_MEM_LOCKED");
PUSH_FLAG(SC, IMAGE_SCN_MEM_PRELOAD, C, "IMAGE_SCN_MEM_PRELOAD");
PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1BYTES, C,
"IMAGE_SCN_ALIGN_1BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2BYTES, C,
"IMAGE_SCN_ALIGN_2BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4BYTES, C,
"IMAGE_SCN_ALIGN_4BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8BYTES, C,
"IMAGE_SCN_ALIGN_8BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_16BYTES, C,
"IMAGE_SCN_ALIGN_16BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_32BYTES, C,
"IMAGE_SCN_ALIGN_32BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_64BYTES, C,
"IMAGE_SCN_ALIGN_64BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_128BYTES, C,
"IMAGE_SCN_ALIGN_128BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_256BYTES, C,
"IMAGE_SCN_ALIGN_256BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_512BYTES, C,
"IMAGE_SCN_ALIGN_512BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1024BYTES, C,
"IMAGE_SCN_ALIGN_1024BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2048BYTES, C,
"IMAGE_SCN_ALIGN_2048BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4096BYTES, C,
"IMAGE_SCN_ALIGN_4096BYTES");
PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8192BYTES, C,
"IMAGE_SCN_ALIGN_8192BYTES");
PUSH_FLAG(SC, IMAGE_SCN_LNK_NRELOC_OVFL, C, "IMAGE_SCN_LNK_NRELOC_OVFL");
PUSH_FLAG(SC, IMAGE_SCN_MEM_DISCARDABLE, C, "IMAGE_SCN_MEM_DISCARDABLE");
PUSH_FLAG(SC, IMAGE_SCN_MEM_NOT_CACHED, C, "IMAGE_SCN_MEM_NOT_CACHED");
PUSH_FLAG(SC, IMAGE_SCN_MEM_NOT_PAGED, C, "IMAGE_SCN_MEM_NOT_PAGED");
PUSH_FLAG(SC, IMAGE_SCN_MEM_SHARED, C, "IMAGE_SCN_MEM_SHARED");
PUSH_FLAG(SC, IMAGE_SCN_MEM_EXECUTE, C, "IMAGE_SCN_MEM_EXECUTE");
PUSH_FLAG(SC, IMAGE_SCN_MEM_READ, C, "IMAGE_SCN_MEM_READ");
PUSH_FLAG(SC, IMAGE_SCN_MEM_WRITE, C, "IMAGE_SCN_MEM_WRITE");
return typesetItemList(Opts, 3, IndentLevel, " | ");
}
static std::string formatSegMapDescriptorFlag(uint32_t IndentLevel,
OMFSegDescFlags Flags) {
std::vector<std::string> Opts;
if (Flags == OMFSegDescFlags::None)
return "none";
PUSH_FLAG(OMFSegDescFlags, Read, Flags, "read");
PUSH_FLAG(OMFSegDescFlags, Write, Flags, "write");
PUSH_FLAG(OMFSegDescFlags, Execute, Flags, "execute");
PUSH_FLAG(OMFSegDescFlags, AddressIs32Bit, Flags, "32 bit addr");
PUSH_FLAG(OMFSegDescFlags, IsSelector, Flags, "selector");
PUSH_FLAG(OMFSegDescFlags, IsAbsoluteAddress, Flags, "absolute addr");
PUSH_FLAG(OMFSegDescFlags, IsGroup, Flags, "group");
return typesetItemList(Opts, 4, IndentLevel, " | ");
}
Error RawOutputStyle::dumpSectionContribs() {
printHeader(P, "Section Contributions");
ExitOnError Err("Error dumping publics stream");
AutoIndent Indent(P);
if (!File.hasPDBDbiStream()) {
P.formatLine(
"Section contribs require a DBI Stream, which could not be loaded");
return Error::success();
}
auto &Dbi = Err(File.getPDBDbiStream());
class Visitor : public ISectionContribVisitor {
public:
Visitor(LinePrinter &P) : P(P) {}
void visit(const SectionContrib &SC) override {
P.formatLine(
"SC | mod = {2}, {0}, size = {1}, data crc = {3}, reloc crc = {4}",
formatSegmentOffset(SC.ISect, SC.Off), SC.Size, SC.Imod, SC.DataCrc,
SC.RelocCrc);
P.formatLine(" {0}",
formatSectionCharacteristics(P.getIndentLevel() + 6,
SC.Characteristics));
}
void visit(const SectionContrib2 &SC) override {
P.formatLine("SC2 | mod = {2}, {0}, size = {1}, data crc = {3}, reloc "
"crc = {4}, coff section = {5}",
formatSegmentOffset(SC.Base.ISect, SC.Base.Off),
SC.Base.Size, SC.Base.Imod, SC.Base.DataCrc,
SC.Base.RelocCrc, SC.ISectCoff);
P.formatLine(" {0}",
formatSectionCharacteristics(P.getIndentLevel() + 6,
SC.Base.Characteristics));
}
private:
LinePrinter &P;
};
Visitor V(P);
Dbi.visitSectionContributions(V);
return Error::success();
}
Error RawOutputStyle::dumpSectionMap() {
printHeader(P, "Section Map");
ExitOnError Err("Error dumping section map");
AutoIndent Indent(P);
if (!File.hasPDBDbiStream()) {
P.formatLine("Dumping the section map requires a DBI Stream, which could "
"not be loaded");
return Error::success();
}
auto &Dbi = Err(File.getPDBDbiStream());
uint32_t I = 0;
for (auto &M : Dbi.getSectionMap()) {
P.formatLine(
"Section {0:4} | ovl = {0}, group = {1}, frame = {2}, name = {3}", I,
M.Ovl, M.Group, M.Frame, M.SecName);
P.formatLine(" class = {0}, offset = {1}, size = {2}",
M.ClassName, M.Offset, M.SecByteLength);
P.formatLine(" flags = {0}",
formatSegMapDescriptorFlag(
P.getIndentLevel() + 13,
static_cast<OMFSegDescFlags>(uint16_t(M.Flags))));
++I;
}
return Error::success();
}

View File

@ -32,13 +32,6 @@ using namespace llvm;
using namespace llvm::codeview; using namespace llvm::codeview;
using namespace llvm::pdb; using namespace llvm::pdb;
static bool checkModuleSubsection(opts::ModuleSubsection MS) {
return any_of(opts::pdb2yaml::DumpModuleSubsections,
[=](opts::ModuleSubsection M) {
return M == MS || M == opts::ModuleSubsection::All;
});
}
YAMLOutputStyle::YAMLOutputStyle(PDBFile &File) YAMLOutputStyle::YAMLOutputStyle(PDBFile &File)
: File(File), Out(outs()), Obj(File.getAllocator()) { : File(File), Out(outs()), Obj(File.getAllocator()) {
Out.setWriteDefaultValues(!opts::pdb2yaml::Minimal); Out.setWriteDefaultValues(!opts::pdb2yaml::Minimal);
@ -100,8 +93,8 @@ Error YAMLOutputStyle::dumpFileHeaders() {
} }
Error YAMLOutputStyle::dumpStringTable() { Error YAMLOutputStyle::dumpStringTable() {
bool RequiresStringTable = opts::pdb2yaml::DumpModuleFiles || bool RequiresStringTable = opts::shared::DumpModuleFiles ||
!opts::pdb2yaml::DumpModuleSubsections.empty(); !opts::shared::DumpModuleSubsections.empty();
bool RequestedStringTable = opts::pdb2yaml::StringTable; bool RequestedStringTable = opts::pdb2yaml::StringTable;
if (!RequiresStringTable && !RequestedStringTable) if (!RequiresStringTable && !RequestedStringTable)
return Error::success(); return Error::success();
@ -208,7 +201,7 @@ Error YAMLOutputStyle::dumpDbiStream() {
Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld(); Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld();
Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion(); Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion();
Obj.DbiStream->VerHeader = DS.getDbiVersion(); Obj.DbiStream->VerHeader = DS.getDbiVersion();
if (opts::pdb2yaml::DumpModules) { if (opts::shared::DumpModules) {
const auto &Modules = DS.modules(); const auto &Modules = DS.modules();
for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) { for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) {
DbiModuleDescriptor MI = Modules.getModuleDescriptor(I); DbiModuleDescriptor MI = Modules.getModuleDescriptor(I);
@ -218,7 +211,7 @@ Error YAMLOutputStyle::dumpDbiStream() {
DMI.Mod = MI.getModuleName(); DMI.Mod = MI.getModuleName();
DMI.Obj = MI.getObjFileName(); DMI.Obj = MI.getObjFileName();
if (opts::pdb2yaml::DumpModuleFiles) { if (opts::shared::DumpModuleFiles) {
auto Files = Modules.source_files(I); auto Files = Modules.source_files(I);
DMI.SourceFiles.assign(Files.begin(), Files.end()); DMI.SourceFiles.assign(Files.begin(), Files.end());
} }
@ -238,7 +231,7 @@ Error YAMLOutputStyle::dumpDbiStream() {
auto ExpectedST = File.getStringTable(); auto ExpectedST = File.getStringTable();
if (!ExpectedST) if (!ExpectedST)
return ExpectedST.takeError(); return ExpectedST.takeError();
if (!opts::pdb2yaml::DumpModuleSubsections.empty() && if (!opts::shared::DumpModuleSubsections.empty() &&
ModS.hasDebugSubsections()) { ModS.hasDebugSubsections()) {
auto ExpectedChecksums = ModS.findChecksumsSubsection(); auto ExpectedChecksums = ModS.findChecksumsSubsection();
if (!ExpectedChecksums) if (!ExpectedChecksums)
@ -249,7 +242,7 @@ Error YAMLOutputStyle::dumpDbiStream() {
for (const auto &SS : ModS.subsections()) { for (const auto &SS : ModS.subsections()) {
opts::ModuleSubsection OptionKind = convertSubsectionKind(SS.kind()); opts::ModuleSubsection OptionKind = convertSubsectionKind(SS.kind());
if (!checkModuleSubsection(OptionKind)) if (!opts::checkModuleSubsection(OptionKind))
continue; continue;
auto Converted = auto Converted =
@ -260,7 +253,7 @@ Error YAMLOutputStyle::dumpDbiStream() {
} }
} }
if (opts::pdb2yaml::DumpModuleSyms) { if (opts::shared::DumpModuleSyms) {
DMI.Modi.emplace(); DMI.Modi.emplace();
DMI.Modi->Signature = ModS.signature(); DMI.Modi->Signature = ModS.signature();

View File

@ -15,6 +15,7 @@
#include "Analyze.h" #include "Analyze.h"
#include "Diff.h" #include "Diff.h"
#include "LLVMOutputStyle.h"
#include "LinePrinter.h" #include "LinePrinter.h"
#include "OutputStyle.h" #include "OutputStyle.h"
#include "PrettyCompilandDumper.h" #include "PrettyCompilandDumper.h"
@ -22,7 +23,6 @@
#include "PrettyFunctionDumper.h" #include "PrettyFunctionDumper.h"
#include "PrettyTypeDumper.h" #include "PrettyTypeDumper.h"
#include "PrettyVariableDumper.h" #include "PrettyVariableDumper.h"
#include "RawOutputStyle.h"
#include "YAMLOutputStyle.h" #include "YAMLOutputStyle.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
@ -266,8 +266,6 @@ cl::list<std::string> InputFilenames(cl::Positional,
cl::OneOrMore, cl::sub(DiffSubcommand)); cl::OneOrMore, cl::sub(DiffSubcommand));
} }
cl::OptionCategory FileOptions("Module & File Options");
namespace raw { namespace raw {
cl::OptionCategory MsfOptions("MSF Container Options"); cl::OptionCategory MsfOptions("MSF Container Options");
@ -276,11 +274,18 @@ cl::OptionCategory SymbolOptions("Symbol Options");
cl::OptionCategory MiscOptions("Miscellaneous Options"); cl::OptionCategory MiscOptions("Miscellaneous Options");
// MSF OPTIONS // MSF OPTIONS
cl::opt<bool> DumpSummary("summary", cl::desc("dump file summary"), cl::opt<bool> DumpHeaders("headers", cl::desc("dump PDB headers"),
cl::cat(MsfOptions), cl::sub(RawSubcommand)); cl::cat(MsfOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpStreams("streams", cl::opt<bool> DumpStreamBlocks("stream-blocks",
cl::desc("dump PDB stream blocks"),
cl::cat(MsfOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpStreamSummary("stream-summary",
cl::desc("dump summary of the PDB streams"), cl::desc("dump summary of the PDB streams"),
cl::cat(MsfOptions), cl::sub(RawSubcommand)); cl::cat(MsfOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpPageStats(
"page-stats",
cl::desc("dump allocation stats of the pages in the MSF file"),
cl::cat(MsfOptions), cl::sub(RawSubcommand));
cl::opt<std::string> cl::opt<std::string>
DumpBlockRangeOpt("block-data", cl::value_desc("start[-end]"), DumpBlockRangeOpt("block-data", cl::value_desc("start[-end]"),
cl::desc("Dump binary data from specified range."), cl::desc("Dump binary data from specified range."),
@ -294,45 +299,40 @@ cl::list<std::string>
cl::cat(MsfOptions), cl::sub(RawSubcommand)); cl::cat(MsfOptions), cl::sub(RawSubcommand));
// TYPE OPTIONS // TYPE OPTIONS
cl::opt<bool> DumpTypes("types", cl::opt<bool>
CompactRecords("compact-records",
cl::desc("Dump type and symbol records with less detail"),
cl::cat(TypeOptions), cl::sub(RawSubcommand));
cl::opt<bool>
DumpTpiRecords("tpi-records",
cl::desc("dump CodeView type records from TPI stream"), cl::desc("dump CodeView type records from TPI stream"),
cl::cat(TypeOptions), cl::sub(RawSubcommand)); cl::cat(TypeOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpTypeData( cl::opt<bool> DumpTpiRecordBytes(
"type-data", "tpi-record-bytes",
cl::desc("dump CodeView type record raw bytes from TPI stream"), cl::desc("dump CodeView type record raw bytes from TPI stream"),
cl::cat(TypeOptions), cl::sub(RawSubcommand)); cl::cat(TypeOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpTpiHash("tpi-hash", cl::desc("dump CodeView TPI hash stream"),
cl::opt<bool> DumpTypeHashes("type-hash",
cl::desc("dump CodeView TPI hash stream"),
cl::cat(TypeOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpIds("ids",
cl::desc("dump CodeView type records from IPI stream"),
cl::cat(TypeOptions), cl::sub(RawSubcommand)); cl::cat(TypeOptions), cl::sub(RawSubcommand));
cl::opt<bool> cl::opt<bool>
DumpIdData("id-data", DumpIpiRecords("ipi-records",
cl::desc("dump CodeView type records from IPI stream"),
cl::cat(TypeOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpIpiRecordBytes(
"ipi-record-bytes",
cl::desc("dump CodeView type record raw bytes from IPI stream"), cl::desc("dump CodeView type record raw bytes from IPI stream"),
cl::cat(TypeOptions), cl::sub(RawSubcommand)); cl::cat(TypeOptions), cl::sub(RawSubcommand));
// SYMBOL OPTIONS // SYMBOL OPTIONS
cl::opt<bool> DumpGlobals("globals", cl::desc("dump globals stream data"),
cl::cat(SymbolOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpPublics("publics", cl::desc("dump Publics stream data"), cl::opt<bool> DumpPublics("publics", cl::desc("dump Publics stream data"),
cl::cat(SymbolOptions), cl::sub(RawSubcommand)); cl::cat(SymbolOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpSymbols("symbols", cl::desc("dump module symbols"),
cl::cat(SymbolOptions), cl::sub(RawSubcommand));
cl::opt<bool> cl::opt<bool>
DumpSymRecordBytes("sym-data", DumpSymRecordBytes("sym-record-bytes",
cl::desc("dump CodeView symbol record raw bytes"), cl::desc("dump CodeView symbol record raw bytes"),
cl::cat(SymbolOptions), cl::sub(RawSubcommand)); cl::cat(SymbolOptions), cl::sub(RawSubcommand));
// MODULE & FILE OPTIONS
cl::opt<bool> DumpModules("modules", cl::desc("dump compiland information"),
cl::cat(FileOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpModuleFiles(
"files",
cl::desc("for each module dumped, dump the contributing source files"),
cl::cat(FileOptions), cl::sub(RawSubcommand));
// MISCELLANEOUS OPTIONS // MISCELLANEOUS OPTIONS
cl::opt<bool> DumpStringTable("string-table", cl::desc("dump PDB String Table"), cl::opt<bool> DumpStringTable("string-table", cl::desc("dump PDB String Table"),
cl::cat(MiscOptions), cl::sub(RawSubcommand)); cl::cat(MiscOptions), cl::sub(RawSubcommand));
@ -342,6 +342,11 @@ cl::opt<bool> DumpSectionContribs("section-contribs",
cl::cat(MiscOptions), cl::sub(RawSubcommand)); cl::cat(MiscOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpSectionMap("section-map", cl::desc("dump section map"), cl::opt<bool> DumpSectionMap("section-map", cl::desc("dump section map"),
cl::cat(MiscOptions), cl::sub(RawSubcommand)); cl::cat(MiscOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpSectionHeaders("section-headers",
cl::desc("dump section headers"),
cl::cat(MiscOptions), cl::sub(RawSubcommand));
cl::opt<bool> DumpFpo("fpo", cl::desc("dump FPO records"), cl::cat(MiscOptions),
cl::sub(RawSubcommand));
cl::opt<bool> RawAll("all", cl::desc("Implies most other options."), cl::opt<bool> RawAll("all", cl::desc("Implies most other options."),
cl::cat(MiscOptions), cl::sub(RawSubcommand)); cl::cat(MiscOptions), cl::sub(RawSubcommand));
@ -399,11 +404,20 @@ cl::opt<bool> IpiStream("ipi-stream",
cl::desc("Dump the IPI Stream (Stream 5)"), cl::desc("Dump the IPI Stream (Stream 5)"),
cl::sub(PdbToYamlSubcommand), cl::init(false)); cl::sub(PdbToYamlSubcommand), cl::init(false));
cl::list<std::string> InputFilename(cl::Positional,
cl::desc("<input PDB file>"), cl::Required,
cl::sub(PdbToYamlSubcommand));
}
namespace shared {
cl::OptionCategory FileOptions("Module & File Options");
// MODULE & FILE OPTIONS // MODULE & FILE OPTIONS
cl::opt<bool> DumpModules("modules", cl::desc("dump compiland information"), cl::opt<bool> DumpModules("modules", cl::desc("dump compiland information"),
cl::cat(FileOptions), cl::sub(PdbToYamlSubcommand)); cl::cat(FileOptions), cl::sub(RawSubcommand),
cl::sub(PdbToYamlSubcommand));
cl::opt<bool> DumpModuleFiles("module-files", cl::desc("dump file information"), cl::opt<bool> DumpModuleFiles("module-files", cl::desc("dump file information"),
cl::cat(FileOptions), cl::cat(FileOptions), cl::sub(RawSubcommand),
cl::sub(PdbToYamlSubcommand)); cl::sub(PdbToYamlSubcommand));
cl::list<ModuleSubsection> DumpModuleSubsections( cl::list<ModuleSubsection> DumpModuleSubsections(
"subsections", cl::ZeroOrMore, cl::CommaSeparated, "subsections", cl::ZeroOrMore, cl::CommaSeparated,
@ -434,15 +448,11 @@ cl::list<ModuleSubsection> DumpModuleSubsections(
clEnumValN(ModuleSubsection::Unknown, "unknown", clEnumValN(ModuleSubsection::Unknown, "unknown",
"Any subsection not covered by another option"), "Any subsection not covered by another option"),
clEnumValN(ModuleSubsection::All, "all", "All known subsections")), clEnumValN(ModuleSubsection::All, "all", "All known subsections")),
cl::cat(FileOptions), cl::sub(PdbToYamlSubcommand)); cl::cat(FileOptions), cl::sub(RawSubcommand), cl::sub(PdbToYamlSubcommand));
cl::opt<bool> DumpModuleSyms("module-syms", cl::desc("dump module symbols"), cl::opt<bool> DumpModuleSyms("module-syms", cl::desc("dump module symbols"),
cl::cat(FileOptions), cl::cat(FileOptions), cl::sub(RawSubcommand),
cl::sub(PdbToYamlSubcommand)); cl::sub(PdbToYamlSubcommand));
} // namespace shared
cl::list<std::string> InputFilename(cl::Positional,
cl::desc("<input PDB file>"), cl::Required,
cl::sub(PdbToYamlSubcommand));
} // namespace pdb2yaml
namespace analyze { namespace analyze {
cl::opt<bool> StringTable("hash-collisions", cl::desc("Find hash collisions"), cl::opt<bool> StringTable("hash-collisions", cl::desc("Find hash collisions"),
@ -464,6 +474,13 @@ cl::opt<std::string>
static ExitOnError ExitOnErr; static ExitOnError ExitOnErr;
bool opts::checkModuleSubsection(opts::ModuleSubsection MS) {
return any_of(opts::shared::DumpModuleSubsections,
[=](opts::ModuleSubsection M) {
return M == MS || M == opts::ModuleSubsection::All;
});
}
static void yamlToPdb(StringRef Path) { static void yamlToPdb(StringRef Path) {
BumpPtrAllocator Allocator; BumpPtrAllocator Allocator;
ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer = ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
@ -594,7 +611,7 @@ static void dumpRaw(StringRef Path) {
std::unique_ptr<IPDBSession> Session; std::unique_ptr<IPDBSession> Session;
auto &File = loadPDB(Path, Session); auto &File = loadPDB(Path, Session);
auto O = llvm::make_unique<RawOutputStyle>(File); auto O = llvm::make_unique<LLVMOutputStyle>(File);
ExitOnErr(O->dump()); ExitOnErr(O->dump());
} }
@ -887,21 +904,49 @@ int main(int argc_, const char *argv_[]) {
} }
} }
if ((opts::RawSubcommand && opts::raw::RawAll) ||
(opts::PdbToYamlSubcommand && opts::pdb2yaml::All)) {
opts::shared::DumpModules = true;
opts::shared::DumpModuleFiles = true;
opts::shared::DumpModuleSyms = true;
opts::shared::DumpModuleSubsections.push_back(opts::ModuleSubsection::All);
if (llvm::is_contained(opts::shared::DumpModuleSubsections,
opts::ModuleSubsection::All)) {
opts::shared::DumpModuleSubsections.reset();
opts::shared::DumpModuleSubsections.push_back(
opts::ModuleSubsection::All);
}
}
if (opts::shared::DumpModuleSyms || opts::shared::DumpModuleFiles)
opts::shared::DumpModules = true;
if (opts::shared::DumpModules)
opts::pdb2yaml::DbiStream = true;
if (opts::RawSubcommand) { if (opts::RawSubcommand) {
if (opts::raw::RawAll) { if (opts::raw::RawAll) {
opts::raw::DumpIds = true; opts::raw::DumpHeaders = true;
opts::raw::DumpGlobals = true;
opts::raw::DumpPublics = true; opts::raw::DumpPublics = true;
opts::raw::DumpSectionContribs = true; opts::raw::DumpSectionHeaders = true;
opts::raw::DumpStreamSummary = true;
opts::raw::DumpPageStats = true;
opts::raw::DumpStreamBlocks = true;
opts::raw::DumpTpiRecords = true;
opts::raw::DumpTpiHash = true;
opts::raw::DumpIpiRecords = true;
opts::raw::DumpSectionMap = true; opts::raw::DumpSectionMap = true;
opts::raw::DumpStreams = true; opts::raw::DumpSectionContribs = true;
opts::raw::DumpFpo = true;
opts::raw::DumpStringTable = true; opts::raw::DumpStringTable = true;
opts::raw::DumpSummary = true; }
opts::raw::DumpSymbols = true;
opts::raw::DumpIds = true; if (opts::raw::CompactRecords &&
opts::raw::DumpTypes = true; (opts::raw::DumpTpiRecordBytes || opts::raw::DumpIpiRecordBytes)) {
opts::raw::DumpTypeHashes = true; errs() << "-compact-records is incompatible with -tpi-record-bytes and "
opts::raw::DumpModules = true; "-ipi-record-bytes.\n";
opts::raw::DumpModuleFiles = true; exit(1);
} }
} }
if (opts::PdbToYamlSubcommand) { if (opts::PdbToYamlSubcommand) {
@ -913,26 +958,9 @@ int main(int argc_, const char *argv_[]) {
opts::pdb2yaml::DbiStream = true; opts::pdb2yaml::DbiStream = true;
opts::pdb2yaml::TpiStream = true; opts::pdb2yaml::TpiStream = true;
opts::pdb2yaml::IpiStream = true; opts::pdb2yaml::IpiStream = true;
opts::pdb2yaml::DumpModules = true;
opts::pdb2yaml::DumpModuleFiles = true;
opts::pdb2yaml::DumpModuleSyms = true;
opts::pdb2yaml::DumpModuleSubsections.push_back(
opts::ModuleSubsection::All);
if (llvm::is_contained(opts::pdb2yaml::DumpModuleSubsections,
opts::ModuleSubsection::All)) {
opts::pdb2yaml::DumpModuleSubsections.reset();
opts::pdb2yaml::DumpModuleSubsections.push_back(
opts::ModuleSubsection::All);
} }
} }
if (opts::pdb2yaml::DumpModuleSyms || opts::pdb2yaml::DumpModuleFiles)
opts::pdb2yaml::DumpModules = true;
if (opts::pdb2yaml::DumpModules)
opts::pdb2yaml::DbiStream = true;
}
llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded); llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
if (opts::PdbToYamlSubcommand) { if (opts::PdbToYamlSubcommand) {

View File

@ -27,8 +27,6 @@ uint32_t getTypeLength(const PDBSymbolData &Symbol);
namespace opts { namespace opts {
enum class DumpLevel { None, Basic, Verbose };
enum class ModuleSubsection { enum class ModuleSubsection {
Unknown, Unknown,
Lines, Lines,
@ -43,6 +41,15 @@ enum class ModuleSubsection {
All All
}; };
bool checkModuleSubsection(ModuleSubsection Kind);
template <typename... Ts>
bool checkModuleSubsection(ModuleSubsection K1, ModuleSubsection K2,
Ts &&... Rest) {
return checkModuleSubsection(K1) ||
checkModuleSubsection(K2, std::forward<Ts>(Rest)...);
}
namespace pretty { namespace pretty {
enum class ClassDefinitionFormat { None, Layout, All }; enum class ClassDefinitionFormat { None, Layout, All };
@ -98,24 +105,27 @@ struct BlockRange {
llvm::Optional<uint32_t> Max; llvm::Optional<uint32_t> Max;
}; };
extern llvm::cl::opt<bool> DumpSummary;
extern llvm::cl::opt<bool> DumpStreams;
extern llvm::Optional<BlockRange> DumpBlockRange; extern llvm::Optional<BlockRange> DumpBlockRange;
extern llvm::cl::list<std::string> DumpStreamData; extern llvm::cl::list<std::string> DumpStreamData;
extern llvm::cl::opt<bool> DumpStringTable;
extern llvm::cl::opt<bool> DumpTypes; extern llvm::cl::opt<bool> CompactRecords;
extern llvm::cl::opt<bool> DumpTypeData; extern llvm::cl::opt<bool> DumpGlobals;
extern llvm::cl::opt<bool> DumpTypeHashes; extern llvm::cl::opt<bool> DumpHeaders;
extern llvm::cl::opt<bool> DumpIds; extern llvm::cl::opt<bool> DumpStreamBlocks;
extern llvm::cl::opt<bool> DumpIdData; extern llvm::cl::opt<bool> DumpStreamSummary;
extern llvm::cl::opt<bool> DumpSymbols; extern llvm::cl::opt<bool> DumpPageStats;
extern llvm::cl::opt<bool> DumpSymRecordBytes; extern llvm::cl::opt<bool> DumpTpiHash;
extern llvm::cl::opt<bool> DumpTpiRecordBytes;
extern llvm::cl::opt<bool> DumpTpiRecords;
extern llvm::cl::opt<bool> DumpIpiRecords;
extern llvm::cl::opt<bool> DumpIpiRecordBytes;
extern llvm::cl::opt<bool> DumpPublics; extern llvm::cl::opt<bool> DumpPublics;
extern llvm::cl::opt<bool> DumpSectionContribs; extern llvm::cl::opt<bool> DumpSectionContribs;
extern llvm::cl::opt<bool> DumpSectionMap; extern llvm::cl::opt<bool> DumpSectionMap;
extern llvm::cl::opt<bool> DumpModules; extern llvm::cl::opt<bool> DumpSymRecordBytes;
extern llvm::cl::opt<bool> DumpModuleFiles; extern llvm::cl::opt<bool> DumpSectionHeaders;
extern llvm::cl::opt<bool> RawAll; extern llvm::cl::opt<bool> DumpFpo;
extern llvm::cl::opt<bool> DumpStringTable;
} }
namespace diff { namespace diff {
@ -134,11 +144,14 @@ extern llvm::cl::opt<bool> DbiStream;
extern llvm::cl::opt<bool> TpiStream; extern llvm::cl::opt<bool> TpiStream;
extern llvm::cl::opt<bool> IpiStream; extern llvm::cl::opt<bool> IpiStream;
extern llvm::cl::list<std::string> InputFilename; extern llvm::cl::list<std::string> InputFilename;
}
namespace shared {
extern llvm::cl::opt<bool> DumpModules; extern llvm::cl::opt<bool> DumpModules;
extern llvm::cl::opt<bool> DumpModuleFiles; extern llvm::cl::opt<bool> DumpModuleFiles;
extern llvm::cl::list<ModuleSubsection> DumpModuleSubsections; extern llvm::cl::list<ModuleSubsection> DumpModuleSubsections;
extern llvm::cl::opt<bool> DumpModuleSyms; extern llvm::cl::opt<bool> DumpModuleSyms;
} // namespace pdb2yaml } // namespace shared
} }
#endif #endif