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