program-headers.yaml
21.4 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
## Show that obj2yaml is able to dump program headers.
## Part I. Base check. All simple cases that look OK as a part of a single large test live here.
# RUN: yaml2obj %s -o %t1
## Show the layout of the object before we dump it using obj2yaml.
## The check is here to make it clear what the layout should look like.
# RUN: llvm-readelf --segments %t1 | FileCheck %s --check-prefix=SEGMENT-MAPPING
# SEGMENT-MAPPING: Program Headers:
# SEGMENT-MAPPING-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
# SEGMENT-MAPPING-NEXT: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000281 0x000281 R 0x1000
# SEGMENT-MAPPING-NEXT: LOAD 0x000281 0x0000000000001000 0x0000000000001000 0x000010 0x000010 R E 0x1000
# SEGMENT-MAPPING-NEXT: LOAD 0x000291 0x0000000000002000 0x0000000000002000 0x000009 0x000009 R 0x1000
# SEGMENT-MAPPING-NEXT: LOAD 0x00029a 0x0000000000003ef0 0x0000000000003ef0 0x000011 0x000011 RW 0x1000
# SEGMENT-MAPPING-NEXT: DYNAMIC 0x00029a 0x0000000000003ef0 0x0000000000003ef0 0x000010 0x000010 RW 0x8
# SEGMENT-MAPPING-NEXT: GNU_RELRO 0x00029a 0x0000000000003ef0 0x0000000000003ef0 0x000010 0x000010 R 0x1
# SEGMENT-MAPPING-NEXT: LOAD 0x000000 0x0000000000004000 0x0000000000004000 0x000000 0x000000 R 0x1
# SEGMENT-MAPPING-NEXT: LOAD 0x000248 0x00000000000001a0 0x00000000000001a0 0x000020 0x000020 R 0x1
# SEGMENT-MAPPING-NEXT: LOAD 0x000248 0x00000000000001a0 0x00000000000001a0 0x000020 0x000020 R 0x1
# SEGMENT-MAPPING: Section to Segment mapping:
# SEGMENT-MAPPING-NEXT: Segment Sections...
# SEGMENT-MAPPING-NEXT: 00 .hash .gnu.hash .dynsym .dynstr {{$}}
# SEGMENT-MAPPING-NEXT: 01 .foo .zed {{$}}
# SEGMENT-MAPPING-NEXT: 02 .foo .baz {{$}}
# SEGMENT-MAPPING-NEXT: 03 .dynamic .dynamic.tail {{$}}
# SEGMENT-MAPPING-NEXT: 04 .dynamic {{$}}
# SEGMENT-MAPPING-NEXT: 05 .dynamic {{$}}
# SEGMENT-MAPPING-NEXT: 06{{ *$}}
# SEGMENT-MAPPING-NEXT: 07 .gnu.hash {{$}}
# SEGMENT-MAPPING-NEXT: 08 .gnu.hash {{$}}
# SEGMENT-MAPPING-NEXT: None .symtab .strtab .shstrtab {{$}}
## Check that obj2yaml produced a correct program headers description.
# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=YAML
# YAML: ProgramHeaders:
# YAML-NEXT: - Type: PT_LOAD
# YAML-NEXT: Flags: [ PF_R ]
# YAML-NEXT: Sections:
# YAML-NEXT: - Section: .hash
# YAML-NEXT: - Section: .gnu.hash
# YAML-NEXT: - Section: .dynsym
# YAML-NEXT: - Section: .dynstr
# YAML-NEXT: Align: 0x0000000000001000
# YAML-NEXT: - Type: PT_LOAD
# YAML-NEXT: Flags: [ PF_X, PF_R ]
# YAML-NEXT: Sections:
# YAML-NEXT: - Section: .foo
# YAML-NEXT: - Section: .zed
# YAML-NEXT: VAddr: 0x0000000000001000
# YAML-NEXT: Align: 0x0000000000001000
# YAML-NEXT: - Type: PT_LOAD
# YAML-NEXT: Flags: [ PF_R ]
# YAML-NEXT: Sections:
# YAML-NEXT: - Section: '.foo (1)'
# YAML-NEXT: - Section: .baz
# YAML-NEXT: VAddr: 0x0000000000002000
# YAML-NEXT: Align: 0x0000000000001000
# YAML-NEXT: - Type: PT_LOAD
# YAML-NEXT: Flags: [ PF_W, PF_R ]
# YAML-NEXT: Sections:
# YAML-NEXT: - Section: .dynamic
# YAML-NEXT: - Section: .dynamic.tail
# YAML-NEXT: VAddr: 0x0000000000003EF0
# YAML-NEXT: Align: 0x0000000000001000
# YAML-NEXT: - Type: PT_DYNAMIC
# YAML-NEXT: Flags: [ PF_W, PF_R ]
# YAML-NEXT: Sections:
# YAML-NEXT: - Section: .dynamic
# YAML-NEXT: VAddr: 0x0000000000003EF0
# YAML-NEXT: Align: 0x0000000000000008
# YAML-NEXT: - Type: PT_GNU_RELRO
# YAML-NEXT: Flags: [ PF_R ]
# YAML-NEXT: Sections:
# YAML-NEXT: - Section: .dynamic
# YAML-NEXT: VAddr: 0x0000000000003EF0
# YAML-NEXT: - Type: PT_LOAD
# YAML-NEXT: Flags: [ PF_R ]
# YAML-NEXT: VAddr: 0x0000000000004000
# YAML-NEXT: - Type: PT_LOAD
# YAML-NEXT: Flags: [ PF_R ]
# YAML-NEXT: Sections:
# YAML-NEXT: - Section: .gnu.hash
# YAML-NEXT: VAddr: 0x00000000000001A0
# YAML-NEXT: - Type: PT_LOAD
# YAML-NEXT: Flags: [ PF_R ]
# YAML-NEXT: Sections:
# YAML-NEXT: - Section: .gnu.hash
# YAML-NEXT: VAddr: 0x00000000000001A0
# YAML-NEXT: Sections:
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
ProgramHeaders:
## Check we can create a PT_LOAD with arbitrary (we used .hash, .gnu.hash)
## and implicit sections (we use .dynsym, .dynstr). It also checks that the
## SHT_NULL section at index 0 is not included in the segment.
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: .hash
- Section: .gnu.hash
- Section: .dynsym
- Section: .dynstr
Align: 0x1000
Offset: 0x0
## Check we can create a PT_LOAD with a different set of properties and sections.
- Type: PT_LOAD
Flags: [ PF_X, PF_R ]
Sections:
- Section: .foo
- Section: .zed
VAddr: 0x1000
Align: 0x1000
## Create a PT_LOAD to demonstate we are able to refer to output sections with the same name.
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: '.foo (1)'
- Section: .baz
VAddr: 0x2000
Align: 0x1000
## Show we can create a writeable PT_LOAD segment and put an arbitrary section into it.
## Here we test both regular (SHT_PROGBITS) and a special section (SHT_DYNAMIC).
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
Sections:
- Section: .dynamic
- Section: .dynamic.tail
VAddr: 0x3EF0
Align: 0x1000
## Show we can create a nested dynamic segment and put a section into it.
- Type: PT_DYNAMIC
Flags: [ PF_W, PF_R ]
Sections:
- Section: .dynamic
VAddr: 0x3EF0
Align: 0x8
## Show we can create a relro segment and put a section into it.
## We used .dynamic here and in tests above to demonstrate that
## we can place a section in any number of segments.
## Also, we explicitly set the "Align" property to 1 to demonstate
## that we do not dump it, because it is the default alignment
## value set by yaml2obj.
- Type: PT_GNU_RELRO
Flags: [ PF_R ]
Sections:
- Section: .dynamic
VAddr: 0x3EF0
Align: 0x1
## Show we can dump a standalone empty segment.
- Type: PT_LOAD
Flags: [ PF_R ]
Sections: [ ]
VAddr: 0x4000
Align: 0x1
## ELF specification says that loadable segment entries in the
## program header are sorted by virtual address.
## Show we can dump an out of order segment.
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: .gnu.hash
VAddr: 0x1A0
Align: 0x1
## Test we are able to dump duplicated segments.
## We use a segment that is the same as the previous one for this.
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: .gnu.hash
VAddr: 0x1A0
Align: 0x1
Sections:
- Name: .hash
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Address: 0x190
Size: 0x10
- Name: .gnu.hash
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Address: 0x1A0
Size: 0x20
- Name: .dynsym
Type: SHT_DYNSYM
Flags: [ SHF_ALLOC ]
Address: 0x1C0
Link: .dynstr
EntSize: 0x18
- Name: .dynstr
Type: SHT_STRTAB
Flags: [ SHF_ALLOC ]
Address: 0x1D8
- Name: .foo
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x1000
Size: 0x8
- Name: .zed
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x1008
Size: 0x8
- Name: '.foo (1)'
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Address: 0x2000
Size: 0x8
- Name: .baz
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Address: 0x2008
Size: 0x1
- Name: .dynamic
Type: SHT_DYNAMIC
Flags: [ SHF_WRITE, SHF_ALLOC ]
Address: 0x0000000000003EF0
Link: .dynstr
Entries:
- Tag: DT_NULL
Value: 0x0
- Name: .dynamic.tail
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
Content: "FE"
Symbols: []
DynamicSymbols: []
## Part II. More specific tests.
## Check we are able to dump segments that are empty or
## contain empty sections.
# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=EMPTY
# EMPTY: - Type: PT_LOAD
# EMPTY-NEXT: Flags: [ PF_W, PF_R ]
# EMPTY-NEXT: Sections:
# EMPTY-NEXT: - Section: .empty.tls.start
# EMPTY-NEXT: - Section: .section.1
# EMPTY-NEXT: - Section: .empty.tls.middle
# EMPTY-NEXT: - Section: .section.2
# EMPTY-NEXT: - Section: .empty.tls.end
# EMPTY-NEXT: VAddr: 0x0000000000001000
# EMPTY-NEXT: Align: 0x0000000000001000
# EMPTY-NEXT: - Type: PT_TLS
# EMPTY-NEXT: Flags: [ PF_W, PF_R ]
# EMPTY-NEXT: Sections:
# EMPTY-NEXT: - Section: .empty.tls.start
# EMPTY-NEXT: VAddr: 0x0000000000001000
# EMPTY-NEXT: - Type: PT_TLS
# EMPTY-NEXT: Flags: [ PF_W, PF_R ]
# EMPTY-NEXT: Sections:
# EMPTY-NEXT: - Section: .empty.tls.middle
# EMPTY-NEXT: VAddr: 0x0000000000001100
# EMPTY-NEXT: - Type: PT_TLS
# EMPTY-NEXT: Flags: [ PF_W, PF_R ]
# EMPTY-NEXT: Sections:
# EMPTY-NEXT: - Section: .empty.tls.end
# EMPTY-NEXT: VAddr: 0x0000000000001200
# EMPTY-NEXT: Sections:
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
Sections:
- Section: .empty.tls.start
- Section: .section.1
- Section: .empty.tls.middle
- Section: .section.2
- Section: .empty.tls.end
VAddr: 0x1000
Align: 0x1000
- Type: PT_TLS
Flags: [ PF_W, PF_R ]
Sections:
- Section: .empty.tls.start
VAddr: 0x1000
Align: 0x1
- Type: PT_TLS
Flags: [ PF_W, PF_R ]
Sections:
- Section: .empty.tls.middle
VAddr: 0x1100
Align: 0x1
- Type: PT_TLS
Flags: [ PF_W, PF_R ]
Sections:
- Section: .empty.tls.end
VAddr: 0x1200
Align: 0x1
Sections:
- Name: .empty.tls.start
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_TLS ]
Size: 0x0
Address: 0x1000
- Name: .section.1
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Size: 0x100
- Name: .empty.tls.middle
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_TLS ]
Size: 0x0
- Name: .section.2
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Size: 0x100
- Name: .empty.tls.end
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_TLS ]
Size: 0x0
## Document we are able to dump misaligned segments.
## I.e. segments where (p_offset % p_align) != (p_vaddr % p_align).
# RUN: yaml2obj --docnum=3 %s -o %t3
# RUN: llvm-readelf --segments --sections %t3 | FileCheck %s --check-prefix=MISALIGNED-READELF
# RUN: obj2yaml %t3 | FileCheck %s --check-prefix=MISALIGNED-YAML
## As a misaligned p_offset value we use (`.foo` section offset - 1).
# MISALIGNED-READELF: [Nr] Name Type Address Off
# MISALIGNED-READELF: [ 1] .foo PROGBITS 0000000000001000 000078
# MISALIGNED-READELF: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
# MISALIGNED-READELF-NEXT: LOAD 0x000077 0x0000000000001000 0x0000000000001000 0x000078 0x000078 R 0x1000
# MISALIGNED-YAML: ProgramHeaders:
# MISALIGNED-YAML-NEXT: - Type: PT_LOAD
# MISALIGNED-YAML-NEXT: Flags: [ PF_R ]
# MISALIGNED-YAML-NEXT: Sections:
# MISALIGNED-YAML-NEXT: - Section: .foo
# MISALIGNED-YAML-NEXT: VAddr: 0x0000000000001000
# MISALIGNED-YAML-NEXT: Align: 0x0000000000001000
# MISALIGNED-YAML-NEXT: Sections:
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: .foo
VAddr: 0x1000
Align: 0x1000
Offset: 0x000077
Sections:
- Name: .foo
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Size: 0x77
Address: 0x1000
## Test we include non-allocatable sections in segments.
## We also document that SHT_NULL sections are not considered to be inside a segment.
# RUN: yaml2obj --docnum=4 %s -o %t4
# RUN: obj2yaml %t4 | FileCheck %s --check-prefix=NON-ALLOC
# NON-ALLOC: ProgramHeaders:
# NON-ALLOC-NEXT: - Type: PT_LOAD
# NON-ALLOC-NEXT: Flags: [ PF_R ]
# NON-ALLOC-NEXT: Sections:
# NON-ALLOC-NEXT: - Section: .alloc.1
# NON-ALLOC-NEXT: - Section: .non-alloc.1
# NON-ALLOC-NEXT: - Section: .alloc.2
# NON-ALLOC-NEXT: VAddr: 0x0000000000001000
# NON-ALLOC-NEXT: Sections:
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: .alloc.1
- Section: .alloc.2
VAddr: 0x1000
Sections:
- Name: .alloc.1
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Size: 0x100
Address: 0x1000
- Name: .non-alloc.1
Type: SHT_PROGBITS
Flags: [ ]
Size: 0x10
- Name: .non-alloc.2
Type: SHT_NULL
Flags: [ ]
Size: 0x10
- Name: .alloc.2
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Size: 0x1
## Check how we dump segments which contain SHT_NOBITS sections.
# RUN: yaml2obj --docnum=5 %s -o %t5
# RUN: obj2yaml %t5 | FileCheck %s --check-prefix=NOBITS
# NOBITS: ProgramHeaders:
# NOBITS-NEXT: - Type: PT_LOAD
# NOBITS-NEXT: Flags: [ PF_W, PF_R ]
# NOBITS-NEXT: Sections:
# NOBITS-NEXT: - Section: .bss
# NOBITS-NEXT: - Type: PT_LOAD
# NOBITS-NEXT: Flags: [ PF_W, PF_R ]
# NOBITS-NEXT: Sections:
# NOBITS-NEXT: - Section: .data.1
# NOBITS-NEXT: - Section: .bss
# NOBITS-NEXT: - Type: PT_LOAD
# NOBITS-NEXT: Flags: [ PF_W, PF_R ]
# NOBITS-NEXT: Sections:
# NOBITS-NEXT: - Section: .data.1
# NOBITS-NEXT: - Section: .bss
# NOBITS-NEXT: - Section: .data.2
# NOBITS-NEXT: - Type: PT_LOAD
# NOBITS-NEXT: Flags: [ PF_W, PF_R ]
# NOBITS-NEXT: Sections:
# NOBITS-NEXT: - Section: .bss
# NOBITS-NEXT: - Section: .data.2
# NOBITS-NEXT: - Type: PT_LOAD
# NOBITS-NEXT: Flags: [ PF_W, PF_R ]
# NOBITS-NEXT: Sections:
# NOBITS-NEXT: - Section: .foo.bss
# NOBITS-NEXT: - Section: .bar.bss
# NOBITS-NEXT: VAddr: 0x0000000200000000
# NOBITS-NEXT: Sections:
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
ProgramHeaders:
## Case 1: the segment contains a single SHT_NOBITS section.
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
Sections:
- Section: .bss
## Case 2: the SHT_NOBITS section is the last section in the segment.
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
Sections:
- Section: .data.1
- Section: .bss
## Case 3: the SHT_NOBITS section is in the middle of the segment.
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
Sections:
- Section: .data.1
- Section: .bss
- Section: .data.2
## Case 4: the SHT_NOBITS section is the first section in the segment.
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
Sections:
- Section: .bss
- Section: .data.2
## Case 5: another two SHT_NOBITS sections in a different segment.
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
Sections:
- Section: .foo.bss
- Section: .bar.bss
VAddr: 0x200000000
Sections:
- Name: .data.1
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
## Use an arbitrary address and size.
Address: 0x1000
Size: 0x1
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
## Use a size that is larger than the file size.
ShSize: 0x00000000FFFFFFFF
- Name: .data.2
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
## Use an arbitrary size.
Size: 0x1
- Name: .foo.bss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
## Set an arbitrary address and size so that this section can be used
## to start a different non-overlapping segment.
## I.e. its address is larger than addresses of previous sections.
Size: 0x10
Address: 0x200000000
- Name: .bar.bss
Type: SHT_NOBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
## Use an arbitrary size that is different to the size of
## the previous section.
Size: 0x20
## Check that we require sections in a program header
## declaration to be sorted by their offsets.
# RUN: not yaml2obj --docnum=6 %s -o %t6 2>&1 | \
# RUN: FileCheck %s --check-prefix=UNSORTED --implicit-check-not="error:"
# UNSORTED: error: sections in the program header with index 1 are not sorted by their file offset
# UNSORTED-NEXT: error: sections in the program header with index 3 are not sorted by their file offset
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
ProgramHeaders:
## Case 1: the .bar section is placed after the .foo section in the file.
## Check we report an error about the violation of the order.
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: .bar
- Section: .foo
VAddr: 0x1000
## There is nothing wrong with this segment. We have it to show that
## we report correct program header indices in error messages.
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: .foo
- Section: .bar
VAddr: 0x1000
## Case 2: the .bar section is placed before the .zed section in the file,
## but the sh_offset of .zed is less than the sh_offset of
## the .bar section because of the "ShOffset" property.
## Document we report an error for such a case.
- Type: PT_LOAD
Flags: [ PF_R ]
Sections:
- Section: .bar
- Section: .zed
VAddr: 0x1001
Sections:
- Name: .foo
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Size: 0x1
Address: 0x1000
- Name: .bar
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Size: 0x1
- Name: .zed
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC ]
Size: 0x1
ShOffset: 0x0
## Check how we dump segments which contain empty sections.
# RUN: yaml2obj --docnum=7 %s -o %t7
## Show the layout of the object before we dump it using obj2yaml.
## Notes: 1) '.empty.foo', '.empty.bar1' and '.bar' have the same file offset, but '.empty.foo'
## has a VA that is outside of the segment, hence we should not include it in it.
## 2) '.bar1' ends at 0x79, which is the starting file offset of both '.empty.bar2'
## and '.empty.zed'. We should only include '.empty.bar2', because the VA of the
## '.empty.zed' section is outside the segment's virtual space.
# RUN: llvm-readelf -sections %t7 | FileCheck %s --check-prefix=ZERO-SIZE-MAPPING
# ZERO-SIZE-MAPPING: Section Headers:
# ZERO-SIZE-MAPPING-NEXT: [Nr] Name Type Address Off Size
# ZERO-SIZE-MAPPING: [ 1] .empty.foo PROGBITS 0000000000001000 000078 000000
# ZERO-SIZE-MAPPING-NEXT: [ 2] .empty.bar1 PROGBITS 0000000000002000 000078 000000
# ZERO-SIZE-MAPPING-NEXT: [ 3] .bar PROGBITS 0000000000002000 000078 000001
# ZERO-SIZE-MAPPING-NEXT: [ 4] .empty.bar2 PROGBITS 0000000000002001 000079 000000
# ZERO-SIZE-MAPPING-NEXT: [ 5] .empty.zed PROGBITS 0000000000003000 000079 000000
# RUN: obj2yaml %t7 | FileCheck %s --check-prefix=ZERO-SIZE
# ZERO-SIZE: ProgramHeaders:
# ZERO-SIZE-NEXT: - Type: PT_LOAD
# ZERO-SIZE-NEXT: Flags: [ PF_W, PF_R ]
# ZERO-SIZE-NEXT: Sections:
# ZERO-SIZE-NEXT: - Section: .empty.bar1
# ZERO-SIZE-NEXT: - Section: .bar
# ZERO-SIZE-NEXT: - Section: .empty.bar2
# ZERO-SIZE-NEXT: VAddr: 0x0000000000002000
# ZERO-SIZE-NEXT: Sections:
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
Sections:
- Section: .bar
VAddr: 0x2000
Sections:
- Name: .empty.foo
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x1000
- Name: .empty.bar1
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x2000
- Name: .bar
Type: SHT_PROGBITS
Flags: [ SHF_WRITE, SHF_ALLOC ]
Address: 0x2000
Size: 0x1
- Name: .empty.bar2
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x2001
- Name: .empty.zed
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x3000
## Check how we dump a segment when we have sections that are outside of the virtual
## address space of a segment, but inside its file space. We do not include such sections
## in a segment when they are at the edges of a segment, because this is a normal case and
## it may mean they belong to a different segment.
# RUN: yaml2obj --docnum=8 %s -o %t8
# RUN: obj2yaml %t8 | FileCheck %s --check-prefix=BROKEN-VA
# BROKEN-VA: ProgramHeaders:
# BROKEN-VA-NEXT: - Type: PT_LOAD
# BROKEN-VA-NEXT: Flags: [ PF_W, PF_R ]
# BROKEN-VA-NEXT: Sections:
# BROKEN-VA-NEXT: - Section: .empty_middle
# BROKEN-VA-NEXT: VAddr: 0x0000000000001000
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_W, PF_R ]
VAddr: 0x1000
Sections:
- Section: .empty_begin
- Section: .empty_middle
- Section: .empty_end
Sections:
- Name: .empty_begin
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0xFEFEFEFE
- Type: Fill
Pattern: "00"
Size: 1
Name: begin
- Name: .empty_middle
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0xFEFEFEFE
- Type: Fill
Pattern: "00"
Size: 1
- Name: .empty_end
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0xFEFEFEFE