forked from OSchip/llvm-project
Allow fetching source line, when multiple "AX" sections present
Differential revision: https://reviews.llvm.org/D26070 llvm-svn: 285680
This commit is contained in:
parent
251f6dd93d
commit
c4681203e1
|
@ -23,6 +23,7 @@
|
|||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/LTO/LTO.h"
|
||||
#include "llvm/MC/StringTableBuilder.h"
|
||||
#include "llvm/Object/ELFObjectFile.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
|
@ -36,13 +37,31 @@ using namespace lld::elf;
|
|||
|
||||
std::vector<InputFile *> InputFile::Pool;
|
||||
|
||||
template <class ELFT> DIHelper<ELFT>::DIHelper(elf::InputFile *F) {
|
||||
namespace {
|
||||
// In ELF object file all section addresses are zero. If we have multiple
|
||||
// .text sections (when using -ffunction-section or comdat group) then
|
||||
// LLVM DWARF parser will not be able to parse .debug_line correctly, unless
|
||||
// we assign each section some unique address. This callback method assigns
|
||||
// each section an address equal to its offset in ELF object file.
|
||||
class ObjectInfo : public LoadedObjectInfo {
|
||||
public:
|
||||
uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override {
|
||||
return static_cast<const ELFSectionRef &>(Sec).getOffset();
|
||||
}
|
||||
std::unique_ptr<LoadedObjectInfo> clone() const override {
|
||||
return std::unique_ptr<LoadedObjectInfo>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class ELFT> DIHelper<ELFT>::DIHelper(InputFile *F) {
|
||||
Expected<std::unique_ptr<object::ObjectFile>> Obj =
|
||||
object::ObjectFile::createObjectFile(F->MB);
|
||||
if (!Obj)
|
||||
return;
|
||||
|
||||
DWARFContextInMemory Dwarf(*Obj.get());
|
||||
ObjectInfo ObjInfo;
|
||||
DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo);
|
||||
DwarfLine.reset(new DWARFDebugLine(&Dwarf.getLineSection().Relocs));
|
||||
DataExtractor LineData(Dwarf.getLineSection().Data,
|
||||
ELFT::TargetEndianness == support::little,
|
||||
|
@ -55,7 +74,9 @@ template <class ELFT> DIHelper<ELFT>::DIHelper(elf::InputFile *F) {
|
|||
|
||||
template <class ELFT> DIHelper<ELFT>::~DIHelper() {}
|
||||
|
||||
template <class ELFT> std::string DIHelper<ELFT>::getLineInfo(uintX_t Offset) {
|
||||
template <class ELFT>
|
||||
std::string DIHelper<ELFT>::getLineInfo(InputSectionBase<ELFT> *S,
|
||||
uintX_t Offset) {
|
||||
if (!DwarfLine)
|
||||
return "";
|
||||
|
||||
|
@ -65,7 +86,12 @@ template <class ELFT> std::string DIHelper<ELFT>::getLineInfo(uintX_t Offset) {
|
|||
const DWARFDebugLine::LineTable *LineTbl = DwarfLine->getLineTable(0);
|
||||
if (!LineTbl)
|
||||
return "";
|
||||
LineTbl->getFileLineInfoForAddress(Offset, nullptr, Spec.FLIKind, LineInfo);
|
||||
|
||||
// Use fake address calcuated by adding section file offset and offset in
|
||||
// section.
|
||||
// See comments for ObjectInfo class
|
||||
LineTbl->getFileLineInfoForAddress(S->Offset + Offset, nullptr, Spec.FLIKind,
|
||||
LineInfo);
|
||||
return LineInfo.Line != 0
|
||||
? LineInfo.FileName + " (" + std::to_string(LineInfo.Line) + ")"
|
||||
: "";
|
||||
|
|
|
@ -69,7 +69,7 @@ template <class ELFT> class DIHelper {
|
|||
public:
|
||||
DIHelper(InputFile *F);
|
||||
~DIHelper();
|
||||
std::string getLineInfo(uintX_t Offset);
|
||||
std::string getLineInfo(InputSectionBase<ELFT> *S, uintX_t Offset);
|
||||
|
||||
private:
|
||||
std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
|
||||
|
|
|
@ -75,7 +75,9 @@ InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
|
|||
Kind SectionKind)
|
||||
: InputSectionBase(File, Hdr->sh_flags, Hdr->sh_type, Hdr->sh_entsize,
|
||||
Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
|
||||
getSectionContents(File, Hdr), Name, SectionKind) {}
|
||||
getSectionContents(File, Hdr), Name, SectionKind) {
|
||||
this->Offset = Hdr->sh_offset;
|
||||
}
|
||||
|
||||
template <class ELFT> size_t InputSectionBase<ELFT>::getSize() const {
|
||||
if (auto *D = dyn_cast<InputSection<ELFT>>(this))
|
||||
|
|
|
@ -88,6 +88,7 @@ protected:
|
|||
public:
|
||||
// These corresponds to the fields in Elf_Shdr.
|
||||
uintX_t Flags;
|
||||
uintX_t Offset = 0;
|
||||
uintX_t Entsize;
|
||||
uint32_t Type;
|
||||
uint32_t Link;
|
||||
|
|
|
@ -544,7 +544,7 @@ static std::string getLocation(SymbolBody &Sym, InputSectionBase<ELFT> &S,
|
|||
ObjectFile<ELFT> *File = S.getFile();
|
||||
|
||||
// First check if we can get desired values from debugging information.
|
||||
std::string LineInfo = File->getDIHelper()->getLineInfo(Offset);
|
||||
std::string LineInfo = File->getDIHelper()->getLineInfo(&S, Offset);
|
||||
if (!LineInfo.empty())
|
||||
return LineInfo;
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
.file 1 "undef-debug.s"
|
||||
.loc 1 3
|
||||
.quad zed3
|
||||
|
||||
.section .text.1,"ax"
|
||||
.loc 1 7
|
||||
.quad zed4
|
||||
|
||||
.section .text.2,"ax"
|
||||
.loc 1 11
|
||||
.quad zed5
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
# CHECK: error: undef.s (.text+0x10): undefined symbol 'foo(int)'
|
||||
# CHECK: error: {{.*}}2.a({{.*}}.o) (.text+0x0): undefined symbol 'zed2'
|
||||
# CHECK: error: undef-debug.s (3): undefined symbol 'zed3'
|
||||
# CHECK: error: undef-debug.s (7): undefined symbol 'zed4'
|
||||
# CHECK: error: undef-debug.s (11): undefined symbol 'zed5'
|
||||
|
||||
# RUN: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \
|
||||
# RUN: FileCheck -check-prefix=NO-DEMANGLE %s
|
||||
|
|
Loading…
Reference in New Issue