llvm.org GIT mirror llvm / 9fd7184
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 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@317646 91177308-0d34-0410-b5e6-96231b3b80d8 Dave Lee 1 year, 11 months ago
4 changed file(s) with 86 addition(s) and 38 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
2
3 !ELF
4 FileHeader:
5 Class: ELFCLASS64
6 Data: ELFDATA2LSB
7 Type: ET_EXEC
8 Machine: EM_X86_64
9 Sections:
10 - Type: SHT_PROGBITS
11 - Name: .text
12 Type: SHT_PROGBITS
13 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
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 assert(!missing && "Expected section not found in index");
81 return Idx;
82 }
83 unsigned size() const { return Map.size(); }
7684 };
7785 } // end anonymous namespace
7886
143151 ContiguousBlobAccumulator &CBA);
144152
145153 // - 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; }
154 // - symbol table (.symtab) (defaults to third to last)
155 // - string table (.strtab) (defaults to second to last)
156 // - section header string table (.shstrtab) (defaults to last)
157 unsigned getDotSymTabSecNo() const { return SN2I.get(".symtab"); }
158 unsigned getDotStrTabSecNo() const { return SN2I.get(".strtab"); }
159 unsigned getDotShStrTabSecNo() const { return SN2I.get(".shstrtab"); }
160 unsigned getSectionCount() const { return SN2I.size() + 1; }
153161
154162 ELFState(const ELFYAML::Object &D) : Doc(D) {}
155163
156164 public:
157165 static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc);
158166 };
167
168 static const char * const ImplicitSecNames[] = {".symtab", ".strtab", ".shstrtab"};
159169 } // end anonymous namespace
160170
161171 template
210220 zero(SHeader);
211221 SHeaders.push_back(SHeader);
212222
213 for (const auto &Sec : Doc.Sections)
214 DotShStrtab.add(Sec->Name);
215 DotShStrtab.finalize();
216
217223 for (const auto &Sec : Doc.Sections) {
218224 zero(SHeader);
219225 SHeader.sh_name = DotShStrtab.getOffset(Sec->Name);
546552 }
547553
548554 template bool ELFState::buildSectionIndex() {
549 SN2I.addName(".symtab", getDotSymTabSecNo());
550 SN2I.addName(".strtab", getDotStrTabSecNo());
551 SN2I.addName(".shstrtab", getDotShStrTabSecNo());
552
553555 for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
554556 StringRef Name = Doc.Sections[i]->Name;
557 DotShStrtab.add(Name);
555558 if (Name.empty())
556559 continue;
557560 // "+ 1" to take into account the SHT_NULL entry.
561564 return false;
562565 }
563566 }
567
568 auto SecNo = 1 + Doc.Sections.size();
569 // Add special sections after input sections, if necessary.
570 for (const auto &Name : ImplicitSecNames)
571 if (!SN2I.addName(Name, SecNo)) {
572 // Account for this section, since it wasn't in the Doc
573 ++SecNo;
574 DotShStrtab.add(Name);
575 }
576
577 DotShStrtab.finalize();
564578 return true;
565579 }
566580
607621 Header.e_shentsize * Header.e_shnum;
608622 ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
609623
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
616624 std::vector SHeaders;
625 SHeaders.reserve(State.SN2I.size());
617626 if(!State.initSectionHeaders(SHeaders, CBA))
618627 return 1;
619628
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);
629 // Populate SHeaders with implicit sections not present in the Doc
630 for (const auto &Name : ImplicitSecNames)
631 if (State.SN2I.get(Name) >= SHeaders.size())
632 SHeaders.push_back({});
633
634 // Initialize the implicit sections
635 auto Index = State.SN2I.get(".symtab");
636 State.initSymtabSectionHeader(SHeaders[Index], CBA);
637 Index = State.SN2I.get(".strtab");
638 State.initStrtabSectionHeader(SHeaders[Index], ".strtab", State.DotStrtab, CBA);
639 Index = State.SN2I.get(".shstrtab");
640 State.initStrtabSectionHeader(SHeaders[Index], ".shstrtab", State.DotShStrtab, CBA);
636641
637642 // Now we can decide segment offsets
638643 State.setProgramHeaderLayout(PHeaders, SHeaders);