Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
lld/ELF/DWARF.cpp
Show All 20 Lines | |||||
#include "llvm/Object/ELFObjectFile.h" | #include "llvm/Object/ELFObjectFile.h" | ||||
using namespace llvm; | using namespace llvm; | ||||
using namespace llvm::object; | using namespace llvm::object; | ||||
using namespace lld; | using namespace lld; | ||||
using namespace lld::elf; | using namespace lld::elf; | ||||
template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) { | template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) { | ||||
for (InputSectionBase *sec : obj->getSections()) { | ArrayRef<typename ELFT::Shdr> objSections = | ||||
CHECK(obj->getObj().sections(), obj); | |||||
for (auto it : llvm::enumerate(obj->getSections())) { | |||||
InputSectionBase *sec = it.value(); | |||||
if (!sec) | if (!sec) | ||||
grimar: So, you need this to read the flags from the `sh_flags` field of a section header in the… | |||||
continue; | continue; | ||||
// In DWARF v5, a .debug_info in a COMDAT group may represent a type unit. | |||||
// Don't bother calling data() (which may uncompress the content) on it. | |||||
if (LLDDWARFSection *m = | if (LLDDWARFSection *m = | ||||
StringSwitch<LLDDWARFSection *>(sec->name) | StringSwitch<LLDDWARFSection *>(sec->name) | ||||
.Case(".debug_addr", &addrSection) | .Case(".debug_addr", &addrSection) | ||||
.Case(".debug_gnu_pubnames", &gnuPubnamesSection) | .Case(".debug_gnu_pubnames", &gnuPubnamesSection) | ||||
.Case(".debug_gnu_pubtypes", &gnuPubtypesSection) | .Case(".debug_gnu_pubtypes", &gnuPubtypesSection) | ||||
.Case(".debug_info", &infoSection) | |||||
.Case(".debug_loclists", &loclistsSection) | .Case(".debug_loclists", &loclistsSection) | ||||
.Case(".debug_ranges", &rangesSection) | .Case(".debug_ranges", &rangesSection) | ||||
.Case(".debug_rnglists", &rnglistsSection) | .Case(".debug_rnglists", &rnglistsSection) | ||||
.Case(".debug_str_offsets", &strOffsetsSection) | .Case(".debug_str_offsets", &strOffsetsSection) | ||||
.Case(".debug_line", &lineSection) | .Case(".debug_line", &lineSection) | ||||
.Default(nullptr)) { | .Default(nullptr)) { | ||||
m->Data = toStringRef(sec->data()); | m->Data = toStringRef(sec->data()); | ||||
m->sec = sec; | m->sec = sec; | ||||
continue; | continue; | ||||
} | } | ||||
if (sec->name == ".debug_abbrev") | if (sec->name == ".debug_abbrev") | ||||
abbrevSection = toStringRef(sec->data()); | abbrevSection = toStringRef(sec->data()); | ||||
else if (sec->name == ".debug_str") | else if (sec->name == ".debug_str") | ||||
strSection = toStringRef(sec->data()); | strSection = toStringRef(sec->data()); | ||||
else if (sec->name == ".debug_line_str") | else if (sec->name == ".debug_line_str") | ||||
lineStrSection = toStringRef(sec->data()); | lineStrSection = toStringRef(sec->data()); | ||||
else if (sec->name == ".debug_info" && | |||||
!(objSections[it.index()].sh_flags & ELF::SHF_GROUP)) { | |||||
// In DWARF v5, -fdebug-types-section places type units in .debug_info | |||||
// sections in COMDAT groups. They are not compile units and thus should | |||||
// be ignored. If we place compile units in COMDAT groups in the future, | |||||
// we will need to perform a lightweight parsing. We drop the SHF_GROUP | |||||
// flag when the InputSection was created, so we need to retrieve sh_flags | |||||
// from the ELF section header. | |||||
infoSection.Data = toStringRef(sec->data()); | |||||
infoSection.sec = sec; | |||||
} | |||||
} | } | ||||
} | } | ||||
namespace { | namespace { | ||||
template <class RelTy> struct LLDRelocationResolver { | template <class RelTy> struct LLDRelocationResolver { | ||||
// In the ELF ABIs, S sepresents the value of the symbol in the relocation | // In the ELF ABIs, S sepresents the value of the symbol in the relocation | ||||
// entry. For Rela, the addend is stored as part of the relocation entry. | // entry. For Rela, the addend is stored as part of the relocation entry. | ||||
static uint64_t resolve(object::RelocationRef ref, uint64_t s, | static uint64_t resolve(object::RelocationRef ref, uint64_t s, | ||||
▲ Show 20 Lines • Show All 62 Lines • Show Last 20 Lines |
So, you need this to read the flags from the sh_flags field of a section header in the initial object.
And you can't just use sec->flags, because we drop the SHF_GROUP flag much earlier.
I do not know a simpler way to access initial flags. Though probably it worth adding an assert to check that the number
of sections in obj->getObj().sections() == the number of them in obj->getSections() and a comment
about SHT_GROUP flag? That way we will not forget to simplify this loop back later when will stop relying on SHF_GROUP flag.