mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-23 00:20:25 +00:00
Add support for applying in-memory relocations to the .debug_line section and, in the case of ELF files, using symbol addresses when available for relocations to the .debug_info section. Also extending the llvm-rtdyld tool to add the ability to dump line number information for testing purposes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173517 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include "DWARFDebugAbbrev.h"
|
||||
#include "DWARFDebugInfoEntry.h"
|
||||
#include "DWARFDebugRangeList.h"
|
||||
#include "DWARFRelocMap.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
@@ -20,7 +21,6 @@ namespace llvm {
|
||||
class DWARFDebugAbbrev;
|
||||
class StringRef;
|
||||
class raw_ostream;
|
||||
typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
|
||||
|
||||
class DWARFCompileUnit {
|
||||
const DWARFDebugAbbrev *Abbrev;
|
||||
|
||||
@@ -53,7 +53,7 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
|
||||
DataExtractor lineData(getLineSection(), isLittleEndian(),
|
||||
savedAddressByteSize);
|
||||
DWARFDebugLine::DumpingState state(OS);
|
||||
DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state);
|
||||
DWARFDebugLine::parseStatementTable(lineData, &lineRelocMap(), &stmtOffset, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +155,7 @@ const DWARFDebugAranges *DWARFContext::getDebugAranges() {
|
||||
const DWARFLineTable *
|
||||
DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) {
|
||||
if (!Line)
|
||||
Line.reset(new DWARFDebugLine());
|
||||
Line.reset(new DWARFDebugLine(&lineRelocMap()));
|
||||
|
||||
unsigned stmtOffset =
|
||||
cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list,
|
||||
@@ -422,12 +422,15 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
|
||||
else
|
||||
continue;
|
||||
|
||||
// TODO: For now only handle relocations for the debug_info section.
|
||||
// TODO: Add support for relocations in other sections as needed.
|
||||
// Record relocations for the debug_info and debug_line sections.
|
||||
RelocAddrMap *Map;
|
||||
if (name == "debug_info")
|
||||
Map = &InfoRelocMap;
|
||||
else if (name == "debug_info.dwo")
|
||||
Map = &InfoDWORelocMap;
|
||||
else if (name == "debug_line")
|
||||
Map = &LineRelocMap;
|
||||
else
|
||||
continue;
|
||||
|
||||
@@ -441,10 +444,17 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
|
||||
reloc_i->getAddress(Address);
|
||||
uint64_t Type;
|
||||
reloc_i->getType(Type);
|
||||
uint64_t SymAddr = 0;
|
||||
// ELF relocations may need the symbol address
|
||||
if (Obj->isELF()) {
|
||||
object::SymbolRef Sym;
|
||||
reloc_i->getSymbol(Sym);
|
||||
Sym.getAddress(SymAddr);
|
||||
}
|
||||
|
||||
object::RelocVisitor V(Obj->getFileFormatName());
|
||||
// The section address is always 0 for debug sections.
|
||||
object::RelocToApply R(V.visit(Type, *reloc_i));
|
||||
object::RelocToApply R(V.visit(Type, *reloc_i, 0, SymAddr));
|
||||
if (V.error()) {
|
||||
SmallString<32> Name;
|
||||
error_code ec(reloc_i->getTypeName(Name));
|
||||
|
||||
@@ -95,6 +95,7 @@ public:
|
||||
|
||||
virtual bool isLittleEndian() const = 0;
|
||||
virtual const RelocAddrMap &infoRelocMap() const = 0;
|
||||
virtual const RelocAddrMap &lineRelocMap() const = 0;
|
||||
virtual StringRef getInfoSection() = 0;
|
||||
virtual StringRef getAbbrevSection() = 0;
|
||||
virtual StringRef getARangeSection() = 0;
|
||||
@@ -130,6 +131,7 @@ class DWARFContextInMemory : public DWARFContext {
|
||||
virtual void anchor();
|
||||
bool IsLittleEndian;
|
||||
RelocAddrMap InfoRelocMap;
|
||||
RelocAddrMap LineRelocMap;
|
||||
StringRef InfoSection;
|
||||
StringRef AbbrevSection;
|
||||
StringRef ARangeSection;
|
||||
@@ -150,6 +152,7 @@ public:
|
||||
DWARFContextInMemory(object::ObjectFile *);
|
||||
virtual bool isLittleEndian() const { return IsLittleEndian; }
|
||||
virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
|
||||
virtual const RelocAddrMap &lineRelocMap() const { return LineRelocMap; }
|
||||
virtual StringRef getInfoSection() { return InfoSection; }
|
||||
virtual StringRef getAbbrevSection() { return AbbrevSection; }
|
||||
virtual StringRef getARangeSection() { return ARangeSection; }
|
||||
|
||||
@@ -155,7 +155,7 @@ DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
|
||||
if (pos.second) {
|
||||
// Parse and cache the line table for at this offset.
|
||||
State state;
|
||||
if (!parseStatementTable(debug_line_data, &offset, state))
|
||||
if (!parseStatementTable(debug_line_data, RelocMap, &offset, state))
|
||||
return 0;
|
||||
pos.first->second = state;
|
||||
}
|
||||
@@ -219,7 +219,8 @@ DWARFDebugLine::parsePrologue(DataExtractor debug_line_data,
|
||||
}
|
||||
|
||||
bool
|
||||
DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
||||
DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
||||
const RelocAddrMap *RMap,
|
||||
uint32_t *offset_ptr, State &state) {
|
||||
const uint32_t debug_line_offset = *offset_ptr;
|
||||
|
||||
@@ -268,7 +269,15 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
|
||||
// relocatable address. All of the other statement program opcodes
|
||||
// that affect the address register add a delta to it. This instruction
|
||||
// stores a relocatable value into it instead.
|
||||
state.Address = debug_line_data.getAddress(offset_ptr);
|
||||
{
|
||||
// If this address is in our relocation map, apply the relocation.
|
||||
RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
|
||||
if (AI != RMap->end()) {
|
||||
const std::pair<uint8_t, int64_t> &R = AI->second;
|
||||
state.Address = debug_line_data.getAddress(offset_ptr) + R.second;
|
||||
} else
|
||||
state.Address = debug_line_data.getAddress(offset_ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_LNE_define_file:
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H
|
||||
#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
|
||||
|
||||
#include "DWARFRelocMap.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
@@ -21,6 +22,7 @@ class raw_ostream;
|
||||
|
||||
class DWARFDebugLine {
|
||||
public:
|
||||
DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {}
|
||||
struct FileNameEntry {
|
||||
FileNameEntry() : Name(0), DirIdx(0), ModTime(0), Length(0) {}
|
||||
|
||||
@@ -227,6 +229,7 @@ public:
|
||||
Prologue *prologue);
|
||||
/// Parse a single line table (prologue and all rows).
|
||||
static bool parseStatementTable(DataExtractor debug_line_data,
|
||||
const RelocAddrMap *RMap,
|
||||
uint32_t *offset_ptr, State &state);
|
||||
|
||||
const LineTable *getLineTable(uint32_t offset) const;
|
||||
@@ -238,6 +241,7 @@ private:
|
||||
typedef LineTableMapTy::iterator LineTableIter;
|
||||
typedef LineTableMapTy::const_iterator LineTableConstIter;
|
||||
|
||||
const RelocAddrMap *RelocMap;
|
||||
LineTableMapTy LineTableMap;
|
||||
};
|
||||
|
||||
|
||||
21
lib/DebugInfo/DWARFRelocMap.h
Normal file
21
lib/DebugInfo/DWARFRelocMap.h
Normal file
@@ -0,0 +1,21 @@
|
||||
//===-- DWARFRelocMap.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGINFO_DWARFRELOCMAP_H
|
||||
#define LLVM_DEBUGINFO_DWARFRELOCMAP_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_DWARFRELOCMAP_H
|
||||
Reference in New Issue
Block a user