Skip to content

Commit 6861658

Browse files
committed
[llvm-objcopy][ELF] Avoid reordering section headers
As for now, llvm-objcopy sorts section headers according to the offsets of the sections in the input file. That can corrupt section references in the dynamic symbol table because it is a loadable section and as such is not updated by the tool. Even though the section references are not required for loading the binary correctly, they are still handy for a user who analyzes the file. While the patch removes global reordering of section headers, it layouts the sections in the same way as before, i.e. according to their original offsets. All that helps the output file to resemble the input better. Note that the patch removes sorting SHT_GROUP sections to the start of the list, which was introduced in D62620 in order to ensure that they come before the group members, along with the corresponding test. The original issue was caused by the sorting of section headers, so dropping the sorting also resolves the issue. Differential Revision: https://reviews.llvm.org/D107653
1 parent a1ef81d commit 6861658

12 files changed

+346
-190
lines changed

llvm/test/tools/llvm-objcopy/ELF/drawf-fission.test renamed to llvm/test/tools/llvm-objcopy/ELF/dwarf-fission.test

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,36 @@
88

99
#DWARF: SectionHeaderCount: 8
1010

11+
#DWARF: Name: .strtab
1112
#DWARF: Name: .debug_loc.dwo
1213
#DWARF: Name: .debug_str.dwo
1314
#DWARF: Name: .debug_str_offsets.dwo
1415
#DWARF: Name: .debug_info.dwo
1516
#DWARF: Name: .debug_abbrev.dwo
1617
#DWARF: Name: .debug_line.dwo
17-
#DWARF: Name: .strtab
1818

1919
#STRIP: SectionHeaderCount: 24
2020

21+
#STRIP: Name: .strtab
2122
#STRIP: Name: .text
23+
#STRIP: Name: .rela.text
2224
#STRIP: Name: .rodata.str1.1
2325
#STRIP: Name: .debug_str
2426
#STRIP: Name: .debug_abbrev
2527
#STRIP: Name: .debug_info
28+
#STRIP: Name: .rela.debug_info
2629
#STRIP: Name: .debug_ranges
2730
#STRIP: Name: .debug_macinfo
2831
#STRIP: Name: .debug_addr
32+
#STRIP: Name: .rela.debug_addr
2933
#STRIP: Name: .debug_pubnames
34+
#STRIP: Name: .rela.debug_pubnames
3035
#STRIP: Name: .debug_pubtypes
36+
#STRIP: Name: .rela.debug_pubtypes
3137
#STRIP: Name: .comment
3238
#STRIP: Name: .note.GNU-stack
3339
#STRIP: Name: .debug_frame
34-
#STRIP: Name: .debug_line
35-
#STRIP: Name: .symtab
36-
#STRIP: Name: .rela.text
37-
#STRIP: Name: .rela.debug_info
38-
#STRIP: Name: .rela.debug_addr
39-
#STRIP: Name: .rela.debug_pubnames
40-
#STRIP: Name: .rela.debug_pubtypes
4140
#STRIP: Name: .rela.debug_frame
41+
#STRIP: Name: .debug_line
4242
#STRIP: Name: .rela.debug_line
43-
#STRIP: Name: .strtab
43+
#STRIP: Name: .symtab
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: llvm-objcopy %t %t2
3+
# RUN: llvm-readobj --dyn-syms %t2 | FileCheck %s
4+
5+
## This checks that section references in the dynamic symbol table are not
6+
## corrupted after processing a file where the sequence of section headers does
7+
## not follow the order of their offsets. The tool avoids updating loadable
8+
## sections, so, the content of the dynamic symbol table stays intact and the
9+
## used section indices are preserved. In this test, the section 'dummy' comes
10+
## first while having the offset after all other sections. If the section
11+
## headers were sorted by their offsets by the tool, what it did before, the
12+
## index of the '.text' section would change from '2' to '1', which resulted
13+
## in an incorrect reference in the corresponding dynamic symbol 'foo'.
14+
15+
# CHECK: Name: foo
16+
# CHECK-NEXT: Value:
17+
# CHECK-NEXT: Size:
18+
# CHECK-NEXT: Binding:
19+
# CHECK-NEXT: Type:
20+
# CHECK-NEXT: Other:
21+
# CHECK-NEXT: Section: .text
22+
23+
!ELF
24+
FileHeader:
25+
Class: ELFCLASS64
26+
Data: ELFDATA2LSB
27+
Type: ET_DYN
28+
Machine: EM_X86_64
29+
ProgramHeaders:
30+
- Type: PT_LOAD
31+
Flags: [ PF_X, PF_R ]
32+
FirstSec: .text
33+
LastSec: .text
34+
Align: 0x1000
35+
Sections:
36+
- Name: .text
37+
Type: SHT_PROGBITS
38+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
39+
AddressAlign: 0x4
40+
Offset: 0x1000
41+
Content: 0000000000000000
42+
- Name: .dynsym
43+
Type: SHT_DYNSYM
44+
Flags: [ SHF_ALLOC ]
45+
Link: .dynstr
46+
- Name: .dynstr
47+
Type: SHT_STRTAB
48+
Flags: [ SHF_ALLOC ]
49+
- Name: dummy
50+
Type: SHT_PROGBITS
51+
Flags: [ SHF_ALLOC ]
52+
Offset: 0x1100
53+
- Type: SectionHeaderTable
54+
Sections:
55+
## 'dummy' comes before '.text' in the section header table despite its offset
56+
## is larger.
57+
- Name: dummy
58+
- Name: .text
59+
- Name: .dynsym
60+
- Name: .dynstr
61+
- Name: .shstrtab
62+
- Name: .strtab
63+
DynamicSymbols:
64+
- Name: foo
65+
Type: STT_FUNC
66+
Section: .text
67+
Binding: STB_GLOBAL
68+
Value: 0x0
69+
Size: 0x8

