llvm.org GIT mirror llvm / 595a448
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. 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@317622 91177308-0d34-0410-b5e6-96231b3b80d8 Dave Lee 1 year, 11 months ago
3 changed file(s) with 72 addition(s) and 39 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
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;
79 assert(!lookup(Name, Idx) && "Expected section not found in index");
80 return Idx;
81 }
82 unsigned size() const { return Map.size(); }
7683 };
7784 } // end anonymous namespace
7885
143150 ContiguousBlobAccumulator &CBA);
144151
145152 // - 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; }
153 // - symbol table (.symtab) (defaults to third to last)
154 // - string table (.strtab) (defaults to second to last)
155 // - section header string table (.shstrtab) (defaults to last)
156 unsigned getDotSymTabSecNo() const { return SN2I.get(".symtab"); }
157 unsigned getDotStrTabSecNo() const { return SN2I.get(".strtab"); }
158 unsigned getDotShStrTabSecNo() const { return SN2I.get(".shstrtab"); }
159 unsigned getSectionCount() const { return SN2I.size() + 1; }
153160
154161 ELFState(const ELFYAML::Object &D) : Doc(D) {}
155162
156163 public:
157164 static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc);
158165 };
166
167 static const char * const ImplicitSecNames[] = {".symtab", ".strtab", ".shstrtab"};
159168 } // end anonymous namespace
160169
161170 template
210219 zero(SHeader);
211220 SHeaders.push_back(SHeader);
212221
213 for (const auto &Sec : Doc.Sections)
214 DotShStrtab.add(Sec->Name);
215 DotShStrtab.finalize();
216
217222 for (const auto &Sec : Doc.Sections) {
218223 zero(SHeader);
219224 SHeader.sh_name = DotShStrtab.getOffset(Sec->Name);
546551 }
547552
548553 template bool ELFState::buildSectionIndex() {
549 SN2I.addName(".symtab", getDotSymTabSecNo());
550 SN2I.addName(".strtab", getDotStrTabSecNo());
551 SN2I.addName(".shstrtab", getDotShStrTabSecNo());
552
553554 for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
554555 StringRef Name = Doc.Sections[i]->Name;
555556 if (Name.empty())
560561 << "' at YAML section number " << i << ".\n";
561562 return false;
562563 }
563 }
564 DotShStrtab.add(Name);
565 }
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;
624 SHeaders.reserve(State.SN2I.size());
617625 if(!State.initSectionHeaders(SHeaders, CBA))
618626 return 1;
619627
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);
628 // Populate SHeaders with implicit sections not present in the Doc
629 for (const auto &Name : ImplicitSecNames)
630 if (State.SN2I.get(Name) >= SHeaders.size())
631 SHeaders.push_back({});
632
633 // Initialize the implicit sections
634 auto Index = State.SN2I.get(".symtab");
635 State.initSymtabSectionHeader(SHeaders[Index], CBA);
636 Index = State.SN2I.get(".strtab");
637 State.initStrtabSectionHeader(SHeaders[Index], ".strtab", State.DotStrtab, CBA);
638 Index = State.SN2I.get(".shstrtab");
639 State.initStrtabSectionHeader(SHeaders[Index], ".shstrtab", State.DotShStrtab, CBA);
636640
637641 // Now we can decide segment offsets
638642 State.setProgramHeaderLayout(PHeaders, SHeaders);