1/*
2 * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2012-2013, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef DWARF_FILE_H
7#define DWARF_FILE_H
8
9
10#include <ObjectList.h>
11#include <Referenceable.h>
12#include <util/DoublyLinkedList.h>
13#include <util/OpenHashTable.h>
14
15#include "DebugInfoEntries.h"
16#include "TypeUnit.h"
17
18
19struct AbbreviationEntry;
20class AbbreviationTable;
21class BVariant;
22class CfaContext;
23class CompilationUnit;
24class DataReader;
25class DwarfTargetInterface;
26class ElfFile;
27class ElfSection;
28class TargetAddressRangeList;
29class ValueLocation;
30
31
32class DwarfFile : public BReferenceable,
33	public DoublyLinkedListLinkImpl<DwarfFile> {
34public:
35								DwarfFile();
36								~DwarfFile();
37
38			status_t			StartLoading(const char* fileName,
39									BString& _requiredExternalFile);
40			status_t			Load(uint8 addressSize, bool isBigEndian,
41									const BString& externalFilePath);
42			status_t			FinishLoading(uint8 addressSize, bool isBigEndian);
43
44			const char*			Name() const		{ return fName; }
45			ElfFile*			GetElfFile() const	{ return fElfFile; }
46
47			bool				HasFrameInformation() const
48									{ return fDebugFrameSection != NULL
49										|| fEHFrameSection != NULL; }
50
51			int32				CountCompilationUnits() const;
52			CompilationUnit*	CompilationUnitAt(int32 index) const;
53			CompilationUnit*	CompilationUnitForDIE(
54									const DebugInfoEntry* entry) const;
55
56			TargetAddressRangeList* ResolveRangeList(CompilationUnit* unit,
57									uint64 offset) const;
58
59			status_t			UnwindCallFrame(CompilationUnit* unit,
60									uint8 addressSize, bool isBigEndian,
61									DIESubprogram* subprogramEntry,
62									target_addr_t location,
63									const DwarfTargetInterface* inputInterface,
64									DwarfTargetInterface* outputInterface,
65									target_addr_t& _framePointer);
66
67			status_t			EvaluateExpression(CompilationUnit* unit,
68									uint8 addressSize, bool isBigEndian,
69									DIESubprogram* subprogramEntry,
70									const void* expression,
71									off_t expressionLength,
72									const DwarfTargetInterface* targetInterface,
73									target_addr_t instructionPointer,
74									target_addr_t framePointer,
75									target_addr_t valueToPush, bool pushValue,
76									target_addr_t& _result);
77			status_t			ResolveLocation(CompilationUnit* unit,
78									uint8 addressSize, bool isBigEndian,
79									DIESubprogram* subprogramEntry,
80									const LocationDescription* location,
81									const DwarfTargetInterface* targetInterface,
82									target_addr_t instructionPointer,
83									target_addr_t objectPointer,
84									bool hasObjectPointer,
85									target_addr_t framePointer,
86									target_addr_t relocationDelta,
87									ValueLocation& _result);
88									// The returned location will have DWARF
89									// semantics regarding register numbers and
90									// bit offsets/sizes (cf. bit pieces).
91
92			status_t			EvaluateConstantValue(CompilationUnit* unit,
93									uint8 addressSize, bool isBigEndian,
94									DIESubprogram* subprogramEntry,
95									const ConstantAttributeValue* value,
96									const DwarfTargetInterface* targetInterface,
97									target_addr_t instructionPointer,
98									target_addr_t framePointer,
99									BVariant& _result);
100			status_t			EvaluateDynamicValue(CompilationUnit* unit,
101									uint8 addressSize, bool isBigEndian,
102									DIESubprogram* subprogramEntry,
103									const DynamicAttributeValue* value,
104									const DwarfTargetInterface* targetInterface,
105									target_addr_t instructionPointer,
106									target_addr_t framePointer,
107									BVariant& _result, DIEType** _type = NULL);
108
109private:
110			struct ExpressionEvaluationContext;
111			struct FDEAugmentation;
112			struct CIEAugmentation;
113			struct FDELookupInfo;
114
115			typedef DoublyLinkedList<AbbreviationTable> AbbreviationTableList;
116			typedef BObjectList<CompilationUnit> CompilationUnitList;
117			typedef BOpenHashTable<TypeUnitTableHashDefinition> TypeUnitTable;
118			typedef BObjectList<FDELookupInfo> FDEInfoList;
119
120private:
121			status_t			_ParseDebugInfoSection(uint8 _addressSize, bool isBigEndian);
122			status_t			_ParseTypesSection(uint8 _addressSize, bool isBigEndian);
123			status_t			_ParseFrameSection(ElfSection* section,
124									uint8 addressSize, bool isBigEndian,
125									bool ehFrame, FDEInfoList& infos);
126			status_t			_ParseCompilationUnit(CompilationUnit* unit);
127			status_t			_ParseTypeUnit(TypeUnit* unit);
128			status_t			_ParseDebugInfoEntry(DataReader& dataReader,
129									BaseUnit* unit,
130									AbbreviationTable* abbreviationTable,
131									DebugInfoEntry*& _entry,
132									bool& _endOfEntryList, int level = 0);
133			status_t			_FinishUnit(BaseUnit* unit);
134			status_t			_ReadStringIndirect(BaseUnit* unit,
135									uint64 index, const char*& value) const;
136			status_t			_ReadAddressIndirect(BaseUnit* unit,
137									uint64 index, uint64& value) const;
138			status_t			_ParseEntryAttributes(DataReader& dataReader,
139									BaseUnit* unit,
140									DebugInfoEntry* entry,
141									AbbreviationEntry& abbreviationEntry);
142
143			status_t			_ParseLineInfoFormatString(CompilationUnit* unit,
144									DataReader &dataReader,
145									uint64 format, const char*& value);
146			status_t			_ParseLineInfoFormatUint(CompilationUnit* unit,
147									DataReader &dataReader,
148									uint64 format, uint64 &value);
149			status_t			_ParseLineInfo(CompilationUnit* unit);
150
151			status_t			_UnwindCallFrame(CompilationUnit* unit,
152									uint8 addressSize, bool isBigEndian,
153									DIESubprogram* subprogramEntry,
154									target_addr_t location,
155									const FDELookupInfo* info,
156									const DwarfTargetInterface* inputInterface,
157									DwarfTargetInterface* outputInterface,
158									target_addr_t& _framePointer);
159
160			status_t			_ParseCIEHeader(ElfSection* debugFrameSection,
161									bool usingEHFrameSection,
162									CompilationUnit* unit,
163									uint8 addressSize, bool isBigEndian,
164									CfaContext& context, off_t cieOffset,
165									CIEAugmentation& cieAugmentation,
166									DataReader& reader,
167									off_t& _cieRemaining);
168			status_t			_ParseFrameInfoInstructions(
169									CompilationUnit* unit, CfaContext& context,
170									DataReader& dataReader,
171									CIEAugmentation& cieAugmentation);
172
173			status_t			_ParsePublicTypesInfo(uint8 _addressSize, bool isBigEndian);
174			status_t			_ParsePublicTypesInfo(DataReader& dataReader,
175									bool dwarf64);
176
177			status_t			_GetAbbreviationTable(off_t offset,
178									AbbreviationTable*& _table);
179
180			DebugInfoEntry*		_ResolveReference(BaseUnit* unit,
181									uint64 offset,
182									uint8 refType) const;
183
184			status_t			_GetLocationExpression(CompilationUnit* unit,
185									const LocationDescription* location,
186									target_addr_t instructionPointer,
187									const void*& _expression,
188									off_t& _length) const;
189			status_t			_FindLocationExpression(CompilationUnit* unit,
190									uint64 offset, target_addr_t address,
191									const void*& _expression,
192									off_t& _length) const;
193
194			status_t			_LocateDebugInfo(
195									BString& _requiredExternalFileName,
196									const char* locatedFilePath = NULL);
197
198			status_t			_GetDebugInfoPath(const char* fileName,
199									BString& _infoPath) const;
200
201			TypeUnitTableEntry*	_GetTypeUnit(uint64 signature) const;
202			CompilationUnit*	_GetContainingCompilationUnit(
203									off_t refAddr) const;
204
205			FDELookupInfo*		_GetContainingFDEInfo(
206									target_addr_t offset) const;
207
208			FDELookupInfo*		_GetContainingFDEInfo(
209									target_addr_t offset,
210									const FDEInfoList& infoList) const;
211
212private:
213			friend struct 		DwarfFile::ExpressionEvaluationContext;
214
215private:
216			char*				fName;
217			char*				fAlternateName;
218			ElfFile*			fElfFile;
219			ElfFile*			fAlternateElfFile;
220			ElfSection*			fDebugInfoSection;
221			ElfSection*			fDebugAbbrevSection;
222			ElfSection*			fDebugAddressSection;
223			ElfSection*			fDebugStringSection;
224			ElfSection*			fDebugStrOffsetsSection;
225			ElfSection*			fDebugRangesSection;
226			ElfSection*			fDebugLineSection;
227			ElfSection*			fDebugLineStrSection;
228			ElfSection*			fDebugFrameSection;
229			ElfSection*			fEHFrameSection;
230			ElfSection*			fDebugLocationSection;
231			ElfSection*			fDebugPublicTypesSection;
232			ElfSection*			fDebugTypesSection;
233			AbbreviationTableList fAbbreviationTables;
234			DebugInfoEntryFactory fDebugInfoFactory;
235			CompilationUnitList	fCompilationUnits;
236			TypeUnitTable		fTypeUnits;
237			FDEInfoList			fDebugFrameInfos;
238			FDEInfoList			fEHFrameInfos;
239			bool				fTypesSectionRequired;
240			bool				fFinished;
241			bool				fItaniumEHFrameFormat;
242			status_t			fFinishError;
243};
244
245
246#endif	// DWARF_FILE_H
247