xref: /llvm-project/llvm/test/tools/llvm-objcopy/ELF/only-keep-debug.test (revision 3787de40de207b6a505e7b110d58ef4497241bff)
1# RUN: yaml2obj --docnum=1 %s -o %t1
2# RUN: llvm-objcopy --only-keep-debug %t1 %t1.dbg
3# RUN: llvm-readelf -S -l -x .note1 -x .note2 -x .debug_abbrev -x .debug_frame -x .debug_info %t1.dbg | FileCheck %s
4## --only-keep-debug suppresses the default --strip-all.
5# RUN: llvm-strip --only-keep-debug %t1
6# RUN: llvm-readelf -S -l -x .note1 -x .note2 -x .debug_abbrev -x .debug_frame -x .debug_info %t1 | FileCheck %s
7
8## Check that SHT_NOTE and .debug* are kept, but others are changed to SHT_NOBITS.
9## SHT_NOBITS sections do not occupy space in the output.
10
11# CHECK:      [Nr] Name          Type     Address          Off    Size   ES Flg Lk Inf Al
12# CHECK:      [ 1] .note1        NOTE     0000000000000400 000400 000001 00   A  0   0 1024
13# CHECK-NEXT: [ 2] .note2        NOTE     0000000000000401 000401 000001 00   A  0   0  0
14# CHECK-NEXT: [ 3] .text         NOBITS   0000000000000402 000402 000001 00  AX  0   0  0
15# CHECK-NEXT: [ 4] .tdata        NOBITS   0000000000001480 000480 000007 00 WAT  0   0 128
16# CHECK-NEXT: [ 5] .tbss         NOBITS   0000000000001487 000480 000005 00 WAT  0   0  0
17# CHECK-NEXT: [ 6] .bss          NOBITS   00000000000014a0 000480 00003f 00  WA  0   0 32
18## objcopy sets sh_offset to 0x402. We don't do this to keep sh_offset non-decreasing.
19# CHECK-NEXT: [ 7] .debug_abbrev PROGBITS 0000000000000000 000480 000001 00      0   0  0
20# CHECK-NEXT: [ 8] .debug_frame  PROGBITS 0000000000000000 000488 000001 00      0   0  8
21# CHECK-NEXT: [ 9] .debug_info   PROGBITS 0000000000000000 000489 000001 00      0   0  0
22# CHECK-NEXT: [10] .strtab       STRTAB   0000000000000000 00048a 000001 00      0   0  1
23# CHECK-NEXT: [11] .shstrtab     STRTAB   0000000000000000 00048b 000060 00      0   0  1
24
25# CHECK:      Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
26# CHECK-NEXT: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000402 0x000403 R E 0x1000
27# CHECK-NEXT: LOAD 0x000480 0x0000000000001480 0x0000000000001480 0x000000 0x00005f RW  0x1000
28# CHECK-NEXT: TLS  0x000480 0x0000000000001480 0x0000000000001480 0x000000 0x00000c RW  0x80
29# CHECK-NEXT: NOTE 0x000400 0x0000000000000400 0x0000000000000400 0x000002 0x000002     0x400
30
31## Contents of SHT_NOTE and .debug* are kept.
32
33# CHECK:      Hex dump of section '.note1':
34# CHECK-NEXT: 0x00000400 01
35# CHECK:      Hex dump of section '.note2':
36# CHECK-NEXT: 0x00000401 02
37# CHECK:      Hex dump of section '.debug_abbrev':
38# CHECK-NEXT: 0x00000000 03
39# CHECK:      Hex dump of section '.debug_frame':
40# CHECK-NEXT: 0x00000000 04
41# CHECK:      Hex dump of section '.debug_info':
42# CHECK-NEXT: 0x00000000 05
43
44--- !ELF
45FileHeader:
46  Class:     ELFCLASS64
47  Data:      ELFDATA2LSB
48  Type:      ET_DYN
49  Machine:   EM_X86_64
50Sections:
51  - Name:         .note1
52    Type:         SHT_NOTE
53    Flags:        [ SHF_ALLOC ]
54    Address:      0x400
55    AddressAlign: 0x400
56    Content:      01
57  - Name:         .note2
58    Type:         SHT_NOTE
59    Flags:        [ SHF_ALLOC ]
60    Address:      0x401
61    Content:      02
62  - Name:         .text
63    Type:         SHT_PROGBITS
64    Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
65    Address:      0x402
66    Content:      c3
67  - Name:         .tdata
68    Type:         SHT_PROGBITS
69    Flags:        [ SHF_ALLOC, SHF_WRITE, SHF_TLS ]
70    Address:      0x1480          # Ensure Address=0x1000+Offset
71    AddressAlign: 0x80
72    # An arbitrary non-zero Size tests that .tdata does not occupy space
73    # and we can rewrite p_filesz of PT_TLS.
74    Size:         7
75  - Name:         .tbss
76    Type:         SHT_NOBITS
77    Flags:        [ SHF_ALLOC, SHF_WRITE, SHF_TLS ]
78    Address:      0x1487          # Ensure Address=0x1000+Offset
79    Size:         5
80  - Name:         .bss
81    Type:         SHT_NOBITS
82    Flags:        [ SHF_ALLOC, SHF_WRITE ]
83    Address:      0x14a0          # Ensure Address=0x1000+Offset
84    AddressAlign: 0x20
85    # An arbitrary non-zero Size tests that .bss does not occupy space.
86    Size:         63
87  - Name:         .debug_abbrev
88    Type:         SHT_PROGBITS
89    Content:      03
90  - Name:         .debug_frame
91    Type:         SHT_PROGBITS
92    # AddressAlign tests the file offset assignment leaves a gap.
93    AddressAlign: 0x8
94    Content:      04
95  - Name:         .debug_info
96    Type:         SHT_PROGBITS
97    Content:      05
98ProgramHeaders:
99  - Type:     PT_LOAD
100    Flags:    [ PF_R, PF_X ]
101    Offset:   0
102    Align:    0x1000
103    FirstSec: .note1
104    LastSec:  .text
105  - Type:     PT_LOAD
106    Flags:    [ PF_R, PF_W ]
107    VAddr:    0x1480    # Ensure Offset=VAddr (mod Align) if Offset changes
108    Align:    0x1000
109    FirstSec: .tdata
110    LastSec:  .bss
111  - Type:     PT_TLS
112    Flags:    [ PF_R, PF_W ]
113    VAddr:    0x1480    # Ensure Offset=VAddr (mod Align) if Offset changes
114    FirstSec: .tdata
115    LastSec:  .tbss
116  - Type:     PT_NOTE
117    VAddr:    0x400
118    FirstSec: .note1
119    LastSec:  .note2
120...
121
122# RUN: yaml2obj --docnum=2 %s -o %t2
123# RUN: llvm-objcopy --only-keep-debug %t2 %t2.dbg
124# RUN: llvm-readelf -S -l %t2.dbg | FileCheck --check-prefix=CHECK2 %s
125
126## Only the tail of a segment can be trimmed. .text still occupies space because
127## it is followed by .note which is not SHT_NOBITS.
128# CHECK2:      [Nr] Name        Type     Address          Off    Size   ES Flg Lk Inf Al
129# CHECK2:      [ 1] .text       NOBITS   0000000000000200 000200 000001 00  AX  0   0 512
130# CHECK2-NEXT: [ 2] .note       NOTE     0000000000000201 000201 000001 00   A  0   0  0
131# CHECK2-NEXT: [ 3] .debug_info PROGBITS 0000000000000000 000220 000001 00      0   0 32
132# CHECK2-NEXT: [ 4] .strtab     STRTAB   0000000000000000 000221 000001 00      0   0  1
133# CHECK2-NEXT: [ 5] .shstrtab   STRTAB   0000000000000000 000222 00002b 00      0   0  1
134
135## Check that p_offset or p_filesz of PT_PHDR are not modified.
136# CHECK2:      Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
137# CHECK2-NEXT: PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0000a8 0x0000a8 R   0x8
138# CHECK2-NEXT: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000202 0x000202 R E 0x1000
139# CHECK2-NEXT: LOAD 0x000000 0x0000000000000202 0x0000000000000202 0x000000 0x00000e RW  0x1
140
141--- !ELF
142FileHeader:
143  Class:   ELFCLASS64
144  Data:    ELFDATA2LSB
145  Type:    ET_DYN
146  Machine: EM_X86_64
147Sections:
148  - Name:         .text
149    Type:         SHT_PROGBITS
150    Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
151    Address:      0x200
152    AddressAlign: 0x200
153    Content:      c3
154  - Name:         .note
155    Type:         SHT_NOTE
156    Flags:        [ SHF_ALLOC ]
157    Address:      0x201
158    Content:      01
159  - Name:         .debug_info
160    Type:         SHT_PROGBITS
161    AddressAlign: 0x20
162    Content:      02
163ProgramHeaders:
164  - Type:     PT_PHDR
165    Flags:    [ PF_R ]
166    Offset:   0x40
167    VAddr:    0x40
168    # 3 * sizeof(Elf64_Phdr) = 0xa8
169    FileSize: 0xa8
170    MemSize:  0xa8
171    Align:    8
172  - Type:     PT_LOAD
173    Flags:    [ PF_R, PF_X ]
174    Offset:   0
175    Align:    4096
176    FirstSec: .text
177    LastSec:  .note
178  - Type:     PT_LOAD
179    Flags:    [ PF_R, PF_W ]
180    Offset:   0x202
181    VAddr:    0x202
182    FileSize: 14
183    MemSize:  14
184...
185
186## If .symtab or .strtab has the SHF_ALLOC flag, it will be changed to SHT_NOBITS.
187# RUN: yaml2obj --docnum=3 %s -o %t3
188# RUN: llvm-objcopy --only-keep-debug %t3 %t3.dbg
189# RUN: llvm-readelf -S -l %t3.dbg | FileCheck --check-prefix=CHECK3 %s
190
191# CHECK3:      [Nr] Name          Type     Address          Off    Size   ES Flg Lk Inf Al
192# CHECK3:      [ 1] .dynsym       NOBITS   0000000000000000 000040 000018 18   A  2   1 1024
193# CHECK3-NEXT: [ 2] .dynstr       NOBITS   0000000000000018 000040 000001 00   A  0   0  0
194# CHECK3-NEXT: [ 3] .symtab       NOBITS   0000000000000019 000040 000018 00   A  4   1  0
195# CHECK3-NEXT: [ 4] .strtab       NOBITS   0000000000000031 000040 000001 00   A  0   0  0
196# CHECK3-NEXT: [ 5] .shstrtab     STRTAB   0000000000000000 000040 00002b 00      0   0  1
197
198--- !ELF
199FileHeader:
200  Class:   ELFCLASS64
201  Data:    ELFDATA2LSB
202  Type:    ET_DYN
203  Machine: EM_X86_64
204Sections:
205  - Name:  .dynsym
206    Type:  SHT_DYNSYM
207    Flags: [ SHF_ALLOC ]
208    Link:  .dynstr
209    AddressAlign: 0x400
210  - Name:  .dynstr
211    Type:  SHT_STRTAB
212    Flags: [ SHF_ALLOC ]
213  - Name:  .symtab
214## TODO: this should be SHT_SYMTAB, but currently llvm-objcopy reports an error:
215##       error: Symbol table has link index of 4 which is not a string table
216    Type:  SHT_STRTAB
217    Flags: [ SHF_ALLOC ]
218    Link:  .strtab
219  - Name:  .strtab
220    Type:  SHT_STRTAB
221    Flags: [ SHF_ALLOC ]
222DynamicSymbols: []
223Symbols: []
224
225## PT_TLS and .tdata are empty. Test that we set its p_offset to the parent
226## segment's p_offset. If we don't rewrite the p_offset of PT_TLS and the deleted
227## bytes are large, p_offset can be larger than the file size, and trigger
228## validation errors with subsequent tools.
229# RUN: yaml2obj --docnum=4 %s -o %t4
230# RUN: llvm-objcopy --only-keep-debug %t4 %t4.dbg
231# RUN: llvm-readelf -S -l %t4.dbg | FileCheck --check-prefix=CHECK4 %s
232
233# CHECK4:      [Nr] Name        Type     Address          Off    Size   ES Flg Lk Inf Al
234# CHECK4:      [ 1] .text       NOBITS   0000000000000200 000200 000001 00  AX  0   0  0
235# CHECK4-NEXT: [ 2] .tdata      NOBITS   0000000000001240 000240 000000 00 WAT  0   0 64
236# CHECK4-NEXT: [ 3] .got        NOBITS   0000000000001240 000240 000008 00  WA  0   0  0
237
238# CHECK4:      Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
239# CHECK4-NEXT: LOAD 0x000200 0x0000000000000200 0x0000000000000200 0x000000 0x000001 R E 0x1000
240# CHECK4-NEXT: LOAD 0x000240 0x0000000000001240 0x0000000000001240 0x000000 0x000008 RW  0x1000
241# CHECK4-NEXT: TLS  0x000240 0x0000000000001240 0x0000000000001240 0x000000 0x000000 R   0x40
242
243--- !ELF
244FileHeader:
245  Class:   ELFCLASS64
246  Data:    ELFDATA2LSB
247  Type:    ET_DYN
248  Machine: EM_X86_64
249Sections:
250  - Name:         .text
251    Type:         SHT_PROGBITS
252    Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
253    Address:      0x200
254    Size:         1
255  - Name:         .tdata
256    Type:         SHT_PROGBITS
257    Flags:        [ SHF_ALLOC, SHF_WRITE, SHF_TLS ]
258    Address:      0x1240   # Ensure Address=0x1000+Offset
259    AddressAlign: 0x40
260  - Name:         .got
261    Type:         SHT_PROGBITS
262    Flags:        [ SHF_ALLOC, SHF_WRITE ]
263    Size:         8
264ProgramHeaders:
265  - Type:     PT_LOAD
266    Flags:    [ PF_R, PF_X ]
267    VAddr:    0x200
268    Align:    0x1000
269    FirstSec: .text
270    LastSec:  .text
271  ## Add .got so that the PT_LOAD does not have zero p_memsz. We don't add
272  ## sections to zero-sized segments so zero-sized segments may have strange
273  ## offsets. In practice, the Linux kernel errors when mmapping a p_memsz
274  ## PT_LOAD,so for practical so this assumption can generally be made.
275  - Type:     PT_LOAD
276    Flags:    [ PF_R, PF_W ]
277    VAddr:    0x1240
278    Align:    0x1000
279    FirstSec: .tdata
280    LastSec:  .got
281  - Type:     PT_TLS
282    Flags:    [ PF_R ]
283    VAddr:    0x1240
284    FirstSec: .tdata
285    LastSec:  .tdata
286
287## The offset and size fields of segments which contain no section and have no
288## parent segment are set to zeros, so that we can decrease the file size. Such
289## segments are not useful for debugging.
290# RUN: yaml2obj --docnum=5 %s -o %t5
291# RUN: llvm-objcopy --only-keep-debug %t5 %t5.dbg
292# RUN: llvm-readelf -S -l %t5.dbg | FileCheck --check-prefix=CHECK5 %s
293# RUN: llvm-objcopy --strip-sections %t5 %t5s
294# RUN: llvm-objcopy --only-keep-debug %t5s %t5s.dbg
295# RUN: llvm-readelf -S -l %t5s.dbg | FileCheck --check-prefix=CHECK5S %s
296
297# CHECK5:      [Nr] Name        Type     Address          Off    Size   ES Flg Lk Inf Al
298# CHECK5:      [ 1] .foo        NOBITS   0000000000000000 000078 001000 00   A  0   0  0
299# CHECK5-NEXT: [ 2] .strtab     STRTAB   0000000000000000 000078 000001 00      0   0  1
300# CHECK5-NEXT: [ 3] .shstrtab   STRTAB   0000000000000000 000079 000018 00      0   0  1
301
302# CHECK5:      Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
303# CHECK5-NEXT: NULL 0x000000 0x0000000000000000 0x0000000000000000 0x000078 0x001000     0x1
304# CHECK5-EMPTY:
305
306# CHECK5S:      Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
307# CHECK5S-NEXT: NULL 0x000000 0x0000000000000000 0x0000000000000000 0x000078 0x001000     0x1
308# CHECK5S-EMPTY:
309--- !ELF
310FileHeader:
311  Class:   ELFCLASS64
312  Data:    ELFDATA2LSB
313  Type:    ET_DYN
314Sections:
315  - Name:    .foo
316    Type:    SHT_PROGBITS
317    Flags:   [ SHF_ALLOC ]
318    Size:    0x01000
319ProgramHeaders:
320  - Type:     PT_NULL
321    Flags:    []
322    FileSize: 0x01000
323    MemSize:  0x01000
324
325## Check that sections are placed correctly in a case when their order in the
326## section header table is different from their layout.
327# RUN: yaml2obj --docnum=6 %s -o %t6
328# RUN: llvm-objcopy --only-keep-debug %t6 %t6.dbg
329# RUN: llvm-readelf -S -l %t6.dbg | FileCheck --check-prefix=CHECK6 %s
330
331# CHECK6:      [Nr] Name        Type     Address          Off    Size   ES Flg Lk Inf Al
332# CHECK6:      [ 1] foo         NOBITS   0000000000000008 001000 000008 00   A  0   0  4
333# CHECK6-NEXT: [ 2] bar         NOBITS   0000000000000000 001000 000008 00   A  0   0  4
334# CHECK6-NEXT: [ 3] baz         NOTE     0000000000000018 001008 000008 00   A  0   0  0
335# CHECK6-NEXT: [ 4] qux         NOTE     0000000000000010 001000 000008 00   A  0   0  0
336
337# CHECK6:      Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
338# CHECK6-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000000 0x000010 R   0x1000
339# CHECK6-NEXT: LOAD 0x001000 0x0000000000000010 0x0000000000000010 0x000010 0x000010 R   0x1
340# CHECK6-EMPTY:
341
342--- !ELF
343FileHeader:
344  Class:           ELFCLASS64
345  Data:            ELFDATA2LSB
346  Type:            ET_DYN
347  Machine:         EM_X86_64
348ProgramHeaders:
349  - Type:     PT_LOAD
350    Flags:    [ PF_R ]
351    Offset:   0x1000
352    VAddr:    0x0
353    Align:    0x1000
354    FileSize: 0x10
355    MemSize:  0x10
356  - Type:     PT_LOAD
357    Flags:    [ PF_R ]
358    Offset:   0x1010
359    VAddr:    0x10
360    FileSize: 0x10
361    MemSize:  0x10
362Sections:
363  - Name:            bar
364    Type:            SHT_PROGBITS
365    Flags:           [ SHF_ALLOC ]
366    Address:         0x0
367    AddressAlign:    0x4
368    Offset:          0x1000
369    Content:         0000000000000000
370  - Name:            foo
371    Type:            SHT_PROGBITS
372    Flags:           [ SHF_ALLOC ]
373    Address:         0x8
374    AddressAlign:    0x4
375    Offset:          0x1008
376    Content:         0000000000000000
377  - Name:            qux
378    Type:            SHT_NOTE
379    Flags:           [ SHF_ALLOC ]
380    Address:         0x10
381    Offset:          0x1010
382    Content:         0000000000000000
383  - Name:            baz
384    Type:            SHT_NOTE
385    Flags:           [ SHF_ALLOC ]
386    Address:         0x18
387    Offset:          0x1018
388    Content:         0000000000000000
389  - Type:            SectionHeaderTable
390    Sections:
391## Note: the order of section headers differs from their layout.
392      - Name:            foo
393      - Name:            bar
394      - Name:            baz
395      - Name:            qux
396      - Name:            .shstrtab
397      - Name:            .strtab
398