summaryrefslogtreecommitdiffstats
path: root/llvm/tools/yaml2obj/yaml2elf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/yaml2obj/yaml2elf.cpp')
-rw-r--r--llvm/tools/yaml2obj/yaml2elf.cpp94
1 files changed, 59 insertions, 35 deletions
diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp
index 8a53a1b2f48..a02ac8db2d0 100644
--- a/llvm/tools/yaml2obj/yaml2elf.cpp
+++ b/llvm/tools/yaml2obj/yaml2elf.cpp
@@ -358,13 +358,49 @@ static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) {
return Symbols.size();
}
+static uint64_t writeRawSectionData(raw_ostream &OS,
+ const ELFYAML::RawContentSection &RawSec) {
+ size_t ContentSize = 0;
+ if (RawSec.Content) {
+ RawSec.Content->writeAsBinary(OS);
+ ContentSize = RawSec.Content->binary_size();
+ }
+
+ if (!RawSec.Size)
+ return ContentSize;
+
+ OS.write_zeros(*RawSec.Size - ContentSize);
+ return *RawSec.Size;
+}
+
template <class ELFT>
void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
SymtabType STType,
ContiguousBlobAccumulator &CBA,
ELFYAML::Section *YAMLSec) {
- zero(SHeader);
+
bool IsStatic = STType == SymtabType::Static;
+ const auto &Symbols = IsStatic ? Doc.Symbols : Doc.DynamicSymbols;
+
+ ELFYAML::RawContentSection *RawSec =
+ dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
+ if (RawSec && !Symbols.empty() && (RawSec->Content || RawSec->Size)) {
+ if (RawSec->Content)
+ WithColor::error() << "Cannot specify both `Content` and " +
+ (IsStatic ? Twine("`Symbols`")
+ : Twine("`DynamicSymbols`")) +
+ " for symbol table section '"
+ << RawSec->Name << "'.\n";
+ if (RawSec->Size)
+ WithColor::error() << "Cannot specify both `Size` and " +
+ (IsStatic ? Twine("`Symbols`")
+ : Twine("`DynamicSymbols`")) +
+ " for symbol table section '"
+ << RawSec->Name << "'.\n";
+ exit(1);
+ }
+
+ zero(SHeader);
SHeader.sh_name = DotShStrtab.getOffset(IsStatic ? ".symtab" : ".dynsym");
SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM;
@@ -382,13 +418,8 @@ void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
if (!IsStatic)
SHeader.sh_flags |= ELF::SHF_ALLOC;
- // One greater than symbol table index of the last local symbol.
- const auto &Symbols = IsStatic ? Doc.Symbols : Doc.DynamicSymbols;
-
// If the symbol table section is explicitly described in the YAML
// then we should set the fields requested.
- ELFYAML::RawContentSection *RawSec =
- dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
SHeader.sh_info =
RawSec ? (unsigned)RawSec->Info : findFirstNonGlobal(Symbols) + 1;
SHeader.sh_entsize = (YAMLSec && YAMLSec->EntSize)
@@ -397,26 +428,24 @@ void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8;
SHeader.sh_addr = YAMLSec ? (uint64_t)YAMLSec->Address : 0;
- if (RawSec && RawSec->Content.binary_size()) {
- RawSec->Content.writeAsBinary(
- CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign));
- SHeader.sh_size = RawSec->Size;
- } else {
- std::vector<Elf_Sym> Syms;
- {
- // Ensure STN_UNDEF is present
- Elf_Sym Sym;
- zero(Sym);
- Syms.push_back(Sym);
- }
-
- addSymbols(Symbols, Syms, IsStatic ? DotStrtab : DotDynstr);
+ auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+ if (RawSec && (RawSec->Content || RawSec->Size)) {
+ assert(Symbols.empty());
+ SHeader.sh_size = writeRawSectionData(OS, *RawSec);
+ return;
+ }
- writeArrayData(
- CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign),
- makeArrayRef(Syms));
- SHeader.sh_size = arrayDataSize(makeArrayRef(Syms));
+ std::vector<Elf_Sym> Syms;
+ {
+ // Ensure STN_UNDEF is present
+ Elf_Sym Sym;
+ zero(Sym);
+ Syms.push_back(Sym);
}
+
+ addSymbols(Symbols, Syms, IsStatic ? DotStrtab : DotDynstr);
+ writeArrayData(OS, makeArrayRef(Syms));
+ SHeader.sh_size = arrayDataSize(makeArrayRef(Syms));
}
template <class ELFT>
@@ -431,13 +460,12 @@ void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
ELFYAML::RawContentSection *RawSec =
dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
- if (RawSec && RawSec->Content.binary_size()) {
- RawSec->Content.writeAsBinary(
- CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign));
- SHeader.sh_size = RawSec->Size;
+
+ auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
+ if (RawSec && (RawSec->Content || RawSec->Size)) {
+ SHeader.sh_size = writeRawSectionData(OS, *RawSec);
} else {
- STB.write(
- CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign));
+ STB.write(OS);
SHeader.sh_size = STB.getSize();
}
@@ -569,12 +597,9 @@ template <class ELFT>
bool ELFState<ELFT>::writeSectionContent(
Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section,
ContiguousBlobAccumulator &CBA) {
- assert(Section.Size >= Section.Content.binary_size() &&
- "Section size and section content are inconsistent");
raw_ostream &OS =
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
- Section.Content.writeAsBinary(OS);
- OS.write_zeros(Section.Size - Section.Content.binary_size());
+ SHeader.sh_size = writeRawSectionData(OS, Section);
if (Section.EntSize)
SHeader.sh_entsize = *Section.EntSize;
@@ -582,7 +607,6 @@ bool ELFState<ELFT>::writeSectionContent(
SHeader.sh_entsize = sizeof(Elf_Relr);
else
SHeader.sh_entsize = 0;
- SHeader.sh_size = Section.Size;
SHeader.sh_info = Section.Info;
return true;
}
OpenPOWER on IntegriCloud