* Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2012-2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef DWARF_FILE_H
#define DWARF_FILE_H
#include <ObjectList.h>
#include <Referenceable.h>
#include <util/DoublyLinkedList.h>
#include <util/OpenHashTable.h>
#include "DebugInfoEntries.h"
#include "TypeUnit.h"
struct AbbreviationEntry;
class AbbreviationTable;
class BVariant;
class CfaContext;
class CompilationUnit;
class DataReader;
class DwarfTargetInterface;
class ElfFile;
class ElfSection;
class TargetAddressRangeList;
class ValueLocation;
class DwarfFile : public BReferenceable,
public DoublyLinkedListLinkImpl<DwarfFile> {
public:
DwarfFile();
~DwarfFile();
status_t StartLoading(const char* fileName,
BString& _requiredExternalFile);
status_t Load(uint8 addressSize, bool isBigEndian,
const BString& externalFilePath);
status_t FinishLoading(uint8 addressSize, bool isBigEndian);
const char* Name() const { return fName; }
ElfFile* GetElfFile() const { return fElfFile; }
bool HasFrameInformation() const
{ return fDebugFrameSection != NULL
|| fEHFrameSection != NULL; }
int32 CountCompilationUnits() const;
CompilationUnit* CompilationUnitAt(int32 index) const;
CompilationUnit* CompilationUnitForDIE(
const DebugInfoEntry* entry) const;
TargetAddressRangeList* ResolveRangeList(CompilationUnit* unit,
uint64 offset) const;
status_t UnwindCallFrame(CompilationUnit* unit,
uint8 addressSize, bool isBigEndian,
DIESubprogram* subprogramEntry,
target_addr_t location,
const DwarfTargetInterface* inputInterface,
DwarfTargetInterface* outputInterface,
target_addr_t& _framePointer);
status_t EvaluateExpression(CompilationUnit* unit,
uint8 addressSize, bool isBigEndian,
DIESubprogram* subprogramEntry,
const void* expression,
off_t expressionLength,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer,
target_addr_t framePointer,
target_addr_t valueToPush, bool pushValue,
target_addr_t& _result);
status_t ResolveLocation(CompilationUnit* unit,
uint8 addressSize, bool isBigEndian,
DIESubprogram* subprogramEntry,
const LocationDescription* location,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer,
target_addr_t objectPointer,
bool hasObjectPointer,
target_addr_t framePointer,
target_addr_t relocationDelta,
ValueLocation& _result);
status_t EvaluateConstantValue(CompilationUnit* unit,
uint8 addressSize, bool isBigEndian,
DIESubprogram* subprogramEntry,
const ConstantAttributeValue* value,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer,
target_addr_t framePointer,
BVariant& _result);
status_t EvaluateDynamicValue(CompilationUnit* unit,
uint8 addressSize, bool isBigEndian,
DIESubprogram* subprogramEntry,
const DynamicAttributeValue* value,
const DwarfTargetInterface* targetInterface,
target_addr_t instructionPointer,
target_addr_t framePointer,
BVariant& _result, DIEType** _type = NULL);
private:
struct ExpressionEvaluationContext;
struct FDEAugmentation;
struct CIEAugmentation;
struct FDELookupInfo;
typedef DoublyLinkedList<AbbreviationTable> AbbreviationTableList;
typedef BObjectList<CompilationUnit, true> CompilationUnitList;
typedef BOpenHashTable<TypeUnitTableHashDefinition> TypeUnitTable;
typedef BObjectList<FDELookupInfo, true> FDEInfoList;
private:
status_t _ParseDebugInfoSection(uint8 _addressSize, bool isBigEndian);
status_t _ParseTypesSection(uint8 _addressSize, bool isBigEndian);
status_t _ParseFrameSection(ElfSection* section,
uint8 addressSize, bool isBigEndian,
bool ehFrame, FDEInfoList& infos);
status_t _ParseCompilationUnit(CompilationUnit* unit);
status_t _ParseTypeUnit(TypeUnit* unit);
status_t _ParseDebugInfoEntry(DataReader& dataReader,
BaseUnit* unit,
AbbreviationTable* abbreviationTable,
DebugInfoEntry*& _entry,
bool& _endOfEntryList, int level = 0);
status_t _FinishUnit(BaseUnit* unit);
status_t _ReadStringIndirect(BaseUnit* unit,
uint64 index, const char*& value) const;
status_t _ReadAddressIndirect(BaseUnit* unit,
uint64 index, uint64& value) const;
status_t _ParseEntryAttributes(DataReader& dataReader,
BaseUnit* unit,
DebugInfoEntry* entry,
AbbreviationEntry& abbreviationEntry);
status_t _ParseLineInfoFormatString(CompilationUnit* unit,
DataReader &dataReader,
uint64 format, const char*& value);
status_t _ParseLineInfoFormatUint(CompilationUnit* unit,
DataReader &dataReader,
uint64 format, uint64 &value);
status_t _ParseLineInfo(CompilationUnit* unit);
status_t _UnwindCallFrame(CompilationUnit* unit,
uint8 addressSize, bool isBigEndian,
DIESubprogram* subprogramEntry,
target_addr_t location,
const FDELookupInfo* info,
const DwarfTargetInterface* inputInterface,
DwarfTargetInterface* outputInterface,
target_addr_t& _framePointer);
status_t _ParseCIEHeader(ElfSection* debugFrameSection,
bool usingEHFrameSection,
CompilationUnit* unit,
uint8 addressSize, bool isBigEndian,
CfaContext& context, off_t cieOffset,
CIEAugmentation& cieAugmentation,
DataReader& reader,
off_t& _cieRemaining);
status_t _ParseFrameInfoInstructions(
CompilationUnit* unit, CfaContext& context,
DataReader& dataReader,
CIEAugmentation& cieAugmentation);
status_t _ParsePublicTypesInfo(uint8 _addressSize, bool isBigEndian);
status_t _ParsePublicTypesInfo(DataReader& dataReader,
bool dwarf64);
status_t _GetAbbreviationTable(off_t offset,
AbbreviationTable*& _table);
DebugInfoEntry* _ResolveReference(BaseUnit* unit,
uint64 offset,
uint8 refType) const;
status_t _GetLocationExpression(CompilationUnit* unit,
const LocationDescription* location,
target_addr_t instructionPointer,
const void*& _expression,
off_t& _length) const;
status_t _FindLocationExpression(CompilationUnit* unit,
uint64 offset, target_addr_t address,
const void*& _expression,
off_t& _length) const;
status_t _LocateDebugInfo(
BString& _requiredExternalFileName,
const char* locatedFilePath = NULL);
status_t _GetDebugInfoPath(const char* fileName,
BString& _infoPath) const;
TypeUnitTableEntry* _GetTypeUnit(uint64 signature) const;
CompilationUnit* _GetContainingCompilationUnit(
off_t refAddr) const;
FDELookupInfo* _GetContainingFDEInfo(
target_addr_t offset) const;
FDELookupInfo* _GetContainingFDEInfo(
target_addr_t offset,
const FDEInfoList& infoList) const;
private:
friend struct DwarfFile::ExpressionEvaluationContext;
private:
char* fName;
char* fAlternateName;
ElfFile* fElfFile;
ElfFile* fAlternateElfFile;
ElfSection* fDebugInfoSection;
ElfSection* fDebugAbbrevSection;
ElfSection* fDebugAddressSection;
ElfSection* fDebugStringSection;
ElfSection* fDebugStrOffsetsSection;
ElfSection* fDebugRangesSection;
ElfSection* fDebugLineSection;
ElfSection* fDebugLineStrSection;
ElfSection* fDebugFrameSection;
ElfSection* fEHFrameSection;
ElfSection* fDebugLocationSection;
ElfSection* fDebugPublicTypesSection;
ElfSection* fDebugTypesSection;
AbbreviationTableList fAbbreviationTables;
DebugInfoEntryFactory fDebugInfoFactory;
CompilationUnitList fCompilationUnits;
TypeUnitTable fTypeUnits;
FDEInfoList fDebugFrameInfos;
FDEInfoList fEHFrameInfos;
bool fTypesSectionRequired;
bool fFinished;
bool fItaniumEHFrameFormat;
status_t fFinishError;
};
#endif