Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/ObjectYAML/ELFEmitter.cpp
Show First 20 Lines • Show All 187 Lines • ▼ Show 20 Lines | template <class ELFT> class ELFState { | ||||
/// The future ".dynstr" section. | /// The future ".dynstr" section. | ||||
StringTableBuilder DotDynstr{StringTableBuilder::ELF}; | StringTableBuilder DotDynstr{StringTableBuilder::ELF}; | ||||
NameToIdxMap SN2I; | NameToIdxMap SN2I; | ||||
NameToIdxMap SymN2I; | NameToIdxMap SymN2I; | ||||
NameToIdxMap DynSymN2I; | NameToIdxMap DynSymN2I; | ||||
ELFYAML::Object &Doc; | ELFYAML::Object &Doc; | ||||
Optional<DWARFYAML::DWARFState> DWARFState; | |||||
StringSet<> ExcludedSectionHeaders; | StringSet<> ExcludedSectionHeaders; | ||||
uint64_t LocationCounter = 0; | uint64_t LocationCounter = 0; | ||||
bool HasError = false; | bool HasError = false; | ||||
yaml::ErrorHandler ErrHandler; | yaml::ErrorHandler ErrHandler; | ||||
void reportError(const Twine &Msg); | void reportError(const Twine &Msg); | ||||
void reportError(Error Err); | void reportError(Error Err); | ||||
▲ Show 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | if (!DocSections.insert(C->Name).second) | ||||
"' at YAML section/fill number " + Twine(I)); | "' at YAML section/fill number " + Twine(I)); | ||||
} | } | ||||
std::vector<StringRef> ImplicitSections; | std::vector<StringRef> ImplicitSections; | ||||
if (Doc.DynamicSymbols) | if (Doc.DynamicSymbols) | ||||
ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"}); | ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"}); | ||||
if (Doc.Symbols) | if (Doc.Symbols) | ||||
ImplicitSections.push_back(".symtab"); | ImplicitSections.push_back(".symtab"); | ||||
if (Doc.DWARF) | if (Doc.DWARF) { | ||||
for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) { | if (Expected<DWARFYAML::DWARFState> DSOrErr = | ||||
DWARFYAML::DWARFState::create(*Doc.DWARF)) { | |||||
DWARFState.emplace(*DSOrErr); | |||||
for (StringRef DebugSecName : | |||||
DWARFState->getDWARFData().getNonEmptySectionNames()) { | |||||
std::string SecName = ("." + DebugSecName).str(); | std::string SecName = ("." + DebugSecName).str(); | ||||
ImplicitSections.push_back(StringRef(SecName).copy(StringAlloc)); | ImplicitSections.push_back(StringRef(SecName).copy(StringAlloc)); | ||||
} | } | ||||
} else { | |||||
reportError(DSOrErr.takeError()); | |||||
} | |||||
} | |||||
ImplicitSections.insert(ImplicitSections.end(), {".strtab", ".shstrtab"}); | ImplicitSections.insert(ImplicitSections.end(), {".strtab", ".shstrtab"}); | ||||
// Insert placeholders for implicit sections that are not | // Insert placeholders for implicit sections that are not | ||||
// defined explicitly in YAML. | // defined explicitly in YAML. | ||||
for (StringRef SecName : ImplicitSections) { | for (StringRef SecName : ImplicitSections) { | ||||
if (DocSections.count(SecName)) | if (DocSections.count(SecName)) | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 557 Lines • ▼ Show 20 Lines | void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, | ||||
if (YAMLSec && YAMLSec->Flags) | if (YAMLSec && YAMLSec->Flags) | ||||
SHeader.sh_flags = *YAMLSec->Flags; | SHeader.sh_flags = *YAMLSec->Flags; | ||||
else if (Name == ".dynstr") | else if (Name == ".dynstr") | ||||
SHeader.sh_flags = ELF::SHF_ALLOC; | SHeader.sh_flags = ELF::SHF_ALLOC; | ||||
assignSectionAddress(SHeader, YAMLSec); | assignSectionAddress(SHeader, YAMLSec); | ||||
} | } | ||||
static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) { | static bool shouldEmitDWARF(const DWARFYAML::Data &DWARF, StringRef Name) { | ||||
SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames(); | SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames(); | ||||
return Name.consume_front(".") && DebugSecNames.count(Name); | return Name.consume_front(".") && DebugSecNames.count(Name); | ||||
} | } | ||||
template <class ELFT> | template <class ELFT> | ||||
Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, | Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, | ||||
const DWARFYAML::Data &DWARF, | const DWARFYAML::DWARFState &DS, | ||||
ContiguousBlobAccumulator &CBA) { | ContiguousBlobAccumulator &CBA) { | ||||
// We are unable to predict the size of debug data, so we request to write 0 | // We are unable to predict the size of debug data, so we request to write 0 | ||||
// bytes. This should always return us an output stream unless CBA is already | // bytes. This should always return us an output stream unless CBA is already | ||||
// in an error state. | // in an error state. | ||||
raw_ostream *OS = CBA.getRawOS(0); | raw_ostream *OS = CBA.getRawOS(0); | ||||
if (!OS) | if (!OS) | ||||
return 0; | return 0; | ||||
uint64_t BeginOffset = CBA.tell(); | uint64_t BeginOffset = CBA.tell(); | ||||
auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1)); | auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1)); | ||||
if (Error Err = EmitFunc(*OS, DWARF)) | if (Error Err = EmitFunc(*OS, DS)) | ||||
return std::move(Err); | return std::move(Err); | ||||
return CBA.tell() - BeginOffset; | return CBA.tell() - BeginOffset; | ||||
} | } | ||||
template <class ELFT> | template <class ELFT> | ||||
void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, | void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, | ||||
ContiguousBlobAccumulator &CBA, | ContiguousBlobAccumulator &CBA, | ||||
ELFYAML::Section *YAMLSec) { | ELFYAML::Section *YAMLSec) { | ||||
zero(SHeader); | zero(SHeader); | ||||
SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); | SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); | ||||
SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS; | SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS; | ||||
SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; | SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; | ||||
SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, | SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, | ||||
YAMLSec ? YAMLSec->Offset : None); | YAMLSec ? YAMLSec->Offset : None); | ||||
ELFYAML::RawContentSection *RawSec = | ELFYAML::RawContentSection *RawSec = | ||||
dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); | dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); | ||||
if (Doc.DWARF && shouldEmitDWARF(*Doc.DWARF, Name)) { | if (DWARFState && shouldEmitDWARF(DWARFState->getDWARFData(), Name)) { | ||||
if (RawSec && (RawSec->Content || RawSec->Size)) | if (RawSec && (RawSec->Content || RawSec->Size)) | ||||
reportError("cannot specify section '" + Name + | reportError("cannot specify section '" + Name + | ||||
"' contents in the 'DWARF' entry and the 'Content' " | "' contents in the 'DWARF' entry and the 'Content' " | ||||
"or 'Size' in the 'Sections' entry at the same time"); | "or 'Size' in the 'Sections' entry at the same time"); | ||||
else { | else { | ||||
if (Expected<uint64_t> ShSizeOrErr = | if (Expected<uint64_t> ShSizeOrErr = | ||||
emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA)) | emitDWARF<ELFT>(SHeader, Name, *DWARFState, CBA)) | ||||
SHeader.sh_size = *ShSizeOrErr; | SHeader.sh_size = *ShSizeOrErr; | ||||
else | else | ||||
reportError(ShSizeOrErr.takeError()); | reportError(ShSizeOrErr.takeError()); | ||||
} | } | ||||
} else if (RawSec) | } else if (RawSec) | ||||
SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); | SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); | ||||
else | else | ||||
llvm_unreachable("debug sections can only be initialized via the 'DWARF' " | llvm_unreachable("debug sections can only be initialized via the 'DWARF' " | ||||
▲ Show 20 Lines • Show All 919 Lines • Show Last 20 Lines |