forked from OSchip/llvm-project
[BOLT] Strip debug sections by default
Summary: We used to ignore debug sections by default, but we kept them in the binary which led to invalid debug information in the output. It's better to strip debug info and print a warning to the user. Note: we are not updating debug info by default due to high memory requirements for large applications. (cherry picked from FBD15128947)
This commit is contained in:
parent
21ee0e98c7
commit
2b1523362e
|
@ -29,18 +29,16 @@ uint8_t *ExecutableFileMemoryManager::allocateSection(intptr_t Size,
|
|||
StringRef SectionName,
|
||||
bool IsCode,
|
||||
bool IsReadOnly) {
|
||||
// Register as note section (non-allocatable) if we recognize it as so
|
||||
for (auto &OverwriteName : RewriteInstance::SectionsToOverwrite) {
|
||||
if (SectionName == OverwriteName) {
|
||||
uint8_t *DataCopy = new uint8_t[Size];
|
||||
auto &Section = BC.registerOrUpdateNoteSection(SectionName,
|
||||
DataCopy,
|
||||
Size,
|
||||
Alignment);
|
||||
Section.setSectionID(SectionID);
|
||||
assert(!Section.isAllocatable() && "note sections cannot be allocatable");
|
||||
return DataCopy;
|
||||
}
|
||||
// Register a debug section as a note section.
|
||||
if (RewriteInstance::isDebugSection(SectionName)) {
|
||||
uint8_t *DataCopy = new uint8_t[Size];
|
||||
auto &Section = BC.registerOrUpdateNoteSection(SectionName,
|
||||
DataCopy,
|
||||
Size,
|
||||
Alignment);
|
||||
Section.setSectionID(SectionID);
|
||||
assert(!Section.isAllocatable() && "note sections cannot be allocatable");
|
||||
return DataCopy;
|
||||
}
|
||||
|
||||
uint8_t *Ret;
|
||||
|
|
|
@ -512,6 +512,7 @@ MCPlusBuilder *createMCPlusBuilder(const Triple::ArchType Arch,
|
|||
}
|
||||
|
||||
constexpr const char *RewriteInstance::SectionsToOverwrite[];
|
||||
constexpr const char *RewriteInstance::DebugSectionsToOverwrite[];
|
||||
|
||||
const std::string RewriteInstance::OrgSecPrefix = ".bolt.org";
|
||||
|
||||
|
@ -1720,6 +1721,7 @@ void RewriteInstance::readSpecialSections() {
|
|||
TimerGroupName, TimerGroupDesc, opts::TimeRewrite);
|
||||
|
||||
bool HasTextRelocations = false;
|
||||
bool HasDebugInfo = false;
|
||||
|
||||
// Process special sections.
|
||||
for (const auto &Section : InputFile->sections()) {
|
||||
|
@ -1733,9 +1735,16 @@ void RewriteInstance::readSpecialSections() {
|
|||
<< " @ 0x" << Twine::utohexstr(Section.getAddress()) << ":0x"
|
||||
<< Twine::utohexstr(Section.getAddress() + Section.getSize())
|
||||
<< "\n");
|
||||
if (isDebugSection(SectionName))
|
||||
HasDebugInfo = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (HasDebugInfo && !opts::UpdateDebugSections) {
|
||||
errs() << "BOLT-WARNING: debug info will be stripped from the binary. "
|
||||
"Use -update-debug-sections to keep it.\n";
|
||||
}
|
||||
|
||||
HasTextRelocations = (bool)BC->getUniqueSectionByName(".rela.text");
|
||||
LSDASection = BC->getUniqueSectionByName(".gcc_except_table");
|
||||
EHFrameSection = BC->getUniqueSectionByName(".eh_frame");
|
||||
|
@ -3763,8 +3772,7 @@ std::string RewriteInstance::getOutputSectionName(const ELFObjType *Obj,
|
|||
StringRef SectionName =
|
||||
cantFail(Obj->getSectionName(&Section), "cannot get section name");
|
||||
|
||||
if ((Section.sh_flags & ELF::SHF_ALLOC) &&
|
||||
willOverwriteSection(SectionName))
|
||||
if ((Section.sh_flags & ELF::SHF_ALLOC) && willOverwriteSection(SectionName))
|
||||
return OrgSecPrefix + SectionName.str();
|
||||
|
||||
return SectionName;
|
||||
|
@ -3868,6 +3876,10 @@ std::vector<ELFShdrTy> RewriteInstance::getOutputSections(
|
|||
StringRef SectionName =
|
||||
cantFail(Obj->getSectionName(&Section), "cannot get section name");
|
||||
|
||||
// Strip debug sections if not updating them.
|
||||
if (isDebugSection(SectionName) && !opts::UpdateDebugSections)
|
||||
continue;
|
||||
|
||||
auto BSec = BC->getUniqueSectionByName(SectionName);
|
||||
assert(BSec && "missing section info for non-allocatable section");
|
||||
|
||||
|
@ -4789,7 +4801,18 @@ bool RewriteInstance::willOverwriteSection(StringRef SectionName) {
|
|||
if (SectionName == OverwriteName)
|
||||
return true;
|
||||
}
|
||||
for (auto &OverwriteName : DebugSectionsToOverwrite) {
|
||||
if (SectionName == OverwriteName)
|
||||
return true;
|
||||
}
|
||||
|
||||
auto Section = BC->getUniqueSectionByName(SectionName);
|
||||
return Section && Section->isAllocatable() && Section->isFinalized();
|
||||
}
|
||||
|
||||
bool RewriteInstance::isDebugSection(StringRef SectionName) {
|
||||
if (SectionName.startswith(".debug_") || SectionName == ".gdb_index")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -259,11 +259,15 @@ private:
|
|||
bool shouldDisassemble(BinaryFunction &BF) const;
|
||||
|
||||
public:
|
||||
/// When updating debug info, these are the sections we overwrite.
|
||||
/// Standard ELF sections we overwrite.
|
||||
static constexpr const char *SectionsToOverwrite[] = {
|
||||
".shstrtab",
|
||||
".symtab",
|
||||
".strtab",
|
||||
};
|
||||
|
||||
/// Debug section to we overwrite while updating the debug info.
|
||||
static constexpr const char *DebugSectionsToOverwrite[] = {
|
||||
".debug_aranges",
|
||||
".debug_line",
|
||||
".debug_loc",
|
||||
|
@ -271,6 +275,9 @@ public:
|
|||
".gdb_index",
|
||||
};
|
||||
|
||||
/// Return true if the section holds debug information.
|
||||
static bool isDebugSection(StringRef SectionName);
|
||||
|
||||
using SectionPatchersType =
|
||||
std::map<std::string, std::unique_ptr<BinaryPatcher>>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue