diff -r 1af5c1be89f8 -r 92d87f2e53c2 tools/elf4rom/src/dwarfabbrevmanager.cpp --- /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 . +*/ + +#include +#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); +}