1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef ABBREVIATION_TABLE_H
6#define ABBREVIATION_TABLE_H
7
8#include <util/DoublyLinkedList.h>
9#include <util/OpenHashTable.h>
10
11#include "DataReader.h"
12#include "Dwarf.h"
13
14
15struct AbbreviationTableEntry {
16	uint32					code;
17	off_t					offset;
18	off_t					size;
19	AbbreviationTableEntry*	next;
20
21	AbbreviationTableEntry(uint32 code, off_t offset, off_t size)
22		:
23		code(code),
24		offset(offset),
25		size(size)
26	{
27	}
28};
29
30
31struct AbbreviationEntry {
32	AbbreviationEntry()
33	{
34	}
35
36	AbbreviationEntry(uint32 code, const void* data, off_t size)
37	{
38		SetTo(code, data, size);
39	}
40
41	void SetTo(uint32 code, const void* data, off_t size)
42	{
43		fCode = code;
44		fAttributesReader.SetTo(data, size, 4, false);
45			// address size and endianness don't matter here
46		fTag = fAttributesReader.ReadUnsignedLEB128(0);
47		fHasChildren = fAttributesReader.Read<uint8>(0);
48		fData = fAttributesReader.Data();
49		fSize = fAttributesReader.BytesRemaining();
50	}
51
52	uint32	Code() const		{ return fCode; }
53	uint32	Tag() const			{ return fTag; }
54	bool	HasChildren() const	{ return fHasChildren == DW_CHILDREN_yes; }
55
56	bool GetNextAttribute(uint32& name, uint32& form, int32& implicitConst)
57	{
58		name = fAttributesReader.ReadUnsignedLEB128(0);
59		form = fAttributesReader.ReadUnsignedLEB128(0);
60		if (form == DW_FORM_implicit_const)
61			implicitConst = fAttributesReader.ReadSignedLEB128(0);
62		return !fAttributesReader.HasOverflow() && (name != 0 || form != 0);
63	}
64
65private:
66	uint32		fCode;
67	const void*	fData;
68	off_t		fSize;
69	uint32		fTag;
70	uint8		fHasChildren;
71	DataReader	fAttributesReader;
72};
73
74
75struct AbbreviationTableHashDefinition {
76	typedef uint32					KeyType;
77	typedef	AbbreviationTableEntry	ValueType;
78
79	size_t HashKey(uint32 key) const
80	{
81		return (size_t)key;
82	}
83
84	size_t Hash(AbbreviationTableEntry* value) const
85	{
86		return HashKey(value->code);
87	}
88
89	bool Compare(uint32 key, AbbreviationTableEntry* value) const
90	{
91		return value->code == key;
92	}
93
94	AbbreviationTableEntry*& GetLink(AbbreviationTableEntry* value) const
95	{
96		return value->next;
97	}
98};
99
100
101class AbbreviationTable : public DoublyLinkedListLinkImpl<AbbreviationTable> {
102public:
103								AbbreviationTable(off_t offset);
104								~AbbreviationTable();
105
106			status_t			Init(const void* section, off_t sectionSize);
107
108			off_t				Offset() const	{ return fOffset; }
109
110			bool				GetAbbreviationEntry(uint32 code,
111									AbbreviationEntry& entry);
112
113private:
114			typedef BOpenHashTable<AbbreviationTableHashDefinition> EntryTable;
115
116private:
117			status_t			_ParseAbbreviationEntry(
118									DataReader& abbrevReader, bool& _nullEntry);
119
120private:
121			off_t				fOffset;
122			const uint8*		fData;
123			off_t				fSize;
124			EntryTable			fEntryTable;
125};
126
127
128#endif	// ABBREVIATION_TABLE_H
129