[prev in list] [next in list] [prev in thread] [next in thread]
List: haiku-commits
Subject: [Haiku-commits] r31325 - haiku/trunk/src/apps/debugger/dwarf
From: bonefish at BerliOS <bonefish () mail ! berlios ! de>
Date: 2009-06-30 12:48:46
Message-ID: 200906301248.n5UCmkF1007963 () sheep ! berlios ! de
[Download RAW message or body]
Author: bonefish
Date: 2009-06-30 14:48:46 +0200 (Tue, 30 Jun 2009)
New Revision: 31325
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31325&view=rev
Modified:
haiku/trunk/src/apps/debugger/dwarf/CompilationUnit.cpp
haiku/trunk/src/apps/debugger/dwarf/CompilationUnit.h
haiku/trunk/src/apps/debugger/dwarf/DataReader.h
haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntries.h
haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntry.cpp
haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntry.h
haiku/trunk/src/apps/debugger/dwarf/DwarfFile.cpp
haiku/trunk/src/apps/debugger/dwarf/DwarfFile.h
haiku/trunk/src/apps/debugger/dwarf/DwarfUtils.cpp
haiku/trunk/src/apps/debugger/dwarf/DwarfUtils.h
Log:
* 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.
Modified: haiku/trunk/src/apps/debugger/dwarf/CompilationUnit.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/CompilationUnit.cpp 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/CompilationUnit.cpp 2009-06-30 12:48:46 UTC (rev 31325)
@@ -5,7 +5,23 @@
#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,
dwarf_off_t contentOffset, dwarf_off_t totalSize,
dwarf_off_t abbreviationOffset)
@@ -15,7 +31,9 @@
fTotalSize(totalSize),
fAbbreviationOffset(abbreviationOffset),
fAbbreviationTable(NULL),
- fUnitEntry(NULL)
+ fUnitEntry(NULL),
+ fDirectories(10, true),
+ fFiles(10, true)
{
}
@@ -88,3 +106,65 @@
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;
+}
Modified: haiku/trunk/src/apps/debugger/dwarf/CompilationUnit.h
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/CompilationUnit.h 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/CompilationUnit.h 2009-06-30 12:48:46 UTC (rev 31325)
@@ -5,6 +5,8 @@
#ifndef COMPILATION_UNIT_H
#define COMPILATION_UNIT_H
+#include <String.h>
+
#include <ObjectList.h>
#include "Array.h"
@@ -50,7 +52,21 @@
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:
dwarf_off_t fHeaderOffset;
dwarf_off_t fContentOffset;
dwarf_off_t fTotalSize;
@@ -59,6 +75,8 @@
DIECompileUnitBase* fUnitEntry;
Array<DebugInfoEntry*> fEntries;
Array<dwarf_off_t> fEntryOffsets;
+ DirectoryList fDirectories;
+ FileList fFiles;
};
Modified: haiku/trunk/src/apps/debugger/dwarf/DataReader.h
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/DataReader.h 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/DataReader.h 2009-06-30 12:48:46 UTC (rev 31325)
@@ -135,6 +135,15 @@
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)
{
if (bytes < 0)
Modified: haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntries.h
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntries.h 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntries.h 2009-06-30 12:48:46 UTC (rev 31325)
@@ -153,6 +153,9 @@
dwarf_addr_t HighPC() const { return fHighPC; }
dwarf_addr_t AddressRangeBase() const;
+ dwarf_off_t StatementListOffset() const
+ { return fStatementListOffset; }
+
virtual status_t AddChild(DebugInfoEntry* child);
virtual status_t AddAttribute_name(uint16 attributeName,
Modified: haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntry.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntry.cpp 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntry.cpp 2009-06-30 12:48:46 UTC (rev 31325)
@@ -94,6 +94,22 @@
}
+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
DebugInfoEntry::AddChild(DebugInfoEntry* child)
{
Modified: haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntry.h
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntry.h 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/DebugInfoEntry.h 2009-06-30 12:48:46 UTC (rev 31325)
@@ -59,6 +59,9 @@
virtual DebugInfoEntry* Specification() const;
virtual DebugInfoEntry* AbstractOrigin() const;
+ bool GetDeclarationLocation(uint32& _file,
+ uint32& _line, uint32& _column) const;
+
virtual status_t AddChild(DebugInfoEntry* child);
virtual status_t AddAttribute_decl_file(uint16 attributeName,
Modified: haiku/trunk/src/apps/debugger/dwarf/DwarfFile.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/DwarfFile.cpp 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/DwarfFile.cpp 2009-06-30 12:48:46 UTC (rev 31325)
@@ -27,6 +27,7 @@
fDebugAbbrevSection(NULL),
fDebugStringSection(NULL),
fDebugRangesSection(NULL),
+ fDebugLineSection(NULL),
fCompilationUnits(20, true),
fCurrentCompilationUnit(NULL),
fFinished(false),
@@ -45,6 +46,7 @@
fElfFile->PutSection(fDebugAbbrevSection);
fElfFile->PutSection(fDebugStringSection);
fElfFile->PutSection(fDebugRangesSection);
+ fElfFile->PutSection(fDebugLineSection);
delete fElfFile;
}
@@ -72,8 +74,6 @@
fDebugInfoSection = fElfFile->GetSection(".debug_info");
fDebugAbbrevSection = fElfFile->GetSection(".debug_abbrev");
fDebugStringSection = fElfFile->GetSection(".debug_str");
- fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
- // not mandatory
if (fDebugInfoSection == NULL || fDebugAbbrevSection == NULL
|| fDebugStringSection == NULL) {
fprintf(stderr, "DwarfManager::File::Load(\"%s\"): no "
@@ -82,15 +82,17 @@
return B_ERROR;
}
+ // not mandatory sections
+ fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
+ fDebugLineSection = fElfFile->GetSection(".debug_line");
+
// iterate through the debug info section
DataReader dataReader(fDebugInfoSection->Data(),
fDebugInfoSection->Size());
while (dataReader.HasData()) {
dwarf_off_t unitHeaderOffset = dataReader.Offset();
- uint64 unitLength = dataReader.Read<uint32>(0);
- bool dwarf64 = (unitLength == 0xffffffff);
- if (dwarf64)
- unitLength = dataReader.Read<uint64>(0);
+ bool dwarf64;
+ uint64 unitLength = dataReader.ReadInitialLength(dwarf64);
dwarf_off_t unitLengthOffset = dataReader.Offset();
// the unitLength starts here
@@ -189,6 +191,30 @@
}
+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
DwarfFile::_ParseCompilationUnit(CompilationUnit* unit)
{
@@ -372,6 +398,9 @@
}
}
+ if (fDebugLineSection != NULL)
+ _ParseLineInfo(unit);
+
return B_OK;
}
@@ -585,6 +614,93 @@
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
DwarfFile::_GetAbbreviationTable(off_t offset, AbbreviationTable*& _table)
{
// check, whether we've already loaded it
Modified: haiku/trunk/src/apps/debugger/dwarf/DwarfFile.h
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/DwarfFile.h 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/DwarfFile.h 2009-06-30 12:48:46 UTC (rev 31325)
@@ -33,6 +33,8 @@
int32 CountCompilationUnits() const;
CompilationUnit* CompilationUnitAt(int32 index) const;
+ CompilationUnit* CompilationUnitForDIE(
+ const DebugInfoEntry* entry) const;
private:
typedef DoublyLinkedList<AbbreviationTable> AbbreviationTableList;
@@ -49,6 +51,8 @@
DebugInfoEntry* entry,
AbbreviationEntry& abbreviationEntry);
+ status_t _ParseLineInfo(CompilationUnit* unit);
+
status_t _GetAbbreviationTable(off_t offset,
AbbreviationTable*& _table);
@@ -64,6 +68,7 @@
ElfSection* fDebugAbbrevSection;
ElfSection* fDebugStringSection;
ElfSection* fDebugRangesSection;
+ ElfSection* fDebugLineSection;
AbbreviationTableList fAbbreviationTables;
DebugInfoEntryFactory fDebugInfoFactory;
CompilationUnitList fCompilationUnits;
Modified: haiku/trunk/src/apps/debugger/dwarf/DwarfUtils.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/DwarfUtils.cpp 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/DwarfUtils.cpp 2009-06-30 12:48:46 UTC (rev 31325)
@@ -7,7 +7,10 @@
#include <String.h>
+#include "CompilationUnit.h"
+#include "DwarfFile.h"
+
/*static*/ void
DwarfUtils::GetDIEName(const DebugInfoEntry* entry, BString& _name)
{
@@ -77,3 +80,55 @@
} else
_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;
+}
Modified: haiku/trunk/src/apps/debugger/dwarf/DwarfUtils.h
===================================================================
--- haiku/trunk/src/apps/debugger/dwarf/DwarfUtils.h 2009-06-30 12:47:41 UTC (rev 31324)
+++ haiku/trunk/src/apps/debugger/dwarf/DwarfUtils.h 2009-06-30 12:48:46 UTC (rev 31325)
@@ -10,6 +10,7 @@
class BString;
class DebugInfoEntry;
+class DwarfFile;
class DwarfUtils {
@@ -21,6 +22,12 @@
static void GetFullyQualifiedDIEName(
const DebugInfoEntry* entry,
BString& _name);
+
+ static bool GetDeclarationLocation(DwarfFile* dwarfFile,
+ const DebugInfoEntry* entry,
+ const char*& _directory,
+ const char*& _file,
+ uint32& _line, uint32& _column);
};
_______________________________________________
Haiku-commits mailing list
Haiku-commits@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/haiku-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic