tools/elf4rom/src/dwarfinfomanager.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 <string.h>
       
    20 #include <iostream>
       
    21 #include <cassert>
       
    22 
       
    23 #include "dwarfmanager.h"
       
    24 #include "inputfile.h"
       
    25 
       
    26 const string DwarfInfoManager::iInfoSectionName(".debug_info");
       
    27 
       
    28 void DwarfInfoManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
       
    29 	iDwarfAbbrevManager.StartContext(aPair.iXIPFileDetails.iElfFile);
       
    30 	Dwarf_Byte_Ptr p = aStart;
       
    31 	Dwarf_Byte_Ptr e = aEnd;
       
    32 	while (p < e) {
       
    33 		p = ProcessCU(aPair, p, e);
       
    34 	}
       
    35 	iDwarfAbbrevManager.EndContext();
       
    36 }
       
    37 
       
    38 #define READ_DWARF_VAL(v,t,p) t v = *((t *)p); p += sizeof(t);
       
    39 Dwarf_Byte_Ptr DwarfInfoManager::ProcessCU(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){
       
    40 	Dwarf_Byte_Ptr p = s;
       
    41 	//Read the CU header info
       
    42 	// first check whether we're dealing with 32bit or 64 bit DWARF
       
    43 	
       
    44 	// TODO: must abstract over base types e.g uint32 etc.
       
    45 	// TODO: this might not be 4 byte aligned and so could cause problems on some
       
    46 	// architectures
       
    47 	READ_DWARF_VAL(len, Uint32, p);
       
    48 	if (len >= 0xfffffff0u){
       
    49 		cerr << "Error: 64 bit DWARF not supported\n";
       
    50 		exit(EXIT_FAILURE);
       
    51 	}
       
    52 	iLocalLength = len;
       
    53 	Dwarf_Byte_Ptr end = p + len;
       
    54 	// TODO: make sensitive to dwarf version number?
       
    55 	READ_DWARF_VAL(version, Dwarf_Half, p);
       
    56 	Uint32 abbrevOffset = *((Uint32 *)p);
       
    57 	// update the offset into the abbrev table
       
    58 	*((Uint32 *)p) = (Uint32)(abbrevOffset + iDwarfAbbrevManager.GetContextSectionOffset());
       
    59 	p += sizeof(Uint32);
       
    60 	READ_DWARF_VAL(address_size, Byte, p);
       
    61 	
       
    62 	// TODO: if this isn't 4 we're doomed aren't we?
       
    63 	iAddressSize = address_size;
       
    64 	
       
    65 	iDwarfAbbrevManager.SetContextAbbrevOffset(abbrevOffset);
       
    66 	
       
    67 	// now process each DIE until end.
       
    68 	while (p < end) {
       
    69 		p = ProcessDIE(aPair, p, end);
       
    70 	}
       
    71 
       
    72 	return p;
       
    73 }
       
    74 
       
    75 void NoteProducer(FileShdrPair & aPair, Dwarf_Byte_Ptr aPtr, Dwarf_Unsigned aForm){
       
    76 
       
    77 	switch (aForm){
       
    78 	case DW_FORM_string:{
       
    79 		const char * producer = (const char *)aPtr;
       
    80 		const char * RvctProducer = "ARM/Thumb C/C++ Compiler, RVCT";
       
    81 		const size_t RvctProducerLength = strlen(RvctProducer);
       
    82 		const char * GccProducer = "GNU C++";
       
    83 		const size_t GccProducerLength = strlen(GccProducer);
       
    84 		if (!strncmp(producer, RvctProducer, RvctProducerLength))
       
    85 			aPair.iXIPFileDetails.iRVCTProduced = true;
       
    86 		if (!strncmp(producer, GccProducer, GccProducerLength))
       
    87 			aPair.iXIPFileDetails.iGCCProduced = true;		
       
    88 		return;
       
    89 	}
       
    90     case DW_FORM_indirect: {
       
    91 	    size_t indir_len = 0;
       
    92 	    Dwarf_Unsigned form_indirect = DwarfSectionManager::DecodeUnsignedLeb128(aPtr, indir_len);
       
    93 	    if (form_indirect == DW_FORM_indirect) {
       
    94 			/* 	Eek, should never happen, will get warned later */
       
    95 	    	return;
       
    96 	    }
       
    97 	    return NoteProducer(aPair, aPtr+indir_len, form_indirect);
       
    98 		}
       
    99     case DW_FORM_strp:
       
   100     	// TODO - We need to get the string table for this -- 
       
   101     	return;
       
   102 	}
       
   103 }
       
   104 
       
   105 Dwarf_Byte_Ptr DwarfInfoManager::ProcessDIE(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){
       
   106 	Dwarf_Byte_Ptr info_ptr = s;
       
   107     size_t leb128_length;
       
   108     
       
   109     Dwarf_Word abbrev_code = DecodeUnsignedLeb128(info_ptr, leb128_length);
       
   110     info_ptr += leb128_length;
       
   111     if (abbrev_code == 0) {
       
   112     	return info_ptr;
       
   113     }
       
   114 
       
   115     DebugAbbrev & abbrev = iDwarfAbbrevManager.GetAbbrev(abbrev_code);
       
   116  
       
   117     //cout << "Tag = " << GetDwarfTag(abbrev.iTag) << " Code = " << abbrev_code <<  " num attrs = " << abbrev.iCount << endl;
       
   118    
       
   119     for (size_t i = 0; i < abbrev.iCount; i++){
       
   120     	size_t attr = abbrev.iParsed[i].iAttr;
       
   121     	Dwarf_Unsigned form = abbrev.iParsed[i].iForm;
       
   122     	//cout << "\tAttr " << GetDwarfAttr(attr) << " Form " << GetDwarfForm(form) << "\n";
       
   123     	
       
   124     	// record anything interesting about the producer here.
       
   125     	if (attr == DW_AT_producer)
       
   126     		NoteProducer(aPair, info_ptr, form);
       
   127 
       
   128     	if (attr > DW_AT_recursive)
       
   129     		info_ptr = DefaultInfoEditFn(*this, info_ptr, form, aPair);
       
   130     	else
       
   131     		info_ptr = iInfoEditFn[attr](*this, info_ptr, form, aPair);
       
   132     }
       
   133     
       
   134 	return info_ptr;
       
   135 }
       
   136 
       
   137 
       
   138 size_t DwarfInfoManager::SizeOfDieValue(Dwarf_Half aForm, Dwarf_Byte_Ptr aPtr){
       
   139     Dwarf_Unsigned length = 0;
       
   140     size_t leb128_length = 0;
       
   141     size_t ret_value = 0;
       
   142 
       
   143     switch (aForm) {
       
   144 
       
   145     default:			/* Handles form = 0. */
       
   146     	return (aForm);
       
   147 
       
   148     case DW_FORM_addr:
       
   149     	return iAddressSize;
       
   150 
       
   151     case DW_FORM_ref_addr:
       
   152     	// TODO: sort this out
       
   153     	return 4;  // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf
       
   154 
       
   155     case DW_FORM_block1:
       
   156     	return (*aPtr) + 1;
       
   157 
       
   158     case DW_FORM_block2:
       
   159     	ret_value = READ_UNALIGNED2(aPtr) + 2;
       
   160 		return ret_value;
       
   161 
       
   162     case DW_FORM_block4:
       
   163     	ret_value = READ_UNALIGNED4(aPtr) + 4;
       
   164     	return ret_value;
       
   165 
       
   166     case DW_FORM_data1:
       
   167 	return 1;
       
   168 
       
   169     case DW_FORM_data2:
       
   170 	return 2;
       
   171 
       
   172     case DW_FORM_data4:
       
   173 	return 4;
       
   174 
       
   175     case DW_FORM_data8:
       
   176 	return 8;
       
   177 
       
   178     case DW_FORM_string:
       
   179 	return (strlen((char *) aPtr) + 1);
       
   180 
       
   181     case DW_FORM_block:
       
   182     	length = DecodeUnsignedLeb128(aPtr, leb128_length);
       
   183     	return length + leb128_length;
       
   184 
       
   185     case DW_FORM_flag:
       
   186 	return 1;
       
   187 
       
   188     case DW_FORM_ref_udata:
       
   189     	DecodeUnsignedLeb128(aPtr, leb128_length);
       
   190 	return leb128_length;
       
   191 
       
   192     case DW_FORM_indirect: {
       
   193 	    size_t indir_len = 0;
       
   194 	    Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   195 	    if (form_indirect == DW_FORM_indirect) {
       
   196 			/* 	Eek, should never happen */
       
   197 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   198 	    }
       
   199 	    return indir_len + SizeOfDieValue(form_indirect, aPtr+indir_len);
       
   200 	}
       
   201 
       
   202     case DW_FORM_ref1:
       
   203     	return 1;
       
   204 
       
   205     case DW_FORM_ref2:
       
   206     	return 2;
       
   207 
       
   208     case DW_FORM_ref4:
       
   209     	return 4;
       
   210 
       
   211     case DW_FORM_ref8:
       
   212     	return 8;
       
   213 
       
   214     case DW_FORM_sdata:
       
   215     	DecodeSignedLeb128(aPtr, leb128_length);
       
   216     	return leb128_length;
       
   217 
       
   218     case DW_FORM_strp:
       
   219     	// TODO: sort this out
       
   220     	return 4;  // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf
       
   221 
       
   222     case DW_FORM_udata:
       
   223     	DecodeUnsignedLeb128(aPtr, leb128_length);
       
   224     	return leb128_length;
       
   225     }
       
   226 }
       
   227 
       
   228 Dwarf_Byte_Ptr DwarfInfoManager::DefaultInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   229 	return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   230 }
       
   231 
       
   232 Dwarf_Byte_Ptr DwarfInfoManager::ErrorInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   233 	cerr << "Error: Undefined DW_FORM value: " << aForm << "\n" ;
       
   234 	exit(EXIT_FAILURE);
       
   235 	return aPtr;
       
   236 }
       
   237 
       
   238 // TODO: implicitly only deals with 32-bit DWARF
       
   239 // Called from other edit functions to deal with blocks that contain location expressions.
       
   240 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocExpr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   241 	Dwarf_Unsigned length = 0;
       
   242 	bool locExpr = false;
       
   243 	Dwarf_Byte_Ptr block = aPtr;
       
   244 	if (aForm == DW_FORM_block1) {
       
   245 		locExpr = true;
       
   246 		length = block[0];
       
   247 		block++;
       
   248 		aPtr += (length + 1); 
       
   249 	} else if (aForm == DW_FORM_block2) {
       
   250 		locExpr = true;
       
   251 		length = READ_UNALIGNED2(block);
       
   252 		block += 2;
       
   253 		aPtr += (length + 2); 
       
   254 	} else if (aForm == DW_FORM_block4) {
       
   255 		locExpr = true;
       
   256 		length = READ_UNALIGNED4(block);
       
   257 		block += 4;
       
   258 		aPtr += (length + 4); 
       
   259 	} else if (aForm == DW_FORM_block) {
       
   260 		locExpr = true;
       
   261 		size_t leb_length = 0;
       
   262 		length = DecodeUnsignedLeb128(block, leb_length);
       
   263 		block += leb_length;
       
   264 		aPtr += (length + leb_length); 
       
   265 	}
       
   266 
       
   267 	if (locExpr){		
       
   268 		EditLocationExpression (block, aManager.iAddressSize, length, aPair);
       
   269 		return aPtr;
       
   270 	} else if (aForm == DW_FORM_indirect){
       
   271 	    size_t indir_len = 0;
       
   272 	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   273 	    if (form_indirect == DW_FORM_indirect) {
       
   274 			/* 	Eek, should never happen */
       
   275 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   276 	    }
       
   277 	    return InfoEditLocExpr(aManager, aPtr+indir_len, form_indirect, aPair);
       
   278 	
       
   279 	} else
       
   280 		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   281 }
       
   282 // TODO: implicitly only deals with 32-bit DWARF
       
   283 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditAddress(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   284 	if (aForm == DW_FORM_addr){
       
   285 		LinearAddr addr = READ_UNALIGNED4(aPtr);
       
   286 		LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr);
       
   287 		WRITE_UNALIGNED4(aPtr, relocatedAddr);
       
   288 		return aPtr + 4;
       
   289 	} else if (aForm == DW_FORM_indirect){
       
   290 	    size_t indir_len = 0;
       
   291 	    Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   292 	    if (form_indirect == DW_FORM_indirect) {
       
   293 			/* 	Eek, should never happen */
       
   294 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   295 	    }
       
   296 	    return InfoEditAddress(aManager, aPtr+indir_len, form_indirect, aPair);
       
   297 	
       
   298 	} else
       
   299 		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   300 }
       
   301 
       
   302 // TODO: implicitly only deals with 32-bit DWARF
       
   303 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLinePtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   304 	if (aForm == DW_FORM_data4){
       
   305 		size_t offset = READ_UNALIGNED4(aPtr);
       
   306 		size_t newOffset = aManager.iDwarfManager.GetLineSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
       
   307 		if (offset != newOffset)
       
   308 			WRITE_UNALIGNED4(aPtr, newOffset);
       
   309 		return aPtr + 4;
       
   310 	} else if (aForm == DW_FORM_indirect){
       
   311 	    size_t indir_len = 0;
       
   312 	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   313 	    if (form_indirect == DW_FORM_indirect) {
       
   314 			/* 	Eek, should never happen */
       
   315 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   316 	    }
       
   317 	    return InfoEditLinePtr(aManager, aPtr+indir_len, form_indirect, aPair);
       
   318 	
       
   319 	} else
       
   320 		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   321 }
       
   322 
       
   323 // TODO: implicitly only deals with 32-bit DWARF
       
   324 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   325 	if (aForm == DW_FORM_data4){
       
   326 		size_t offset = READ_UNALIGNED4(aPtr);
       
   327 		size_t newOffset = aManager.iDwarfManager.GetLocListSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
       
   328 		if (offset != newOffset)
       
   329 			WRITE_UNALIGNED4(aPtr, newOffset);
       
   330 		return aPtr + 4;
       
   331 	} else if (aForm == DW_FORM_indirect){
       
   332 	    size_t indir_len = 0;
       
   333 	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   334 	    if (form_indirect == DW_FORM_indirect) {
       
   335 			/* 	Eek, should never happen */
       
   336 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   337 	    }
       
   338 	    return InfoEditLocListPtr(aManager, aPtr+indir_len, form_indirect, aPair);
       
   339 	
       
   340 	} else
       
   341 		//return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   342 		return InfoEditLocExpr(aManager, aPtr, aForm, aPair);
       
   343 }
       
   344 
       
   345 
       
   346 
       
   347 
       
   348 
       
   349 // TODO: implicitly only deals with 32-bit DWARF
       
   350 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditMacInfoPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   351 	if (aForm == DW_FORM_data4){
       
   352 		size_t offset = READ_UNALIGNED4(aPtr);
       
   353 		size_t newOffset = aManager.iDwarfManager.GetMacInfoSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
       
   354 		if (offset != newOffset)
       
   355 			WRITE_UNALIGNED4(aPtr, newOffset);
       
   356 		return aPtr + 4;
       
   357 	} else if (aForm == DW_FORM_indirect){
       
   358 	    size_t indir_len = 0;
       
   359 	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   360 	    if (form_indirect == DW_FORM_indirect) {
       
   361 			/* 	Eek, should never happen */
       
   362 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   363 	    }
       
   364 	    return InfoEditMacInfoPtr(aManager, aPtr+indir_len, form_indirect, aPair);
       
   365 	
       
   366 	} else
       
   367 		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   368 }
       
   369 
       
   370 // TODO: implicitly only deals with 32-bit DWARF
       
   371 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditRangeListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   372 	if (aForm == DW_FORM_data4){
       
   373 		size_t offset = READ_UNALIGNED4(aPtr);
       
   374 		size_t newOffset = aManager.iDwarfManager.GetRangesSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
       
   375 		if (offset != newOffset)
       
   376 			WRITE_UNALIGNED4(aPtr, newOffset);
       
   377 		return aPtr + 4;
       
   378 	} else if (aForm == DW_FORM_indirect){
       
   379 	    size_t indir_len = 0;
       
   380 	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   381 	    if (form_indirect == DW_FORM_indirect) {
       
   382 			/* 	Eek, should never happen */
       
   383 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   384 	    }
       
   385 	    return InfoEditRangeListPtr(aManager, aPtr+indir_len, form_indirect, aPair);
       
   386 	
       
   387 	} else
       
   388 		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   389 }
       
   390 
       
   391 // TODO: implicitly only deals with 32-bit DWARF
       
   392 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditString(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   393 	
       
   394 	if (aForm == DW_FORM_strp){
       
   395 		size_t offset = READ_UNALIGNED4(aPtr);
       
   396 		size_t newOffset = aManager.iDwarfManager.GetStrSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
       
   397 		if (offset != newOffset)
       
   398 			WRITE_UNALIGNED4(aPtr, newOffset);
       
   399 		return aPtr + 4;
       
   400 	} else if (aForm == DW_FORM_indirect){
       
   401 	    size_t indir_len = 0;
       
   402 	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   403 	    if (form_indirect == DW_FORM_indirect) {
       
   404 			/* 	Eek, should never happen */
       
   405 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   406 	    }
       
   407 	    return InfoEditString(aManager, aPtr+indir_len, form_indirect, aPair);
       
   408 	
       
   409 	} else
       
   410 		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   411 }
       
   412 
       
   413 // TODO: implicitly only deals with 32-bit DWARF
       
   414 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditReference(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   415 	if (aForm == DW_FORM_ref_addr){
       
   416 		size_t offset = READ_UNALIGNED4(aPtr);
       
   417 		size_t newOffset = aManager.CheckNewOffset(aManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset);
       
   418 		if (offset != newOffset)
       
   419 			WRITE_UNALIGNED4(aPtr, newOffset);
       
   420 		return aPtr + 4;
       
   421 	} else if (aForm == DW_FORM_indirect){
       
   422 	    size_t indir_len = 0;
       
   423 	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   424 	    if (form_indirect == DW_FORM_indirect) {
       
   425 			/* 	Eek, should never happen */
       
   426 	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   427 	    }
       
   428 	    return InfoEditReference(aManager, aPtr+indir_len, form_indirect, aPair);
       
   429 	
       
   430 	} else
       
   431 		//return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
       
   432 		return InfoEditLocExpr(aManager, aPtr, aForm, aPair);
       
   433 }
       
   434 
       
   435 // TODO: implicitly only deals with 32-bit DWARF
       
   436 // Explicitly check for *_address and *_strp then let the reference handler deal with the flag possiblity as s 'else'. 
       
   437 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditTrampoline(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
       
   438 	if (aForm == DW_FORM_addr)
       
   439 		return InfoEditAddress(aManager, aPtr, aForm, aPair);
       
   440 	else if (aForm = DW_FORM_strp)
       
   441 		return InfoEditString(aManager, aPtr, aForm, aPair);
       
   442 	else if (aForm == DW_FORM_indirect){
       
   443 		    size_t indir_len = 0;
       
   444 		    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
       
   445 		    if (form_indirect == DW_FORM_indirect) {
       
   446 				/* 	Eek, should never happen */
       
   447 		    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
       
   448 		    }
       
   449 		    return InfoEditTrampoline(aManager, aPtr+indir_len, form_indirect, aPair);
       
   450 		
       
   451 		} 
       
   452 	else
       
   453 		return InfoEditReference(aManager, aPtr, aForm, aPair);
       
   454 }
       
   455 
       
   456 
       
   457 DwarfInfoManager::InfoEditFn DwarfInfoManager::iInfoEditFn [] = {
       
   458 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0 so this should never be called
       
   459 	DwarfInfoManager::InfoEditReference, 	// DW_AT_sibling                           0x01
       
   460 	DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_location                          0x02
       
   461 	DwarfInfoManager::InfoEditString, 		// DW_AT_name                              0x03
       
   462 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  4 so this should never be called
       
   463 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  5 so this should never be called
       
   464 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  6 so this should never be called
       
   465 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  7 so this should never be called
       
   466 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  8 so this should never be called
       
   467     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_ordering                          0x09
       
   468     // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
       
   469     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_subscr_data                       0x0a
       
   470     DwarfInfoManager::InfoEditReference, 	// DW_AT_byte_size                         0x0b
       
   471     DwarfInfoManager::InfoEditReference, 	// DW_AT_bit_offset                        0x0c
       
   472     DwarfInfoManager::InfoEditReference, 	// DW_AT_bit_size                          0x0d
       
   473 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x0e so this should never be called
       
   474     // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
       
   475     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_element_list                      0x0f
       
   476     DwarfInfoManager::InfoEditLinePtr, 		// DW_AT_stmt_list                         0x10
       
   477     DwarfInfoManager::InfoEditAddress, 		// DW_AT_low_pc                            0x11
       
   478     DwarfInfoManager::InfoEditAddress, 		// DW_AT_high_pc                           0x12
       
   479     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_language                          0x13
       
   480     // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
       
   481     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_member                            0x14
       
   482     DwarfInfoManager::InfoEditReference, 	// DW_AT_discr                             0x15
       
   483     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_discr_value                       0x16
       
   484     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_visibility                        0x17
       
   485     DwarfInfoManager::InfoEditReference, 	// DW_AT_import                            0x18
       
   486     DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_string_length                     0x19
       
   487     DwarfInfoManager::InfoEditReference, 	// DW_AT_common_reference                  0x1a
       
   488     DwarfInfoManager::InfoEditString, 		// DW_AT_comp_dir                          0x1b
       
   489     DwarfInfoManager::InfoEditString, 		// DW_AT_const_value                       0x1c
       
   490     DwarfInfoManager::InfoEditReference, 	// DW_AT_containing_type                   0x1d
       
   491     DwarfInfoManager::InfoEditReference, 	// DW_AT_default_value                     0x1e
       
   492 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x1f so this should never be called
       
   493     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_inline                            0x20
       
   494     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_is_optional                       0x21
       
   495     DwarfInfoManager::InfoEditReference, 	// DW_AT_lower_bound                       0x22
       
   496 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x23 so this should never be called
       
   497 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x24 so this should never be called
       
   498     DwarfInfoManager::InfoEditString, 		// DW_AT_producer                          0x25
       
   499 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x26 so this should never be called
       
   500     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_prototyped                        0x27
       
   501 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x28 so this should never be called
       
   502 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x29 so this should never be called
       
   503     DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_return_addr                       0x2a
       
   504 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x2b so this should never be called
       
   505     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_start_scope                       0x2c
       
   506 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x2d so this should never be called
       
   507     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_bit_stride                        0x2e /* DWARF3 name */
       
   508     DwarfInfoManager::InfoEditReference, 	// DW_AT_upper_bound                       0x2f
       
   509 	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x30 so this should never be called
       
   510     DwarfInfoManager::InfoEditReference, 	// DW_AT_abstract_origin                   0x31
       
   511     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_accessibility                     0x32
       
   512     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_address_class                     0x33
       
   513     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_artificial                        0x34
       
   514     DwarfInfoManager::InfoEditReference, 	// DW_AT_base_types                        0x35
       
   515     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_calling_convention                0x36
       
   516     DwarfInfoManager::InfoEditReference, 	// DW_AT_count                             0x37
       
   517     DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_data_member_location              0x38
       
   518     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decl_column                       0x39
       
   519     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decl_file                         0x3a
       
   520     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decl_line                         0x3b
       
   521     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_declaration                       0x3c
       
   522     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_discr_list                        0x3d
       
   523     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_encoding                          0x3e
       
   524     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_external                          0x3f
       
   525     DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_frame_base                        0x40
       
   526     DwarfInfoManager::InfoEditReference, 	// DW_AT_friend                            0x41
       
   527     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_identifier_case                   0x42
       
   528     DwarfInfoManager::InfoEditMacInfoPtr, 	// DW_AT_macro_info                        0x43
       
   529     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_namelist_item                     0x44
       
   530     DwarfInfoManager::InfoEditReference, 	// DW_AT_priority                          0x45
       
   531     DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_segment                           0x46
       
   532     DwarfInfoManager::InfoEditReference, 	// DW_AT_specification                     0x47
       
   533     DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_static_link                       0x48
       
   534     DwarfInfoManager::InfoEditReference, 	// DW_AT_type                              0x49
       
   535     DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_use_location                      0x4a
       
   536     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_variable_parameter                0x4b
       
   537     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_virtuality                        0x4c
       
   538     DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_vtable_elem_location              0x4d
       
   539     DwarfInfoManager::InfoEditReference, 	// DW_AT_allocated                         0x4e /* DWARF3 */
       
   540     DwarfInfoManager::InfoEditReference, 	// DW_AT_associated                        0x4f /* DWARF3 */
       
   541     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_data_location                     0x50 /* DWARF3 */
       
   542     DwarfInfoManager::InfoEditReference, 	// DW_AT_byte_stride                       0x51 /* DWARF3f */
       
   543     DwarfInfoManager::InfoEditAddress, 		// DW_AT_entry_pc                          0x52 /* DWARF3 */
       
   544     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_use_UTF8                          0x53 /* DWARF3 */
       
   545     DwarfInfoManager::InfoEditReference, 	// DW_AT_extension                         0x54 /* DWARF3 */
       
   546     DwarfInfoManager::InfoEditRangeListPtr, // DW_AT_ranges                            0x55 /* DWARF3 */
       
   547     DwarfInfoManager::InfoEditTrampoline, 	// DW_AT_trampoline                        0x56 /* DWARF3 */
       
   548     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_call_column                       0x57 /* DWARF3 */
       
   549     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_call_file                         0x58 /* DWARF3 */
       
   550     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_call_line                         0x59 /* DWARF3 */
       
   551     DwarfInfoManager::InfoEditString, 		// DW_AT_description                       0x5a /* DWARF3 */
       
   552     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_binary_scale                      0x5b /* DWARF3f */
       
   553     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decimal_scale                     0x5c /* DWARF3f */
       
   554     DwarfInfoManager::InfoEditReference, 	// DW_AT_small                             0x5d /* DWARF3f */
       
   555     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decimal_sign                      0x5e /* DWARF3f */
       
   556     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_digit_count                       0x5f /* DWARF3f */
       
   557     DwarfInfoManager::InfoEditString, 		// DW_AT_picture_string                    0x60 /* DWARF3f */
       
   558     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_mutable                           0x61 /* DWARF3f */
       
   559     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_threads_scaled                    0x62 /* DWARF3f */
       
   560     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_explicit                          0x63 /* DWARF3f */
       
   561     DwarfInfoManager::InfoEditReference, 	// DW_AT_object_pointer                    0x64 /* DWARF3f */
       
   562     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_endianity                         0x65 /* DWARF3f */
       
   563     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_elemental                         0x66 /* DWARF3f */
       
   564     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_pure                              0x67 /* DWARF3f */
       
   565     DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_recursive                         0x68 /* DWARF3f */
       
   566 };