llvm.org GIT mirror llvm / 9a5be1f
Reapply: Allow yaml2obj to order implicit sections for ELF Summary: This change allows yaml input to control the order of implicitly added sections (`.symtab`, `.strtab`, `.shstrtab`). The order is controlled by adding a placeholder section of the given name to the Sections field. This change is to support changes in D39582, where it is desirable to control the location of the `.dynsym` section. This reapplied version fixes: 1. use of a function call within an assert 2. failing lld test which has an unnamed section 3. incorrect section count when given an unnamed section Additionally, one more test to cover the unnamed section failure. Reviewers: compnerd, jakehehrlich Reviewed By: jakehehrlich Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39749 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317789 91177308-0d34-0410-b5e6-96231b3b80d8 Dave Lee 3 years ago
4 changed file(s) with 94 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
387387 #define ECase(X) IO.enumCase(Value, #X, ELF::X)
388388 ECase(SHT_NULL);
389389 ECase(SHT_PROGBITS);
390 // No SHT_SYMTAB. Use the top-level `Symbols` key instead.
390 ECase(SHT_SYMTAB);
391391 // FIXME: Issue a diagnostic with this information.
392392 ECase(SHT_STRTAB);
393393 ECase(SHT_RELA);
0 # Ensures that implicitly added sections can be ordered within Sections.
1 # RUN: yaml2obj %s -o %t
2 # RUN: llvm-readobj -sections %t | FileCheck %s
3
4 !ELF
5 FileHeader:
6 Class: ELFCLASS64
7 Data: ELFDATA2LSB
8 Type: ET_EXEC
9 Machine: EM_X86_64
10 Sections:
11 - Name: .text
12 Type: SHT_PROGBITS
13 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
14 - Name: .symtab
15 Type: SHT_SYMTAB
16 - Name: .data
17 Type: SHT_PROGBITS
18 Flags: [ SHF_ALLOC, SHF_WRITE ]
19 - Name: .shstrtab
20 Type: SHT_STRTAB
21 - Name: .strtab
22 Type: SHT_STRTAB
23
24 # CHECK: Name: .text
25 # CHECK: Name: .symtab
26 # CHECK: Name: .data
27 # CHECK: Name: .shstrtab
28 # CHECK: Name: .strtab
0 # Ensure yaml2obj doesn't crash on unnamed sections
1 # RUN: yaml2obj %s -o %t
2 # RUN: llvm-readobj -sections %t | FileCheck %s
3
4 !ELF
5 FileHeader:
6 Class: ELFCLASS64
7 Data: ELFDATA2LSB
8 Type: ET_EXEC
9 Machine: EM_X86_64
10 Sections:
11 - Type: SHT_PROGBITS
12 - Name: .text
13 Type: SHT_PROGBITS
14 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
15
16 # CHECK: Name: (
17 # CHECK-NEXT: Type: SHT_NULL
18 # CHECK: Name: (
19 # CHECK-NEXT: Type: SHT_PROGBITS
20 # CHECK: Name: .text
21 # CHECK-NEXT: Type: SHT_PROGBITS
7373 Idx = I->getValue();
7474 return false;
7575 }
76 /// asserts if name is not present in the map
77 unsigned get(StringRef Name) const {
78 unsigned Idx = 0;
79 auto missing = lookup(Name, Idx);
80 (void)missing;
81 assert(!missing && "Expected section not found in index");
82 return Idx;
83 }
84 unsigned size() const { return Map.size(); }
7685 };
7786 } // end anonymous namespace
7887
143152 ContiguousBlobAccumulator &CBA);
144153
145154 // - SHT_NULL entry (placed first, i.e. 0'th entry)
146 // - symbol table (.symtab) (placed third to last)
147 // - string table (.strtab) (placed second to last)
148 // - section header string table (.shstrtab) (placed last)
149 unsigned getDotSymTabSecNo() const { return Doc.Sections.size() + 1; }
150 unsigned getDotStrTabSecNo() const { return Doc.Sections.size() + 2; }
151 unsigned getDotShStrTabSecNo() const { return Doc.Sections.size() + 3; }
152 unsigned getSectionCount() const { return Doc.Sections.size() + 4; }
155 // - symbol table (.symtab) (defaults to third to last)
156 // - string table (.strtab) (defaults to second to last)
157 // - section header string table (.shstrtab) (defaults to last)
158 unsigned getDotSymTabSecNo() const { return SN2I.get(".symtab"); }
159 unsigned getDotStrTabSecNo() const { return SN2I.get(".strtab"); }
160 unsigned getDotShStrTabSecNo() const { return SN2I.get(".shstrtab"); }
161 unsigned getSectionCount() const { return SN2I.size() + 1; }
153162
154163 ELFState(const ELFYAML::Object &D) : Doc(D) {}
155164
156165 public:
157166 static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc);
158167 };
168
169 static const char * const ImplicitSecNames[] = {".symtab", ".strtab", ".shstrtab"};
159170 } // end anonymous namespace
160171
161172 template
210221 zero(SHeader);
211222 SHeaders.push_back(SHeader);
212223
213 for (const auto &Sec : Doc.Sections)
214 DotShStrtab.add(Sec->Name);
215 DotShStrtab.finalize();
216
217224 for (const auto &Sec : Doc.Sections) {
218225 zero(SHeader);
219226 SHeader.sh_name = DotShStrtab.getOffset(Sec->Name);
546553 }
547554
548555 template bool ELFState::buildSectionIndex() {
549 SN2I.addName(".symtab", getDotSymTabSecNo());
550 SN2I.addName(".strtab", getDotStrTabSecNo());
551 SN2I.addName(".shstrtab", getDotShStrTabSecNo());
552
553556 for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
554557 StringRef Name = Doc.Sections[i]->Name;
555 if (Name.empty())
556 continue;
558 DotShStrtab.add(Name);
557559 // "+ 1" to take into account the SHT_NULL entry.
558560 if (SN2I.addName(Name, i + 1)) {
559561 errs() << "error: Repeated section name: '" << Name
561563 return false;
562564 }
563565 }
566
567 auto SecNo = 1 + Doc.Sections.size();
568 // Add special sections after input sections, if necessary.
569 for (const auto &Name : ImplicitSecNames)
570 if (!SN2I.addName(Name, SecNo)) {
571 // Account for this section, since it wasn't in the Doc
572 ++SecNo;
573 DotShStrtab.add(Name);
574 }
575
576 DotShStrtab.finalize();
564577 return true;
565578 }
566579
607620 Header.e_shentsize * Header.e_shnum;
608621 ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
609622
610 // Doc might not contain .symtab, .strtab and .shstrtab sections,
611 // but we will emit them, so make sure to add them to ShStrTabSHeader.
612 State.DotShStrtab.add(".symtab");
613 State.DotShStrtab.add(".strtab");
614 State.DotShStrtab.add(".shstrtab");
615
616623 std::vector SHeaders;
617624 if(!State.initSectionHeaders(SHeaders, CBA))
618625 return 1;
619626
620 // .symtab section.
621 Elf_Shdr SymtabSHeader;
622 State.initSymtabSectionHeader(SymtabSHeader, CBA);
623 SHeaders.push_back(SymtabSHeader);
624
625 // .strtab string table header.
626 Elf_Shdr DotStrTabSHeader;
627 State.initStrtabSectionHeader(DotStrTabSHeader, ".strtab", State.DotStrtab,
628 CBA);
629 SHeaders.push_back(DotStrTabSHeader);
630
631 // .shstrtab string table header.
632 Elf_Shdr ShStrTabSHeader;
633 State.initStrtabSectionHeader(ShStrTabSHeader, ".shstrtab", State.DotShStrtab,
634 CBA);
635 SHeaders.push_back(ShStrTabSHeader);
627 // Populate SHeaders with implicit sections not present in the Doc
628 for (const auto &Name : ImplicitSecNames)
629 if (State.SN2I.get(Name) >= SHeaders.size())
630 SHeaders.push_back({});
631
632 // Initialize the implicit sections
633 auto Index = State.SN2I.get(".symtab");
634 State.initSymtabSectionHeader(SHeaders[Index], CBA);
635 Index = State.SN2I.get(".strtab");
636 State.initStrtabSectionHeader(SHeaders[Index], ".strtab", State.DotStrtab, CBA);
637 Index = State.SN2I.get(".shstrtab");
638 State.initStrtabSectionHeader(SHeaders[Index], ".shstrtab", State.DotShStrtab, CBA);
636639
637640 // Now we can decide segment offsets
638641 State.setProgramHeaderLayout(PHeaders, SHeaders);