xref: /haiku/src/kits/debugger/dwarf/AbbreviationTable.cpp (revision b247f935d133a42c427cad8a759a1bf2f65bc290)
1 /*
2  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include "AbbreviationTable.h"
7 
8 #include <stdio.h>
9 
10 #include <new>
11 
12 
13 AbbreviationTable::AbbreviationTable(off_t offset)
14 	:
15 	fOffset(offset),
16 	fData(NULL),
17 	fSize(0)
18 {
19 }
20 
21 
22 AbbreviationTable::~AbbreviationTable()
23 {
24 }
25 
26 
27 status_t
28 AbbreviationTable::Init(const void* section, off_t sectionSize)
29 {
30 	if (fOffset < 0 || fOffset >= sectionSize)
31 		return B_BAD_DATA;
32 
33 	fData = (uint8*)section + fOffset;
34 	fSize = sectionSize - fOffset;
35 		// That's only the maximum size. Will be adjusted at the end.
36 
37 	status_t error = fEntryTable.Init();
38 	if (error != B_OK)
39 		return error;
40 
41 	DataReader abbrevReader(fData, fSize, 4);
42 		// address size doesn't matter here
43 
44 	while (true) {
45 		bool nullEntry;
46 		status_t error = _ParseAbbreviationEntry(abbrevReader, nullEntry);
47 		if (error != B_OK)
48 			return error;
49 
50 		if (nullEntry)
51 			break;
52 	}
53 
54 	fSize -= abbrevReader.BytesRemaining();
55 
56 	return B_OK;
57 }
58 
59 
60 bool
61 AbbreviationTable::GetAbbreviationEntry(uint32 code, AbbreviationEntry& entry)
62 {
63 	AbbreviationTableEntry* tableEntry = fEntryTable.Lookup(code);
64 	if (tableEntry == NULL)
65 		return false;
66 
67 	entry.SetTo(code, fData + tableEntry->offset, tableEntry->size);
68 	return true;
69 }
70 
71 
72 status_t
73 AbbreviationTable::_ParseAbbreviationEntry(DataReader& abbrevReader,
74 	bool& _nullEntry)
75 {
76 	uint32 code = abbrevReader.ReadUnsignedLEB128(0);
77 	if (code == 0) {
78 		if (abbrevReader.HasOverflow()) {
79 			fprintf(stderr, "Invalid abbreviation table 1!\n");
80 			return B_BAD_DATA;
81 		}
82 		_nullEntry = true;
83 		return B_OK;
84 	}
85 
86 	off_t remaining = abbrevReader.BytesRemaining();
87 
88 /*	uint32 tag =*/ abbrevReader.ReadUnsignedLEB128(0);
89 /*	uint8 hasChildren =*/ abbrevReader.Read<uint8>(DW_CHILDREN_no);
90 
91 //	printf("entry: %lu, tag: %lu, children: %d\n", code, tag,
92 //		hasChildren);
93 
94 	// parse attribute specifications
95 	while (true) {
96 		uint32 attributeName = abbrevReader.ReadUnsignedLEB128(0);
97 		uint32 attributeForm = abbrevReader.ReadUnsignedLEB128(0);
98 		if (abbrevReader.HasOverflow()) {
99 			fprintf(stderr, "Invalid abbreviation table 2!\n");
100 			return B_BAD_DATA;
101 		}
102 
103 		if (attributeName == 0 && attributeForm == 0)
104 			break;
105 
106 //		printf("  attr: name: %lu, form: %lu\n", attributeName,
107 //			attributeForm);
108 	}
109 
110 	// create the entry
111 	if (fEntryTable.Lookup(code) == NULL) {
112 		AbbreviationTableEntry* entry = new(std::nothrow)
113 			AbbreviationTableEntry(code, fSize - remaining,
114 				remaining - abbrevReader.BytesRemaining());
115 		if (entry == NULL)
116 			return B_NO_MEMORY;
117 
118 		fEntryTable.Insert(entry);
119 	} else {
120 		fprintf(stderr, "Duplicate abbreviation table entry %" B_PRIu32 "!\n",
121 			code);
122 	}
123 
124 	_nullEntry = false;
125 	return B_OK;
126 }
127