--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfabbrevmanager.cpp Fri Jan 15 09:07:44 2010 +0000
@@ -0,0 +1,161 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfAbbrevManager::iAbbrevSectionName(".debug_abbrev");
+void InfoContext::SetAbbrevOffset(size_t offset){
+ if (!iContextValid){
+ cerr << "Error: runtime error - SetAbbrevOffset called on invalid InfoContext\n";
+ exit(EXIT_FAILURE);
+ }
+
+ if (iAbbrevOffset == offset)
+ return;
+ // Save current entry (in particular the cursor value
+ if (iAbbrevOffset != 0xffffffff){
+ AbbrevOffsetMap::iterator old = iMap.find(iAbbrevOffset);
+ if (old != iMap.end())
+ old->second.iCursor = iAbbrevMapEntry.iCursor;
+ else
+ iMap[iAbbrevOffset] = iAbbrevMapEntry;
+ }
+
+ AbbrevOffsetMap::iterator i = iMap.find(offset);
+ if (i != iMap.end()){
+ iAbbrevMapEntry = i->second;
+ } else {
+ AbbrevMap * newMap = new AbbrevMap;
+ new (&iAbbrevMapEntry) AbbrevMapEntry(iSectionStart + offset, newMap);
+ iMap[offset] = iAbbrevMapEntry;
+ }
+ iAbbrevOffset = offset;
+}
+
+DebugAbbrev & InfoContext::GetAbbrev(Dwarf_Word aCode){
+ AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode);
+ if (i != iAbbrevMapEntry.iMap->end()){
+ return i->second;
+ } else {
+ return FindAbbrev(aCode);
+ }
+}
+
+DebugAbbrev & InfoContext::FindAbbrev(Dwarf_Word aCode){
+ // retrieve cursor for where we've scanned so far.
+ Dwarf_Byte_Ptr p = iAbbrevMapEntry.iCursor;
+ // NB. error if we don't find the code before section end
+ Dwarf_Byte_Ptr lim = iSectionEnd;
+ bool error = false;
+ bool found = false;
+ size_t leb128_length;
+
+ while (!found && (p < lim)){
+
+#define CHECK_ABBREV_LIM(p,l,e) { if ((p)>(l)){ e = true; break;} }
+#define CHECK_DECODE_ULEB128(v,p,n,l,e) \
+ DECODE_ULEB128(v,p,n)\
+ CHECK_ABBREV_LIM(p,l,e);
+
+ size_t count = 0;
+ //CHECK_DECODE_ULEB128(abbrev_code,p,leb128_length,lim, error);
+ Dwarf_Word abbrev_code = DwarfSectionManager::DecodeUnsignedLeb128(p, leb128_length);
+ p += leb128_length;
+ if (p>lim){
+ error = true;
+ break;
+ }
+ // Might as well error here since either we've found the NULL abbrev
+ if (abbrev_code == 0) {
+ DebugAbbrev abbr(0, 0, 0, NULL, NULL);
+ (*iAbbrevMapEntry.iMap)[0] = abbr;
+ if (aCode == 0) // ??? why would it
+ found = true;
+ }
+
+ CHECK_DECODE_ULEB128(tag,p,leb128_length,lim, error);
+ // don't care about 'has child'
+ p++;
+ CHECK_ABBREV_LIM(p,lim,error);
+ Dwarf_Byte_Ptr raw_attr_ptr = p;
+ Dwarf_Word attr;
+ Dwarf_Word attr_form;
+ do {
+ CHECK_DECODE_ULEB128(a,p,leb128_length,lim, error);
+ attr = a;
+ CHECK_DECODE_ULEB128(f,p,leb128_length,lim, error);
+ attr_form = f;
+
+ if (attr != 0)
+ count++;
+
+ } while (attr != 0 || attr_form != 0);
+
+ DebugAbbrevAttrForm * list = new DebugAbbrevAttrForm[count];
+ Dwarf_Byte_Ptr q=raw_attr_ptr;
+ for (size_t i=0 ; i < count ; i++){
+ list[i].iAttr = ULEB128(q,leb128_length);
+ list[i].iForm = ULEB128(q,leb128_length);
+ }
+ DebugAbbrev abbr(abbrev_code, tag, count, raw_attr_ptr, list);
+ (*iAbbrevMapEntry.iMap)[abbrev_code] = abbr;
+ if (abbrev_code == aCode)
+ found = true;
+ }
+ if (error){
+ cerr << "Error: corrupt .debug_abbrev section\n";
+ exit(EXIT_FAILURE);
+ }
+ if (!found){
+ cerr << "Error: abbrev code not found in .debug_abbrev section\n";
+ exit(EXIT_FAILURE);
+ }
+ // record where we scanned to
+ iAbbrevMapEntry.iCursor = p;
+ // get the
+ AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode);
+ if (i == iAbbrevMapEntry.iMap->end()){
+ cerr << "Error: Runtime error processing .debug_abbrev section\n";
+ exit(EXIT_FAILURE);
+ }
+
+ return i->second;
+}
+
+void DwarfAbbrevManager::StartContext(PathName & aName){
+ Dwarf_Byte_Ptr section = GetSection(aName);
+ iInfoContext.Init(section, section + GetSectionSize(aName), GetSectionOffset(aName));
+}
+
+void DwarfAbbrevManager::EndContext(){
+ iInfoContext.Reset();
+}
+
+void DwarfAbbrevManager::SetContextAbbrevOffset(Uint32 offset){
+ iInfoContext.SetAbbrevOffset(offset);
+}
+
+size_t DwarfAbbrevManager::GetContextSectionOffset(){
+ return iInfoContext.GetSectionOffset();
+}
+
+DebugAbbrev & DwarfAbbrevManager::GetAbbrev(Dwarf_Word aCode){
+ return iInfoContext.GetAbbrev(aCode);
+}