* Added parsing the .debug_line header for each compilation unit and attaching
the include directory and source file names to CompilationUnit. * Added DwarfUtils::GetDeclarationLocation() which retrieves the respective source file name and line/column index for a given DIE. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31325 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -5,6 +5,22 @@
|
|||||||
|
|
||||||
#include "CompilationUnit.h"
|
#include "CompilationUnit.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
|
struct CompilationUnit::File {
|
||||||
|
BString fileName;
|
||||||
|
const char* dirName;
|
||||||
|
|
||||||
|
|
||||||
|
File(const char* fileName, const char* dirName)
|
||||||
|
:
|
||||||
|
fileName(fileName),
|
||||||
|
dirName(dirName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
CompilationUnit::CompilationUnit(dwarf_off_t headerOffset,
|
CompilationUnit::CompilationUnit(dwarf_off_t headerOffset,
|
||||||
dwarf_off_t contentOffset, dwarf_off_t totalSize,
|
dwarf_off_t contentOffset, dwarf_off_t totalSize,
|
||||||
@@ -15,7 +31,9 @@ CompilationUnit::CompilationUnit(dwarf_off_t headerOffset,
|
|||||||
fTotalSize(totalSize),
|
fTotalSize(totalSize),
|
||||||
fAbbreviationOffset(abbreviationOffset),
|
fAbbreviationOffset(abbreviationOffset),
|
||||||
fAbbreviationTable(NULL),
|
fAbbreviationTable(NULL),
|
||||||
fUnitEntry(NULL)
|
fUnitEntry(NULL),
|
||||||
|
fDirectories(10, true),
|
||||||
|
fFiles(10, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,3 +106,65 @@ CompilationUnit::EntryForOffset(dwarf_off_t offset) const
|
|||||||
|
|
||||||
return fEntryOffsets[lower] == offset ? fEntries[lower] : NULL;
|
return fEntryOffsets[lower] == offset ? fEntries[lower] : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CompilationUnit::AddDirectory(const char* directory)
|
||||||
|
{
|
||||||
|
BString* directoryString = new(std::nothrow) BString(directory);
|
||||||
|
if (directoryString == NULL || directoryString->Length() == 0
|
||||||
|
|| !fDirectories.AddItem(directoryString)) {
|
||||||
|
delete directoryString;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
CompilationUnit::CountDirectories() const
|
||||||
|
{
|
||||||
|
return fDirectories.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
CompilationUnit::DirectoryAt(int32 index) const
|
||||||
|
{
|
||||||
|
BString* directory = fDirectories.ItemAt(index);
|
||||||
|
return directory != NULL ? directory->String() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CompilationUnit::AddFile(const char* fileName, int32 dirIndex)
|
||||||
|
{
|
||||||
|
File* file = new(std::nothrow) File(fileName, DirectoryAt(dirIndex));
|
||||||
|
if (file == NULL || file->fileName.Length() == 0 || !fFiles.AddItem(file)) {
|
||||||
|
delete file;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
CompilationUnit::CountFiles() const
|
||||||
|
{
|
||||||
|
return fFiles.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
CompilationUnit::FileAt(int32 index, const char** _directory) const
|
||||||
|
{
|
||||||
|
if (File* file = fFiles.ItemAt(index)) {
|
||||||
|
if (_directory != NULL)
|
||||||
|
*_directory = file->dirName;
|
||||||
|
return file->fileName.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#ifndef COMPILATION_UNIT_H
|
#ifndef COMPILATION_UNIT_H
|
||||||
#define COMPILATION_UNIT_H
|
#define COMPILATION_UNIT_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
|
|
||||||
#include "Array.h"
|
#include "Array.h"
|
||||||
@@ -50,6 +52,20 @@ public:
|
|||||||
dwarf_off_t& offset) const;
|
dwarf_off_t& offset) const;
|
||||||
DebugInfoEntry* EntryForOffset(dwarf_off_t offset) const;
|
DebugInfoEntry* EntryForOffset(dwarf_off_t offset) const;
|
||||||
|
|
||||||
|
bool AddDirectory(const char* directory);
|
||||||
|
int32 CountDirectories() const;
|
||||||
|
const char* DirectoryAt(int32 index) const;
|
||||||
|
|
||||||
|
bool AddFile(const char* fileName, int32 dirIndex);
|
||||||
|
int32 CountFiles() const;
|
||||||
|
const char* FileAt(int32 index,
|
||||||
|
const char** _directory = NULL) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct File;
|
||||||
|
typedef BObjectList<BString> DirectoryList;
|
||||||
|
typedef BObjectList<File> FileList;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
dwarf_off_t fHeaderOffset;
|
dwarf_off_t fHeaderOffset;
|
||||||
dwarf_off_t fContentOffset;
|
dwarf_off_t fContentOffset;
|
||||||
@@ -59,6 +75,8 @@ private:
|
|||||||
DIECompileUnitBase* fUnitEntry;
|
DIECompileUnitBase* fUnitEntry;
|
||||||
Array<DebugInfoEntry*> fEntries;
|
Array<DebugInfoEntry*> fEntries;
|
||||||
Array<dwarf_off_t> fEntryOffsets;
|
Array<dwarf_off_t> fEntryOffsets;
|
||||||
|
DirectoryList fDirectories;
|
||||||
|
FileList fFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,15 @@ public:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64 ReadInitialLength(bool& _dwarf64)
|
||||||
|
{
|
||||||
|
uint64 length = Read<uint32>(0);
|
||||||
|
_dwarf64 = (length == 0xffffffff);
|
||||||
|
if (_dwarf64)
|
||||||
|
length = Read<uint64>(0);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
bool Skip(off_t bytes)
|
bool Skip(off_t bytes)
|
||||||
{
|
{
|
||||||
if (bytes < 0)
|
if (bytes < 0)
|
||||||
|
|||||||
@@ -153,6 +153,9 @@ public:
|
|||||||
dwarf_addr_t HighPC() const { return fHighPC; }
|
dwarf_addr_t HighPC() const { return fHighPC; }
|
||||||
dwarf_addr_t AddressRangeBase() const;
|
dwarf_addr_t AddressRangeBase() const;
|
||||||
|
|
||||||
|
dwarf_off_t StatementListOffset() const
|
||||||
|
{ return fStatementListOffset; }
|
||||||
|
|
||||||
virtual status_t AddChild(DebugInfoEntry* child);
|
virtual status_t AddChild(DebugInfoEntry* child);
|
||||||
|
|
||||||
virtual status_t AddAttribute_name(uint16 attributeName,
|
virtual status_t AddAttribute_name(uint16 attributeName,
|
||||||
|
|||||||
@@ -94,6 +94,22 @@ DebugInfoEntry::AbstractOrigin() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
DebugInfoEntry::GetDeclarationLocation(uint32& _file, uint32& _line,
|
||||||
|
uint32& _column) const
|
||||||
|
{
|
||||||
|
DeclarationLocation* location = const_cast<DebugInfoEntry*>(this)
|
||||||
|
->GetDeclarationLocation();
|
||||||
|
if (location == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_file = location->file;
|
||||||
|
_line = location->line;
|
||||||
|
_column = location->column;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DebugInfoEntry::AddChild(DebugInfoEntry* child)
|
DebugInfoEntry::AddChild(DebugInfoEntry* child)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ public:
|
|||||||
virtual DebugInfoEntry* Specification() const;
|
virtual DebugInfoEntry* Specification() const;
|
||||||
virtual DebugInfoEntry* AbstractOrigin() const;
|
virtual DebugInfoEntry* AbstractOrigin() const;
|
||||||
|
|
||||||
|
bool GetDeclarationLocation(uint32& _file,
|
||||||
|
uint32& _line, uint32& _column) const;
|
||||||
|
|
||||||
virtual status_t AddChild(DebugInfoEntry* child);
|
virtual status_t AddChild(DebugInfoEntry* child);
|
||||||
|
|
||||||
virtual status_t AddAttribute_decl_file(uint16 attributeName,
|
virtual status_t AddAttribute_decl_file(uint16 attributeName,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ DwarfFile::DwarfFile()
|
|||||||
fDebugAbbrevSection(NULL),
|
fDebugAbbrevSection(NULL),
|
||||||
fDebugStringSection(NULL),
|
fDebugStringSection(NULL),
|
||||||
fDebugRangesSection(NULL),
|
fDebugRangesSection(NULL),
|
||||||
|
fDebugLineSection(NULL),
|
||||||
fCompilationUnits(20, true),
|
fCompilationUnits(20, true),
|
||||||
fCurrentCompilationUnit(NULL),
|
fCurrentCompilationUnit(NULL),
|
||||||
fFinished(false),
|
fFinished(false),
|
||||||
@@ -45,6 +46,7 @@ DwarfFile::~DwarfFile()
|
|||||||
fElfFile->PutSection(fDebugAbbrevSection);
|
fElfFile->PutSection(fDebugAbbrevSection);
|
||||||
fElfFile->PutSection(fDebugStringSection);
|
fElfFile->PutSection(fDebugStringSection);
|
||||||
fElfFile->PutSection(fDebugRangesSection);
|
fElfFile->PutSection(fDebugRangesSection);
|
||||||
|
fElfFile->PutSection(fDebugLineSection);
|
||||||
delete fElfFile;
|
delete fElfFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,8 +74,6 @@ DwarfFile::Load(const char* fileName)
|
|||||||
fDebugInfoSection = fElfFile->GetSection(".debug_info");
|
fDebugInfoSection = fElfFile->GetSection(".debug_info");
|
||||||
fDebugAbbrevSection = fElfFile->GetSection(".debug_abbrev");
|
fDebugAbbrevSection = fElfFile->GetSection(".debug_abbrev");
|
||||||
fDebugStringSection = fElfFile->GetSection(".debug_str");
|
fDebugStringSection = fElfFile->GetSection(".debug_str");
|
||||||
fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
|
|
||||||
// not mandatory
|
|
||||||
if (fDebugInfoSection == NULL || fDebugAbbrevSection == NULL
|
if (fDebugInfoSection == NULL || fDebugAbbrevSection == NULL
|
||||||
|| fDebugStringSection == NULL) {
|
|| fDebugStringSection == NULL) {
|
||||||
fprintf(stderr, "DwarfManager::File::Load(\"%s\"): no "
|
fprintf(stderr, "DwarfManager::File::Load(\"%s\"): no "
|
||||||
@@ -82,15 +82,17 @@ DwarfFile::Load(const char* fileName)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not mandatory sections
|
||||||
|
fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
|
||||||
|
fDebugLineSection = fElfFile->GetSection(".debug_line");
|
||||||
|
|
||||||
// iterate through the debug info section
|
// iterate through the debug info section
|
||||||
DataReader dataReader(fDebugInfoSection->Data(),
|
DataReader dataReader(fDebugInfoSection->Data(),
|
||||||
fDebugInfoSection->Size());
|
fDebugInfoSection->Size());
|
||||||
while (dataReader.HasData()) {
|
while (dataReader.HasData()) {
|
||||||
dwarf_off_t unitHeaderOffset = dataReader.Offset();
|
dwarf_off_t unitHeaderOffset = dataReader.Offset();
|
||||||
uint64 unitLength = dataReader.Read<uint32>(0);
|
bool dwarf64;
|
||||||
bool dwarf64 = (unitLength == 0xffffffff);
|
uint64 unitLength = dataReader.ReadInitialLength(dwarf64);
|
||||||
if (dwarf64)
|
|
||||||
unitLength = dataReader.Read<uint64>(0);
|
|
||||||
|
|
||||||
dwarf_off_t unitLengthOffset = dataReader.Offset();
|
dwarf_off_t unitLengthOffset = dataReader.Offset();
|
||||||
// the unitLength starts here
|
// the unitLength starts here
|
||||||
@@ -189,6 +191,30 @@ DwarfFile::CompilationUnitAt(int32 index) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CompilationUnit*
|
||||||
|
DwarfFile::CompilationUnitForDIE(const DebugInfoEntry* entry) const
|
||||||
|
{
|
||||||
|
// find the root of the tree the entry lives in
|
||||||
|
while (entry != NULL && entry->Parent() != NULL)
|
||||||
|
entry = entry->Parent();
|
||||||
|
|
||||||
|
// that should be the compilation unit entry
|
||||||
|
const DIECompileUnitBase* unitEntry
|
||||||
|
= dynamic_cast<const DIECompileUnitBase*>(entry);
|
||||||
|
if (unitEntry == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// find the compilation unit
|
||||||
|
for (int32 i = 0; CompilationUnit* unit = fCompilationUnits.ItemAt(i);
|
||||||
|
i++) {
|
||||||
|
if (unit->UnitEntry() == unitEntry)
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfFile::_ParseCompilationUnit(CompilationUnit* unit)
|
DwarfFile::_ParseCompilationUnit(CompilationUnit* unit)
|
||||||
{
|
{
|
||||||
@@ -372,6 +398,9 @@ printf("entry %p at %lu\n", entry, offset);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fDebugLineSection != NULL)
|
||||||
|
_ParseLineInfo(unit);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,6 +613,93 @@ printf(" -> no attribute setter!\n");
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DwarfFile::_ParseLineInfo(CompilationUnit* unit)
|
||||||
|
{
|
||||||
|
dwarf_off_t offset = unit->UnitEntry()->StatementListOffset();
|
||||||
|
printf("DwarfFile::_ParseLineInfo(%p), offset: %lu\n", unit, offset);
|
||||||
|
|
||||||
|
DataReader dataReader((uint8*)fDebugLineSection->Data() + offset,
|
||||||
|
fDebugLineSection->Size() - offset);
|
||||||
|
|
||||||
|
// unit length
|
||||||
|
bool dwarf64;
|
||||||
|
uint64 unitLength = dataReader.ReadInitialLength(dwarf64);
|
||||||
|
|
||||||
|
// version (uhalf)
|
||||||
|
uint16 version = dataReader.Read<uint16>(0);
|
||||||
|
|
||||||
|
// header_length (4/8)
|
||||||
|
uint64 headerLength = dwarf64
|
||||||
|
? dataReader.Read<uint64>(0) : (uint64)dataReader.Read<uint32>(0);
|
||||||
|
|
||||||
|
// minimum instruction length
|
||||||
|
uint8 minInstructionLength = dataReader.Read<uint8>(0);
|
||||||
|
|
||||||
|
// default is statement
|
||||||
|
bool defaultIsStatement = dataReader.Read<uint8>(0) != 0;
|
||||||
|
|
||||||
|
// line_base (sbyte)
|
||||||
|
int8 lineBase = (int8)dataReader.Read<uint8>(0);
|
||||||
|
|
||||||
|
// line_range (ubyte)
|
||||||
|
uint8 lineRange = dataReader.Read<uint8>(0);
|
||||||
|
|
||||||
|
// opcode_base (ubyte)
|
||||||
|
uint8 opcodeBase = dataReader.Read<uint8>(0);
|
||||||
|
|
||||||
|
// standard_opcode_lengths (ubyte[])
|
||||||
|
dataReader.Skip(opcodeBase - 1);
|
||||||
|
|
||||||
|
if (dataReader.HasOverflow())
|
||||||
|
return B_BAD_DATA;
|
||||||
|
|
||||||
|
if (version != 2 && version != 3)
|
||||||
|
return B_UNSUPPORTED;
|
||||||
|
|
||||||
|
printf(" unitLength: %llu\n", unitLength);
|
||||||
|
printf(" version: %u\n", version);
|
||||||
|
printf(" headerLength: %llu\n", headerLength);
|
||||||
|
printf(" minInstructionLength: %u\n", minInstructionLength);
|
||||||
|
printf(" defaultIsStatement: %d\n", defaultIsStatement);
|
||||||
|
printf(" lineBase: %d\n", lineBase);
|
||||||
|
printf(" lineRange: %u\n", lineRange);
|
||||||
|
printf(" opcodeBase: %u\n", opcodeBase);
|
||||||
|
|
||||||
|
// include directories
|
||||||
|
printf(" include directories:\n");
|
||||||
|
while (const char* directory = dataReader.ReadString()) {
|
||||||
|
if (*directory == '\0')
|
||||||
|
break;
|
||||||
|
printf(" \"%s\"\n", directory);
|
||||||
|
|
||||||
|
if (!unit->AddDirectory(directory))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file names
|
||||||
|
printf(" files:\n");
|
||||||
|
while (const char* file = dataReader.ReadString()) {
|
||||||
|
if (*file == '\0')
|
||||||
|
break;
|
||||||
|
uint64 dirIndex = dataReader.ReadUnsignedLEB128(0);
|
||||||
|
uint64 modificationTime = dataReader.ReadUnsignedLEB128(0);
|
||||||
|
uint64 fileLength = dataReader.ReadUnsignedLEB128(0);
|
||||||
|
|
||||||
|
if (dataReader.HasOverflow())
|
||||||
|
return B_BAD_DATA;
|
||||||
|
|
||||||
|
printf(" \"%s\", dir index: %llu, mtime: %llu, length: %llu\n", file,
|
||||||
|
dirIndex, modificationTime, fileLength);
|
||||||
|
|
||||||
|
if (!unit->AddFile(file, dirIndex - 1))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfFile::_GetAbbreviationTable(off_t offset, AbbreviationTable*& _table)
|
DwarfFile::_GetAbbreviationTable(off_t offset, AbbreviationTable*& _table)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public:
|
|||||||
|
|
||||||
int32 CountCompilationUnits() const;
|
int32 CountCompilationUnits() const;
|
||||||
CompilationUnit* CompilationUnitAt(int32 index) const;
|
CompilationUnit* CompilationUnitAt(int32 index) const;
|
||||||
|
CompilationUnit* CompilationUnitForDIE(
|
||||||
|
const DebugInfoEntry* entry) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef DoublyLinkedList<AbbreviationTable> AbbreviationTableList;
|
typedef DoublyLinkedList<AbbreviationTable> AbbreviationTableList;
|
||||||
@@ -49,6 +51,8 @@ private:
|
|||||||
DebugInfoEntry* entry,
|
DebugInfoEntry* entry,
|
||||||
AbbreviationEntry& abbreviationEntry);
|
AbbreviationEntry& abbreviationEntry);
|
||||||
|
|
||||||
|
status_t _ParseLineInfo(CompilationUnit* unit);
|
||||||
|
|
||||||
status_t _GetAbbreviationTable(off_t offset,
|
status_t _GetAbbreviationTable(off_t offset,
|
||||||
AbbreviationTable*& _table);
|
AbbreviationTable*& _table);
|
||||||
|
|
||||||
@@ -64,6 +68,7 @@ private:
|
|||||||
ElfSection* fDebugAbbrevSection;
|
ElfSection* fDebugAbbrevSection;
|
||||||
ElfSection* fDebugStringSection;
|
ElfSection* fDebugStringSection;
|
||||||
ElfSection* fDebugRangesSection;
|
ElfSection* fDebugRangesSection;
|
||||||
|
ElfSection* fDebugLineSection;
|
||||||
AbbreviationTableList fAbbreviationTables;
|
AbbreviationTableList fAbbreviationTables;
|
||||||
DebugInfoEntryFactory fDebugInfoFactory;
|
DebugInfoEntryFactory fDebugInfoFactory;
|
||||||
CompilationUnitList fCompilationUnits;
|
CompilationUnitList fCompilationUnits;
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "CompilationUnit.h"
|
||||||
|
#include "DwarfFile.h"
|
||||||
|
|
||||||
|
|
||||||
/*static*/ void
|
/*static*/ void
|
||||||
DwarfUtils::GetDIEName(const DebugInfoEntry* entry, BString& _name)
|
DwarfUtils::GetDIEName(const DebugInfoEntry* entry, BString& _name)
|
||||||
@@ -77,3 +80,55 @@ DwarfUtils::GetFullyQualifiedDIEName(const DebugInfoEntry* entry,
|
|||||||
} else
|
} else
|
||||||
_name = name;
|
_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ bool
|
||||||
|
DwarfUtils::GetDeclarationLocation(DwarfFile* dwarfFile,
|
||||||
|
const DebugInfoEntry* entry, const char*& _directory, const char*& _file,
|
||||||
|
uint32& _line, uint32& _column)
|
||||||
|
{
|
||||||
|
uint32 file;
|
||||||
|
uint32 line;
|
||||||
|
uint32 column;
|
||||||
|
if (!entry->GetDeclarationLocation(file, line, column))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// if no info yet, try the abstract origin (if any)
|
||||||
|
if (file == 0) {
|
||||||
|
if (DebugInfoEntry* abstractOrigin = entry->AbstractOrigin()) {
|
||||||
|
if (abstractOrigin->GetDeclarationLocation(file, line, column)
|
||||||
|
&& file != 0) {
|
||||||
|
entry = abstractOrigin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no info yet, try the specification (if any)
|
||||||
|
if (file == 0) {
|
||||||
|
if (DebugInfoEntry* specification = entry->Specification()) {
|
||||||
|
if (specification->GetDeclarationLocation(file, line, column)
|
||||||
|
&& file != 0) {
|
||||||
|
entry = specification;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// get the compilation unit
|
||||||
|
CompilationUnit* unit = dwarfFile->CompilationUnitForDIE(entry);
|
||||||
|
if (unit == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const char* directoryName;
|
||||||
|
const char* fileName = unit->FileAt(file - 1, &directoryName);
|
||||||
|
if (fileName == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_directory = directoryName;
|
||||||
|
_file = fileName;
|
||||||
|
_line = line;
|
||||||
|
_column = column;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
class BString;
|
class BString;
|
||||||
class DebugInfoEntry;
|
class DebugInfoEntry;
|
||||||
|
class DwarfFile;
|
||||||
|
|
||||||
|
|
||||||
class DwarfUtils {
|
class DwarfUtils {
|
||||||
@@ -21,6 +22,12 @@ public:
|
|||||||
static void GetFullyQualifiedDIEName(
|
static void GetFullyQualifiedDIEName(
|
||||||
const DebugInfoEntry* entry,
|
const DebugInfoEntry* entry,
|
||||||
BString& _name);
|
BString& _name);
|
||||||
|
|
||||||
|
static bool GetDeclarationLocation(DwarfFile* dwarfFile,
|
||||||
|
const DebugInfoEntry* entry,
|
||||||
|
const char*& _directory,
|
||||||
|
const char*& _file,
|
||||||
|
uint32& _line, uint32& _column);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user