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