llvm/test/tools/llvm-objcopy/ELF/group-reorder.test

Lines changed: 0 additions & 65 deletions
This file was deleted.

llvm/test/tools/llvm-objcopy/ELF/ihex-reader.test

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,62 @@
44
# RUN: llvm-objcopy -I ihex -O elf32-i386 %t.hex %t2
55
# RUN: llvm-readobj --section-headers %t2 | FileCheck %s
66

7-
# CHECK: Index: 1
8-
# CHECK-NEXT: Name: .sec1
7+
# CHECK: Name: .sec1
98
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
109
# CHECK-NEXT: Flags [ (0x3)
1110
# CHECK-NEXT: SHF_ALLOC (0x2)
1211
# CHECK-NEXT: SHF_WRITE (0x1)
1312
# CHECK-NEXT: ]
1413
# CHECK-NEXT: Address: 0x0
15-
# CHECK-NEXT: Offset: 0x34
14+
# CHECK-NEXT: Offset:
1615
# CHECK-NEXT: Size: 21
1716
# CHECK-NEXT: Link: 0
1817
# CHECK-NEXT: Info: 0
1918
# CHECK-NEXT: AddressAlignment: 1
2019
# CHECK-NEXT: EntrySize: 0
2120

22-
# CHECK: Index: 2
23-
# CHECK-NEXT: Name: .sec2
21+
# CHECK: Name: .sec2
2422
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
2523
# CHECK-NEXT: Flags [ (0x3)
2624
# CHECK-NEXT: SHF_ALLOC (0x2)
2725
# CHECK-NEXT: SHF_WRITE (0x1)
2826
# CHECK-NEXT: ]
2927
# CHECK-NEXT: Address: 0xFFF8
30-
# CHECK-NEXT: Offset: 0x49
28+
# CHECK-NEXT: Offset:
3129
# CHECK-NEXT: Size: 11
3230
# CHECK-NEXT: Link: 0
3331
# CHECK-NEXT: Info: 0
3432
# CHECK-NEXT: AddressAlignment: 1
3533
# CHECK-NEXT: EntrySize: 0
3634

37-
# CHECK: Index: 3
38-
# CHECK-NEXT: Name: .sec3
35+
# CHECK: Name: .sec3
3936
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
4037
# CHECK-NEXT: Flags [ (0x3)
4138
# CHECK-NEXT: SHF_ALLOC (0x2)
4239
# CHECK-NEXT: SHF_WRITE (0x1)
4340
# CHECK-NEXT: ]
4441
# CHECK-NEXT: Address: 0x10100
45-
# CHECK-NEXT: Offset: 0x54
42+
# CHECK-NEXT: Offset:
4643
# CHECK-NEXT: Size: 4
4744
# CHECK-NEXT: Link: 0
4845
# CHECK-NEXT: Info: 0
4946
# CHECK-NEXT: AddressAlignment: 1
5047
# CHECK-NEXT: EntrySize: 0
5148

52-
# CHECK: Index: 4
53-
# CHECK-NEXT: Name: .sec4
49+
# CHECK: Name: .sec4
5450
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
5551
# CHECK-NEXT: Flags [ (0x3)
5652
# CHECK-NEXT: SHF_ALLOC (0x2)
5753
# CHECK-NEXT: SHF_WRITE (0x1)
5854
# CHECK-NEXT: ]
5955
# CHECK-NEXT: Address: 0x10FFF8
60-
# CHECK-NEXT: Offset: 0x58
56+
# CHECK-NEXT: Offset:
6157
# CHECK-NEXT: Size: 11
6258
# CHECK-NEXT: Link: 0
6359
# CHECK-NEXT: Info: 0
6460
# CHECK-NEXT: AddressAlignment: 1
6561
# CHECK-NEXT: EntrySize: 0
66-
62+
6763
## Check section contents.
6864
# RUN: llvm-objcopy -O binary --only-section=.text %t %t.text
6965
# RUN: llvm-objcopy -O binary --only-section=.sec1 %t2 %t2.sec1
@@ -82,37 +78,34 @@
8278
# RUN: llvm-objcopy -I ihex -O elf32-i386 %p/Inputs/sections.hex %t-raw
8379
# RUN: llvm-readobj --section-headers %t-raw | FileCheck %s --check-prefix=RAW
8480

