Skip to content

Commit

Permalink
Allow fetching source line, when multiple "AX" sections present
Browse files Browse the repository at this point in the history
Differential revision: https://reviews.llvm.org/D26070

llvm-svn: 285680
  • Loading branch information
eleviant777 committed Nov 1, 2016
1 parent 251f6dd commit c468120
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 7 deletions.
34 changes: 30 additions & 4 deletions lld/ELF/InputFiles.cpp
Expand Up @@ -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"

Expand All @@ -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,
Expand All @@ -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 "";

Expand All @@ -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) + ")"
: "";
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/InputFiles.h
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion lld/ELF/InputSection.cpp
Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/InputSection.h
Expand Up @@ -88,6 +88,7 @@ template <class ELFT> class InputSectionBase : public InputSectionData {
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;
Expand Down
2 changes: 1 addition & 1 deletion lld/ELF/Relocations.cpp
Expand Up @@ -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;

Expand Down
8 changes: 8 additions & 0 deletions lld/test/ELF/Inputs/undef-debug.s
@@ -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
2 changes: 2 additions & 0 deletions lld/test/ELF/undef.s
Expand Up @@ -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
Expand Down

0 comments on commit c468120

Please sign in to comment.