tools/elf4rom/src/dwarfabbrevmanager.cpp
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * This program is free software: you can redistribute it and/or modify
       
     6 * it under the terms of the GNU Lesser General Public License as published by
       
     7 * the Free Software Foundation, either version 3 of the License, or
       
     8 * (at your option) any later version.
       
     9 *
       
    10 * This program is distributed in the hope that it will be useful,
       
    11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    13 * GNU Lesser General Public License for more details.
       
    14 * 
       
    15 * You should have received a copy of the GNU Lesser General Public License
       
    16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    17 */
       
    18 
       
    19 #include <iostream>
       
    20 #include "dwarfmanager.h"
       
    21 #include "inputfile.h"
       
    22 
       
    23 const string DwarfAbbrevManager::iAbbrevSectionName(".debug_abbrev");
       
    24 void InfoContext::SetAbbrevOffset(size_t offset){
       
    25 	if (!iContextValid){
       
    26 		cerr << "Error: runtime error - SetAbbrevOffset called on invalid InfoContext\n";
       
    27 		exit(EXIT_FAILURE);
       
    28 	}
       
    29 	
       
    30 	if (iAbbrevOffset == offset)
       
    31 			return;
       
    32 	// Save current entry (in particular the cursor value
       
    33 	if (iAbbrevOffset != 0xffffffff){
       
    34 		AbbrevOffsetMap::iterator old = iMap.find(iAbbrevOffset);
       
    35 		if (old != iMap.end())
       
    36 			old->second.iCursor = iAbbrevMapEntry.iCursor;
       
    37 		else
       
    38 			iMap[iAbbrevOffset] = iAbbrevMapEntry;
       
    39 	}
       
    40 	
       
    41 	AbbrevOffsetMap::iterator i = iMap.find(offset);
       
    42 	if (i != iMap.end()){
       
    43 		iAbbrevMapEntry = i->second;
       
    44 	} else {
       
    45 		AbbrevMap * newMap = new AbbrevMap;
       
    46 		new (&iAbbrevMapEntry) AbbrevMapEntry(iSectionStart + offset, newMap);
       
    47 		iMap[offset] = iAbbrevMapEntry;
       
    48 	}
       
    49 	iAbbrevOffset = offset;
       
    50 }
       
    51 
       
    52 DebugAbbrev & InfoContext::GetAbbrev(Dwarf_Word aCode){
       
    53 	AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode);
       
    54 	if (i != iAbbrevMapEntry.iMap->end()){
       
    55 			return i->second;
       
    56 	} else {
       
    57 		return FindAbbrev(aCode);
       
    58 	}
       
    59 }
       
    60 
       
    61 DebugAbbrev & InfoContext::FindAbbrev(Dwarf_Word aCode){
       
    62 	// retrieve cursor for where we've scanned so far.
       
    63 	Dwarf_Byte_Ptr p = iAbbrevMapEntry.iCursor;
       
    64 	// NB. error if we don't find the code before section end
       
    65 	Dwarf_Byte_Ptr lim = iSectionEnd;
       
    66 	bool error = false;
       
    67 	bool found = false;
       
    68 	size_t leb128_length;
       
    69 
       
    70 	while (!found && (p < lim)){
       
    71 		
       
    72 #define CHECK_ABBREV_LIM(p,l,e) { if ((p)>(l)){ e = true; break;} }
       
    73 #define CHECK_DECODE_ULEB128(v,p,n,l,e) \
       
    74 			DECODE_ULEB128(v,p,n)\
       
    75 			CHECK_ABBREV_LIM(p,l,e);
       
    76 		
       
    77 		size_t count = 0;
       
    78 		//CHECK_DECODE_ULEB128(abbrev_code,p,leb128_length,lim, error);
       
    79 		Dwarf_Word abbrev_code = DwarfSectionManager::DecodeUnsignedLeb128(p, leb128_length);
       
    80 		p += leb128_length;
       
    81 		if (p>lim){ 
       
    82 			error = true; 
       
    83 			break;
       
    84 		}
       
    85 		// Might as well error here since either we've found the NULL abbrev
       
    86 	    if (abbrev_code == 0) {
       
    87 	    	DebugAbbrev abbr(0, 0, 0, NULL, NULL);
       
    88 	    	(*iAbbrevMapEntry.iMap)[0] = abbr;
       
    89 	    	if (aCode == 0) // ??? why would it
       
    90 	    		found = true;
       
    91 	    }
       
    92 
       
    93 		CHECK_DECODE_ULEB128(tag,p,leb128_length,lim, error);
       
    94 		// don't care about 'has child'
       
    95 	    p++;
       
    96 	    CHECK_ABBREV_LIM(p,lim,error);
       
    97 	    Dwarf_Byte_Ptr raw_attr_ptr = p;
       
    98 	    Dwarf_Word attr;
       
    99 	    Dwarf_Word attr_form;
       
   100 	    do {
       
   101 	    	CHECK_DECODE_ULEB128(a,p,leb128_length,lim, error);
       
   102 	    	attr = a;
       
   103 	    	CHECK_DECODE_ULEB128(f,p,leb128_length,lim, error);
       
   104 	    	attr_form = f;
       
   105 
       
   106 	    	if (attr != 0)
       
   107 	    		count++;
       
   108 
       
   109 	    } while (attr != 0 || attr_form != 0);
       
   110 	    
       
   111 		DebugAbbrevAttrForm * list = new DebugAbbrevAttrForm[count];
       
   112 		Dwarf_Byte_Ptr q=raw_attr_ptr;
       
   113 		for (size_t i=0 ; i < count ; i++){
       
   114 			list[i].iAttr = ULEB128(q,leb128_length);
       
   115 			list[i].iForm = ULEB128(q,leb128_length);
       
   116 		}
       
   117 	    DebugAbbrev abbr(abbrev_code, tag, count, raw_attr_ptr, list);
       
   118 	    (*iAbbrevMapEntry.iMap)[abbrev_code] = abbr;
       
   119 	    if (abbrev_code == aCode)
       
   120 	    	found = true;
       
   121 	}
       
   122 	if (error){
       
   123 		cerr << "Error: corrupt .debug_abbrev section\n";
       
   124 		exit(EXIT_FAILURE);
       
   125 	}
       
   126 	if (!found){
       
   127 		cerr << "Error: abbrev code not found in .debug_abbrev section\n";
       
   128 		exit(EXIT_FAILURE);
       
   129 	}
       
   130 	// record where we scanned to
       
   131 	iAbbrevMapEntry.iCursor = p;
       
   132 	// get the 
       
   133 	AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode);
       
   134 	if (i == iAbbrevMapEntry.iMap->end()){
       
   135 		cerr << "Error: Runtime error processing .debug_abbrev section\n";
       
   136 		exit(EXIT_FAILURE);
       
   137 	} 
       
   138 
       
   139 	return i->second;
       
   140 }
       
   141 
       
   142 void DwarfAbbrevManager::StartContext(PathName & aName){
       
   143 	Dwarf_Byte_Ptr section = GetSection(aName);
       
   144 	iInfoContext.Init(section, section + GetSectionSize(aName), GetSectionOffset(aName));
       
   145 }
       
   146 
       
   147 void DwarfAbbrevManager::EndContext(){
       
   148 	iInfoContext.Reset();
       
   149 }
       
   150 
       
   151 void DwarfAbbrevManager::SetContextAbbrevOffset(Uint32 offset){
       
   152 	iInfoContext.SetAbbrevOffset(offset);
       
   153 }
       
   154 
       
   155 size_t DwarfAbbrevManager::GetContextSectionOffset(){
       
   156 	return iInfoContext.GetSectionOffset();
       
   157 }
       
   158 
       
   159 DebugAbbrev & DwarfAbbrevManager::GetAbbrev(Dwarf_Word aCode){
       
   160 	return iInfoContext.GetAbbrev(aCode);
       
   161 }