85-
# RAW: Index: 1
86-
# RAW-NEXT: Name: .sec1
81+
# RAW: Name: .sec1
8782
# RAW-NEXT: Type: SHT_PROGBITS (0x1)
8883
# RAW-NEXT: Flags [ (0x3)
8984
# RAW-NEXT: SHF_ALLOC (0x2)
9085
# RAW-NEXT: SHF_WRITE (0x1)
9186
# RAW-NEXT: ]
9287
# RAW-NEXT: Address: 0x1FFF8
93-
# RAW-NEXT: Offset: 0x34
88+
# RAW-NEXT: Offset:
9489
# RAW-NEXT: Size: 11
9590

96-
# RAW: Index: 2
97-
# RAW-NEXT: Name: .sec2
91+
# RAW: Name: .sec2
9892
# RAW-NEXT: Type: SHT_PROGBITS (0x1)
9993
# RAW-NEXT: Flags [ (0x3)
10094
# RAW-NEXT: SHF_ALLOC (0x2)
10195
# RAW-NEXT: SHF_WRITE (0x1)
10296
# RAW-NEXT: ]
10397
# RAW-NEXT: Address: 0xFFFF8
104-
# RAW-NEXT: Offset: 0x3F
98+
# RAW-NEXT: Offset:
10599
# RAW-NEXT: Size: 11
106100

107-
# RAW: Index: 3
108-
# RAW-NEXT: Name: .sec3
101+
# RAW: Name: .sec3
109102
# RAW-NEXT: Type: SHT_PROGBITS (0x1)
110103
# RAW-NEXT: Flags [ (0x3)
111104
# RAW-NEXT: SHF_ALLOC (0x2)
112105
# RAW-NEXT: SHF_WRITE (0x1)
113106
# RAW-NEXT: ]
114107
# RAW-NEXT: Address: 0x1FFFF8
115-
# RAW-NEXT: Offset: 0x4A
108+
# RAW-NEXT: Offset:
116109
# RAW-NEXT: Size: 11
117110

118111
## Check section contents.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# RUN: yaml2obj %s -o %t
2+
# RUN: llvm-objcopy %t %t2
3+
# RUN: llvm-readobj --sections %t2 | FileCheck %s
4+
5+
## This checks that llvm-objcopy layouts sections in the order of their offsets
6+
## in the input file in spite of the order of section headers is different.
7+
8+
# CHECK: Index: 1
9+
# CHECK-NEXT: Name: foo
10+
# CHECK-NEXT: Type:
11+
# CHECK-NEXT: Flags [
12+
# CHECK-NEXT: SHF_ALLOC
13+
# CHECK-NEXT: ]
14+
# CHECK-NEXT: Address:
15+
# CHECK-NEXT: Offset: 0x50
16+
# CHECK: Index: 2
17+
# CHECK-NEXT: Name: bar
18+
# CHECK-NEXT: Type: SHT_PROGBITS
19+
# CHECK-NEXT: Flags [
20+
# CHECK-NEXT: SHF_ALLOC
21+
# CHECK-NEXT: ]
22+
# CHECK-NEXT: Address:
23+
# CHECK-NEXT: Offset: 0x40
24+
# CHECK: Index: 3
25+
# CHECK-NEXT: Name: baz
26+
# CHECK-NEXT: Type: SHT_PROGBITS
27+
# CHECK-NEXT: Flags [
28+
# CHECK-NEXT: SHF_ALLOC
29+
# CHECK-NEXT: ]
30+
# CHECK-NEXT: Address:
31+
# CHECK-NEXT: Offset: 0x48
32+
33+
--- !ELF
34+
FileHeader:
35+
Class: ELFCLASS64
36+
Data: ELFDATA2LSB
37+
Type: ET_REL
38+
Machine: EM_X86_64
39+
Sections:
40+
- Name: bar
41+
Type: SHT_PROGBITS
42+
Flags: [ SHF_ALLOC ]
43+
AddressAlign: 0x4
44+
Offset: 0x40
45+
Content: 0000000000000000
46+
- Name: baz
47+
Type: SHT_PROGBITS
48+
Flags: [ SHF_ALLOC ]
49+
AddressAlign: 0x4
50+
Offset: 0x48
51+
Content: 0000000000000000
52+
- Name: foo
53+
Type: SHT_PROGBITS
54+
Flags: [ SHF_ALLOC ]
55+
AddressAlign: 0x4
56+
Offset: 0x50
57+
Content: 0000000000000000
58+
- Type: SectionHeaderTable
59+
Sections:
60+
## Note: the order of section headers differs from their layout.
61+
- Name: foo
62+
- Name: bar
63+
- Name: baz
64+
- Name: .shstrtab
65+
- Name: .strtab

0 commit comments

Comments
 (0)