Skip to content

Commit fd99780

Browse files
committed
[yaml2obj]Re-allow dynamic sections to have raw content
Recently, support was added to yaml2obj to allow dynamic sections to have a list of entries, to make it easier to write tests with dynamic sections. However, this change also removed the ability to provide custom contents to the dynamic section, making it hard to test malformed contents (e.g. because the section is not a valid size to contain an array of entries). This change reinstates this. An error is emitted if raw content and dynamic entries are both specified. Reviewed by: grimar, ruiu Differential Review: https://reviews.llvm.org/D58543 llvm-svn: 354770
1 parent 777e1cf commit fd99780

File tree

4 files changed

+66
-4
lines changed

4 files changed

+66
-4
lines changed

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ struct Section {
141141

142142
struct DynamicSection : Section {
143143
std::vector<DynamicEntry> Entries;
144+
Optional<yaml::BinaryRef> Content;
144145

145146
DynamicSection() : Section(SectionKind::Dynamic) {}
146147

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
855855
static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
856856
commonSectionMapping(IO, Section);
857857
IO.mapOptional("Entries", Section.Entries);
858+
IO.mapOptional("Content", Section.Content);
858859
}
859860

860861
static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Show that yaml2obj can handle a dynamic section with raw content instead of
2+
# entries. Also show that it rejects raw content when entries are also provided.
3+
4+
# RUN: yaml2obj --docnum=1 %s -o %t1
5+
# RUN: llvm-readobj -x .dynamic --sections %t1 | FileCheck %s --check-prefix=RAW
6+
7+
# RAW: Name: .dynamic
8+
# RAW-NEXT: Type: SHT_DYNAMIC
9+
# RAW-NEXT: Flags [
10+
# RAW-NEXT: ]
11+
# RAW-NEXT: Address:
12+
# RAW-NEXT: Offset:
13+
# RAW-NEXT: Size: 5
14+
15+
# RAW: Hex dump of section '.dynamic':
16+
# RAW-NEXT: 0x00000000 01234567 89 {{.*}}
17+
18+
# RUN: not yaml2obj --docnum=2 %s -o %t2 2>&1 | FileCheck %s --check-prefix=ERR
19+
# ERR: Cannot specify both raw content and explicit entries for dynamic section '.dynamic'.
20+
21+
--- !ELF
22+
FileHeader:
23+
Class: ELFCLASS64
24+
Data: ELFDATA2LSB
25+
Type: ET_EXEC
26+
Machine: EM_X86_64
27+
Sections:
28+
- Name: .dynamic
29+
Type: SHT_DYNAMIC
30+
Content: "0123456789"
31+
32+
--- !ELF
33+
FileHeader:
34+
Class: ELFCLASS64
35+
Data: ELFDATA2LSB
36+
Type: ET_EXEC
37+
Machine: EM_X86_64
38+
Sections:
39+
- Name: .dynamic
40+
Type: SHT_DYNAMIC
41+
Content: "0123456789"
42+
Entries:
43+
- Tag: DT_STRSZ
44+
Value: 0

llvm/tools/yaml2obj/yaml2elf.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ class ELFState {
169169
bool writeSectionContent(Elf_Shdr &SHeader,
170170
const ELFYAML::MipsABIFlags &Section,
171171
ContiguousBlobAccumulator &CBA);
172-
void writeSectionContent(Elf_Shdr &SHeader,
172+
bool writeSectionContent(Elf_Shdr &SHeader,
173173
const ELFYAML::DynamicSection &Section,
174174
ContiguousBlobAccumulator &CBA);
175175
bool hasDynamicSymbols() const;
@@ -309,7 +309,8 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
309309
// so just to setup the section offset.
310310
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
311311
} else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) {
312-
writeSectionContent(SHeader, *S, CBA);
312+
if (!writeSectionContent(SHeader, *S, CBA))
313+
return false;
313314
} else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec.get())) {
314315
writeSectionContent(SHeader, *S, CBA);
315316
} else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
@@ -713,15 +714,26 @@ bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
713714
}
714715

715716
template <class ELFT>
716-
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
717+
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
717718
const ELFYAML::DynamicSection &Section,
718719
ContiguousBlobAccumulator &CBA) {
719720
typedef typename ELFT::uint uintX_t;
720721

721722
assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
722723
"Section type is not SHT_DYNAMIC");
723724

724-
SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size();
725+
if (!Section.Entries.empty() && Section.Content) {
726+
WithColor::error()
727+
<< "Cannot specify both raw content and explicit entries "
728+
"for dynamic section '"
729+
<< Section.Name << "'.\n";
730+
return false;
731+
}
732+
733+
if (Section.Content)
734+
SHeader.sh_size = Section.Content->binary_size();
735+
else
736+
SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size();
725737
if (Section.EntSize)
726738
SHeader.sh_entsize = *Section.EntSize;
727739
else
@@ -732,6 +744,10 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
732744
support::endian::write<uintX_t>(OS, DE.Tag, ELFT::TargetEndianness);
733745
support::endian::write<uintX_t>(OS, DE.Val, ELFT::TargetEndianness);
734746
}
747+
if (Section.Content)
748+
Section.Content->writeAsBinary(OS);
749+
750+
return true;
735751
}
736752

737753
template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {

0 commit comments

Comments
 (0)