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/IR/Module.h"
|
||||||
#include "llvm/LTO/LTO.h"
|
#include "llvm/LTO/LTO.h"
|
||||||
#include "llvm/MC/StringTableBuilder.h"
|
#include "llvm/MC/StringTableBuilder.h"
|
||||||
|
#include "llvm/Object/ELFObjectFile.h"
|
||||||
#include "llvm/Support/Path.h"
|
#include "llvm/Support/Path.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
|
@ -36,13 +37,31 @@ using namespace lld::elf;
|
||||||
|
|
||||||
std::vector<InputFile *> InputFile::Pool;
|
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 =
|
Expected<std::unique_ptr<object::ObjectFile>> Obj =
|
||||||
object::ObjectFile::createObjectFile(F->MB);
|
object::ObjectFile::createObjectFile(F->MB);
|
||||||
if (!Obj)
|
if (!Obj)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DWARFContextInMemory Dwarf(*Obj.get());
|
ObjectInfo ObjInfo;
|
||||||
|
DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo);
|
||||||
DwarfLine.reset(new DWARFDebugLine(&Dwarf.getLineSection().Relocs));
|
DwarfLine.reset(new DWARFDebugLine(&Dwarf.getLineSection().Relocs));
|
||||||
DataExtractor LineData(Dwarf.getLineSection().Data,
|
DataExtractor LineData(Dwarf.getLineSection().Data,
|
||||||
ELFT::TargetEndianness == support::little,
|
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> 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)
|
if (!DwarfLine)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
@ -65,7 +86,12 @@ template <class ELFT> std::string DIHelper<ELFT>::getLineInfo(uintX_t Offset) {
|
||||||
const DWARFDebugLine::LineTable *LineTbl = DwarfLine->getLineTable(0);
|
const DWARFDebugLine::LineTable *LineTbl = DwarfLine->getLineTable(0);
|
||||||
if (!LineTbl)
|
if (!LineTbl)
|
||||||
return "";
|
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
|
return LineInfo.Line != 0
|
||||||
? LineInfo.FileName + " (" + std::to_string(LineInfo.Line) + ")"
|
? LineInfo.FileName + " (" + std::to_string(LineInfo.Line) + ")"
|
||||||
: "";
|
: "";
|
||||||
|
|
|
@ -69,7 +69,7 @@ template <class ELFT> class DIHelper {
|
||||||
public:
|
public:
|
||||||
DIHelper(InputFile *F);
|
DIHelper(InputFile *F);
|
||||||
~DIHelper();
|
~DIHelper();
|
||||||
std::string getLineInfo(uintX_t Offset);
|
std::string getLineInfo(InputSectionBase<ELFT> *S, uintX_t Offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
|
std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
|
||||||
|
|
|
@ -75,7 +75,9 @@ InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
|
||||||
Kind SectionKind)
|
Kind SectionKind)
|
||||||
: InputSectionBase(File, Hdr->sh_flags, Hdr->sh_type, Hdr->sh_entsize,
|
: InputSectionBase(File, Hdr->sh_flags, Hdr->sh_type, Hdr->sh_entsize,
|
||||||
Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
|
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 {
|
template <class ELFT> size_t InputSectionBase<ELFT>::getSize() const {
|
||||||
if (auto *D = dyn_cast<InputSection<ELFT>>(this))
|
if (auto *D = dyn_cast<InputSection<ELFT>>(this))
|
||||||
|
|
|
@ -88,6 +88,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
// These corresponds to the fields in Elf_Shdr.
|
// These corresponds to the fields in Elf_Shdr.
|
||||||
uintX_t Flags;
|
uintX_t Flags;
|
||||||
|
uintX_t Offset = 0;
|
||||||
uintX_t Entsize;
|
uintX_t Entsize;
|
||||||
uint32_t Type;
|
uint32_t Type;
|
||||||
uint32_t Link;
|
uint32_t Link;
|
||||||
|
|
|
@ -544,7 +544,7 @@ static std::string getLocation(SymbolBody &Sym, InputSectionBase<ELFT> &S,
|
||||||
ObjectFile<ELFT> *File = S.getFile();
|
ObjectFile<ELFT> *File = S.getFile();
|
||||||
|
|
||||||
// First check if we can get desired values from debugging information.
|
// 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())
|
if (!LineInfo.empty())
|
||||||
return LineInfo;
|
return LineInfo;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
.file 1 "undef-debug.s"
|
.file 1 "undef-debug.s"
|
||||||
.loc 1 3
|
.loc 1 3
|
||||||
.quad zed3
|
.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: undef.s (.text+0x10): undefined symbol 'foo(int)'
|
||||||
# CHECK: error: {{.*}}2.a({{.*}}.o) (.text+0x0): undefined symbol 'zed2'
|
# CHECK: error: {{.*}}2.a({{.*}}.o) (.text+0x0): undefined symbol 'zed2'
|
||||||
# CHECK: error: undef-debug.s (3): undefined symbol 'zed3'
|
# 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: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \
|
||||||
# RUN: FileCheck -check-prefix=NO-DEMANGLE %s
|
# RUN: FileCheck -check-prefix=NO-DEMANGLE %s
|
||||||
|
|
Loading…
Reference in New Issue