summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/ObjectYAML/ELFYAML.h1
-rw-r--r--llvm/lib/ObjectYAML/ELFYAML.cpp1
-rw-r--r--llvm/test/tools/yaml2obj/dynamic-section-raw-content.yaml44
-rw-r--r--llvm/tools/yaml2obj/yaml2elf.cpp24
4 files changed, 66 insertions, 4 deletions
diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index c7f517a4b65..91c37ece0d8 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -141,6 +141,7 @@ struct Section {
struct DynamicSection : Section {
std::vector<DynamicEntry> Entries;
+ Optional<yaml::BinaryRef> Content;
DynamicSection() : Section(SectionKind::Dynamic) {}
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index e51454cb759..b2b69d5c30e 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -855,6 +855,7 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
commonSectionMapping(IO, Section);
IO.mapOptional("Entries", Section.Entries);
+ IO.mapOptional("Content", Section.Content);
}
static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
diff --git a/llvm/test/tools/yaml2obj/dynamic-section-raw-content.yaml b/llvm/test/tools/yaml2obj/dynamic-section-raw-content.yaml
new file mode 100644
index 00000000000..37af06755a9
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/dynamic-section-raw-content.yaml
@@ -0,0 +1,44 @@
+# Show that yaml2obj can handle a dynamic section with raw content instead of
+# entries. Also show that it rejects raw content when entries are also provided.
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readobj -x .dynamic --sections %t1 | FileCheck %s --check-prefix=RAW
+
+# RAW: Name: .dynamic
+# RAW-NEXT: Type: SHT_DYNAMIC
+# RAW-NEXT: Flags [
+# RAW-NEXT: ]
+# RAW-NEXT: Address:
+# RAW-NEXT: Offset:
+# RAW-NEXT: Size: 5
+
+# RAW: Hex dump of section '.dynamic':
+# RAW-NEXT: 0x00000000 01234567 89 {{.*}}
+
+# RUN: not yaml2obj --docnum=2 %s -o %t2 2>&1 | FileCheck %s --check-prefix=ERR
+# ERR: Cannot specify both raw content and explicit entries for dynamic section '.dynamic'.
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Content: "0123456789"
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+Sections:
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Content: "0123456789"
+ Entries:
+ - Tag: DT_STRSZ
+ Value: 0
diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp
index 351b7347653..d651c92dd65 100644
--- a/llvm/tools/yaml2obj/yaml2elf.cpp
+++ b/llvm/tools/yaml2obj/yaml2elf.cpp
@@ -169,7 +169,7 @@ class ELFState {
bool writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::MipsABIFlags &Section,
ContiguousBlobAccumulator &CBA);
- void writeSectionContent(Elf_Shdr &SHeader,
+ bool writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::DynamicSection &Section,
ContiguousBlobAccumulator &CBA);
bool hasDynamicSymbols() const;
@@ -309,7 +309,8 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
// so just to setup the section offset.
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
} else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) {
- writeSectionContent(SHeader, *S, CBA);
+ if (!writeSectionContent(SHeader, *S, CBA))
+ return false;
} else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec.get())) {
writeSectionContent(SHeader, *S, CBA);
} else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
@@ -713,7 +714,7 @@ bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
}
template <class ELFT>
-void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
const ELFYAML::DynamicSection &Section,
ContiguousBlobAccumulator &CBA) {
typedef typename ELFT::uint uintX_t;
@@ -721,7 +722,18 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
"Section type is not SHT_DYNAMIC");
- SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size();
+ if (!Section.Entries.empty() && Section.Content) {
+ WithColor::error()
+ << "Cannot specify both raw content and explicit entries "
+ "for dynamic section '"
+ << Section.Name << "'.\n";
+ return false;
+ }
+
+ if (Section.Content)
+ SHeader.sh_size = Section.Content->binary_size();
+ else
+ SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size();
if (Section.EntSize)
SHeader.sh_entsize = *Section.EntSize;
else
@@ -732,6 +744,10 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
support::endian::write<uintX_t>(OS, DE.Tag, ELFT::TargetEndianness);
support::endian::write<uintX_t>(OS, DE.Val, ELFT::TargetEndianness);
}
+ if (Section.Content)
+ Section.Content->writeAsBinary(OS);
+
+ return true;
}
template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
OpenPOWER on IntegriCloud