llvm.org GIT mirror llvm / 9ae2da6
[yaml2obj][ELF] Add support for setting alignment in program headers Sometimes program headers have larger alignments than any of the sections they contain. Currently yaml2obj can't produce such files. A bug recently appeared in llvm-objcopy that failed in such a case. I'd like to be able to add tests to llvm-objcopy for such cases. This change adds an optional alignment parameter to program headers that will be used instead of calculating the alignment. Differential Revision: https://reviews.llvm.org/D39130 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317139 91177308-0d34-0410-b5e6-96231b3b80d8 Jake Ehrlich 1 year, 11 months ago
4 changed file(s) with 77 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
8282 ELF_PF Flags;
8383 llvm::yaml::Hex64 VAddr;
8484 llvm::yaml::Hex64 PAddr;
85 Optional Align;
8586 std::vector Sections;
8687 };
8788
718718 IO.mapOptional("Sections", Phdr.Sections);
719719 IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
720720 IO.mapOptional("PAddr", Phdr.PAddr, Hex64(0));
721 IO.mapOptional("Align", Phdr.Align);
721722 }
722723
723724 namespace {
0 # RUN: yaml2obj %s -o %t
1 # RUN: llvm-readobj -program-headers %t | FileCheck %s
2
3 !ELF
4 FileHeader:
5 Class: ELFCLASS64
6 Data: ELFDATA2LSB
7 Type: ET_EXEC
8 Machine: EM_X86_64
9 Sections:
10 - Name: .text
11 Type: SHT_PROGBITS
12 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
13 AddressAlign: 0x0000000000000008
14 Content: "00000000"
15 - Name: .data
16 Type: SHT_PROGBITS
17 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
18 Content: "00000000"
19 AddressAlign: 0x0000000000000010
20 ProgramHeaders:
21 - Type: PT_LOAD
22 Flags: [ PF_X, PF_R ]
23 VAddr: 0xAAAA1030
24 PAddr: 0xFFFF1030
25 Align: 0x1000
26 Sections:
27 - Section: .text
28 - Type: PT_LOAD
29 Flags: [ PF_R ]
30 VAddr: 0xAAAA2040
31 PAddr: 0xFFFF2040
32 Align: 0x1000
33 Sections:
34 - Section: .data
35
36 #CHECK: ProgramHeaders [
37 #CHECK-NEXT: ProgramHeader {
38 #CHECK-NEXT: Type: PT_LOAD
39 #CHECK-NEXT: Offset: 0x230
40 #CHECK-NEXT: VirtualAddress: 0xAAAA1030
41 #CHECK-NEXT: PhysicalAddress: 0xFFFF1030
42 #CHECK-NEXT: FileSize: 4
43 #CHECK-NEXT: MemSize: 4
44 #CHECK-NEXT: Flags [
45 #CHECK-NEXT: PF_R
46 #CHECK-NEXT: PF_X
47 #CHECK-NEXT: ]
48 #CHECK-NEXT: Alignment: 4096
49 #CHECK-NEXT: }
50 #CHECK-NEXT: ProgramHeader {
51 #CHECK-NEXT: Type: PT_LOAD
52 #CHECK-NEXT: Offset: 0x240
53 #CHECK-NEXT: VirtualAddress: 0xAAAA2040
54 #CHECK-NEXT: PhysicalAddress: 0xFFFF2040
55 #CHECK-NEXT: FileSize: 4
56 #CHECK-NEXT: MemSize: 4
57 #CHECK-NEXT: Flags [
58 #CHECK-NEXT: PF_R
59 #CHECK-NEXT: ]
60 #CHECK-NEXT: Alignment: 4096
61 #CHECK-NEXT: }
62 #CHECK-NEXT:]
377377 }
378378
379379 // Set the alignment of the segment to be the same as the maximum alignment
380 // of the the sections with the same offset so that by default the segment
380 // of the sections with the same offset so that by default the segment
381381 // has a valid and sensible alignment.
382 PHeader.p_align = 1;
383 for (auto SecName : YamlPhdr.Sections) {
384 uint32_t Index = 0;
385 SN2I.lookup(SecName.Section, Index);
386 const auto &SHeader = SHeaders[Index];
387 if (SHeader.sh_offset == PHeader.p_offset)
388 PHeader.p_align = std::max(PHeader.p_align, SHeader.sh_addralign);
382 if (YamlPhdr.Align) {
383 PHeader.p_align = *YamlPhdr.Align;
384 } else {
385 PHeader.p_align = 1;
386 for (auto SecName : YamlPhdr.Sections) {
387 uint32_t Index = 0;
388 SN2I.lookup(SecName.Section, Index);
389 const auto &SHeader = SHeaders[Index];
390 if (SHeader.sh_offset == PHeader.p_offset)
391 PHeader.p_align = std::max(PHeader.p_align, SHeader.sh_addralign);
392 }
389393 }
390394 }
391395 }