1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
Replicate this scenario:
$ cat a.c
struct Foo { int x; };
int g(struct Foo *p);
int main() {
struct Foo f = {42};
return g(&f);
}
$ cat b.c
struct Foo { int x; };
int g(struct Foo *p) { return p->x; }
$ cl -c a.c b.c -Zi -Fdts.pdb
$ lld-link a.obj b.obj -debug -entry:main -nodefaultlib -out:t.exe
RUN: rm -rf %t && mkdir -p %t && cd %t
RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj
RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj
RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb
RUN: lld-link a.obj b.obj -entry:main -debug:noghash -out:t.exe -pdb:t.pdb -nodefaultlib -summary | FileCheck %s -check-prefix SUMMARY
RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s
Re-run with /DEBUG:GHASH
RUN: lld-link a.obj b.obj -entry:main -debug:ghash -out:t.exe -pdb:t.pdb -nodefaultlib -summary -verbose
RUN: llvm-pdbutil dump -symbols -types -ids -globals %t/t.pdb | FileCheck %s
Re-run with pdb from outputpath
RUN: mkdir -p libs
RUN: cp a.obj libs/a.obj && cp b.obj libs/b.obj
RUN: lld-link libs/a.obj libs/b.obj -entry:main -debug:ghash -out:t.exe -pdb:t.pdb -nodefaultlib -summary 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PDBFILE
CHECK-LABEL: Types (TPI Stream)
CHECK: ============================================================
CHECK: [[FOO_DECL:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo`
CHECK: [[FOO_PTR:[^ ]*]] | LF_POINTER [size = 12]
CHECK-NEXT: referent = [[FOO_DECL]]
CHECK: [[G_ARGS:[^ ]*]] | LF_ARGLIST [size = 12]
CHECK-NEXT: [[FOO_PTR]]: `Foo*`
CHECK: [[G_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16]
CHECK-NEXT: return type = 0x0074 (int), # args = 1, param list = [[G_ARGS]]
CHECK-NEXT: calling conv = cdecl, options = None
CHECK: [[FOO_COMPLETE:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo`
CHECK-NEXT: unique name: `.?AUFoo@@`
CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: 0x{{.*}}
CHECK: options: has unique name
CHECK: [[MAIN_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16]
CHECK: return type = 0x0074 (int), # args = 0, param list = 0x{{.*}}
CHECK: calling conv = cdecl, options = None
CHECK-LABEL: Types (IPI Stream)
CHECK: ============================================================
CHECK: [[MAIN_ID:[^ ]*]] | LF_FUNC_ID [size = 20]
CHECK: name = main, type = [[MAIN_PROTO]], parent scope = <no type>
CHECK: [[G_ID:[^ ]*]] | LF_FUNC_ID [size = 16]
CHECK: name = g, type = [[G_PROTO]], parent scope = <no type>
CHECK: [[A_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28]
CHECK: {{.*}}: `a.c`
CHECK: [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28]
CHECK: {{.*}}: `b.c`
CHECK-LABEL: Global Symbols
CHECK: ============================================================
CHECK-NEXT: Records
CHECK-NEXT: 36 | S_PROCREF [size = 20] `main`
CHECK-NEXT: module = 1, sum name = 0, offset = 104
CHECK-NEXT: 68 | S_PROCREF [size = 16] `g`
CHECK-NEXT: module = 2, sum name = 0, offset = 104
CHECK-NEXT: 56 | S_UDT [size = 12] `Foo`
CHECK-NEXT: original type = 0x1006
CHECK-LABEL: Symbols
CHECK: ============================================================
CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`:
CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj`
CHECK: 104 | S_GPROC32 [size = 44] `main`
CHECK: parent = 0, end = 196, addr = 0001:0000, code size = 27
CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none
CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]`
CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`:
CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj`
CHECK: 44 | S_COMPILE3 [size = 60]
CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
CHECK: flags = security checks | hot patchable
CHECK: 104 | S_GPROC32 [size = 44] `g`
CHECK: parent = 0, end = 196, addr = 0001:0032, code size = 13
CHECK: type = {{.*}}, debug start = 5, debug end = 12, flags = none
CHECK: 148 | S_FRAMEPROC [size = 32]
CHECK: size = 0, padding size = 0, offset to padding = 0
CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
CHECK: flags = has async eh | opt speed
CHECK: 180 | S_REGREL32 [size = 16] `p`
CHECK: type = [[FOO_PTR]] (Foo*), register = RSP, offset = 8
CHECK: 196 | S_END [size = 4]
CHECK: 200 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`
CHECK-LABEL: Mod 0002 | `* Linker *`:
SUMMARY: Summary
SUMMARY-NEXT: --------------------------------------------------------------------------------
SUMMARY-NEXT: 2 Input OBJ files (expanded from all cmd-line inputs)
SUMMARY-NEXT: 1 PDB type server dependencies
SUMMARY-NEXT: 0 Precomp OBJ dependencies
SUMMARY-NEXT: 25 Input type records
SUMMARY-NEXT: 868 Input type records bytes
SUMMARY-NEXT: 9 Merged TPI records
SUMMARY-NEXT: 16 Merged IPI records
SUMMARY-NEXT: 3 Output PDB strings
SUMMARY-NEXT: 4 Global symbol records
SUMMARY-NEXT: 14 Module symbol records
SUMMARY-NEXT: 2 Public symbol records
SUMMARY: Top 10 types responsible for the most TPI input:
SUMMARY-NEXT: index total bytes count size
SUMMARY-NEXT: 0x1006: 36 = 1 * 36
SUMMARY: Run llvm-pdbutil to print details about a particular record:
SUMMARY-NEXT: llvm-pdbutil dump -types -type-index 0x1006 t.pdb
SUMMARY: Top 10 types responsible for the most IPI input:
SUMMARY-NEXT: index total bytes count size
SUMMARY-NEXT: 0x1006: 256 = 1 * 256
SUMMARY: Run llvm-pdbutil to print details about a particular record:
SUMMARY-NEXT: llvm-pdbutil dump -ids -id-index 0x1006 t.pdb
FAILURE-MISSING-PDBFILE-NOT: Cannot use debug info for '{{.*}}.obj'
FAILURE-MISSING-PDBFILE-NOT: failed to load reference '{{.*}}.pdb': no such file or directory
|