Modify framebuffer and NGA framebuffer to read screen size from board model dtb file. Optimise memory usuage of frame buffer
Add example minigui application with hooks to profiler (which writes results to S:\). Modified NGA framebuffer to run its own dfc queue at high priority
/*
* 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 <string.h>
#include <iostream>
#include <cassert>
#include "dwarfmanager.h"
#include "inputfile.h"
const string DwarfInfoManager::iInfoSectionName(".debug_info");
void DwarfInfoManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
iDwarfAbbrevManager.StartContext(aPair.iXIPFileDetails.iElfFile);
Dwarf_Byte_Ptr p = aStart;
Dwarf_Byte_Ptr e = aEnd;
while (p < e) {
p = ProcessCU(aPair, p, e);
}
iDwarfAbbrevManager.EndContext();
}
#define READ_DWARF_VAL(v,t,p) t v = *((t *)p); p += sizeof(t);
Dwarf_Byte_Ptr DwarfInfoManager::ProcessCU(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){
Dwarf_Byte_Ptr p = s;
//Read the CU header info
// first check whether we're dealing with 32bit or 64 bit DWARF
// TODO: must abstract over base types e.g uint32 etc.
// TODO: this might not be 4 byte aligned and so could cause problems on some
// architectures
READ_DWARF_VAL(len, Uint32, p);
if (len >= 0xfffffff0u){
cerr << "Error: 64 bit DWARF not supported\n";
exit(EXIT_FAILURE);
}
iLocalLength = len;
Dwarf_Byte_Ptr end = p + len;
// TODO: make sensitive to dwarf version number?
READ_DWARF_VAL(version, Dwarf_Half, p);
Uint32 abbrevOffset = *((Uint32 *)p);
// update the offset into the abbrev table
*((Uint32 *)p) = (Uint32)(abbrevOffset + iDwarfAbbrevManager.GetContextSectionOffset());
p += sizeof(Uint32);
READ_DWARF_VAL(address_size, Byte, p);
// TODO: if this isn't 4 we're doomed aren't we?
iAddressSize = address_size;
iDwarfAbbrevManager.SetContextAbbrevOffset(abbrevOffset);
// now process each DIE until end.
while (p < end) {
p = ProcessDIE(aPair, p, end);
}
return p;
}
void NoteProducer(FileShdrPair & aPair, Dwarf_Byte_Ptr aPtr, Dwarf_Unsigned aForm){
switch (aForm){
case DW_FORM_string:{
const char * producer = (const char *)aPtr;
const char * RvctProducer = "ARM/Thumb C/C++ Compiler, RVCT";
const size_t RvctProducerLength = strlen(RvctProducer);
const char * GccProducer = "GNU C++";
const size_t GccProducerLength = strlen(GccProducer);
if (!strncmp(producer, RvctProducer, RvctProducerLength))
aPair.iXIPFileDetails.iRVCTProduced = true;
if (!strncmp(producer, GccProducer, GccProducerLength))
aPair.iXIPFileDetails.iGCCProduced = true;
return;
}
case DW_FORM_indirect: {
size_t indir_len = 0;
Dwarf_Unsigned form_indirect = DwarfSectionManager::DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen, will get warned later */
return;
}
return NoteProducer(aPair, aPtr+indir_len, form_indirect);
}
case DW_FORM_strp:
// TODO - We need to get the string table for this --
return;
}
}
Dwarf_Byte_Ptr DwarfInfoManager::ProcessDIE(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){
Dwarf_Byte_Ptr info_ptr = s;
size_t leb128_length;
Dwarf_Word abbrev_code = DecodeUnsignedLeb128(info_ptr, leb128_length);
info_ptr += leb128_length;
if (abbrev_code == 0) {
return info_ptr;
}
DebugAbbrev & abbrev = iDwarfAbbrevManager.GetAbbrev(abbrev_code);
//cout << "Tag = " << GetDwarfTag(abbrev.iTag) << " Code = " << abbrev_code << " num attrs = " << abbrev.iCount << endl;
for (size_t i = 0; i < abbrev.iCount; i++){
size_t attr = abbrev.iParsed[i].iAttr;
Dwarf_Unsigned form = abbrev.iParsed[i].iForm;
//cout << "\tAttr " << GetDwarfAttr(attr) << " Form " << GetDwarfForm(form) << "\n";
// record anything interesting about the producer here.
if (attr == DW_AT_producer)
NoteProducer(aPair, info_ptr, form);
if (attr > DW_AT_recursive)
info_ptr = DefaultInfoEditFn(*this, info_ptr, form, aPair);
else
info_ptr = iInfoEditFn[attr](*this, info_ptr, form, aPair);
}
return info_ptr;
}
size_t DwarfInfoManager::SizeOfDieValue(Dwarf_Half aForm, Dwarf_Byte_Ptr aPtr){
Dwarf_Unsigned length = 0;
size_t leb128_length = 0;
size_t ret_value = 0;
switch (aForm) {
default: /* Handles form = 0. */
return (aForm);
case DW_FORM_addr:
return iAddressSize;
case DW_FORM_ref_addr:
// TODO: sort this out
return 4; // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf
case DW_FORM_block1:
return (*aPtr) + 1;
case DW_FORM_block2:
ret_value = READ_UNALIGNED2(aPtr) + 2;
return ret_value;
case DW_FORM_block4:
ret_value = READ_UNALIGNED4(aPtr) + 4;
return ret_value;
case DW_FORM_data1:
return 1;
case DW_FORM_data2:
return 2;
case DW_FORM_data4:
return 4;
case DW_FORM_data8:
return 8;
case DW_FORM_string:
return (strlen((char *) aPtr) + 1);
case DW_FORM_block:
length = DecodeUnsignedLeb128(aPtr, leb128_length);
return length + leb128_length;
case DW_FORM_flag:
return 1;
case DW_FORM_ref_udata:
DecodeUnsignedLeb128(aPtr, leb128_length);
return leb128_length;
case DW_FORM_indirect: {
size_t indir_len = 0;
Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return indir_len + SizeOfDieValue(form_indirect, aPtr+indir_len);
}
case DW_FORM_ref1:
return 1;
case DW_FORM_ref2:
return 2;
case DW_FORM_ref4:
return 4;
case DW_FORM_ref8:
return 8;
case DW_FORM_sdata:
DecodeSignedLeb128(aPtr, leb128_length);
return leb128_length;
case DW_FORM_strp:
// TODO: sort this out
return 4; // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf
case DW_FORM_udata:
DecodeUnsignedLeb128(aPtr, leb128_length);
return leb128_length;
}
}
Dwarf_Byte_Ptr DwarfInfoManager::DefaultInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
}
Dwarf_Byte_Ptr DwarfInfoManager::ErrorInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
cerr << "Error: Undefined DW_FORM value: " << aForm << "\n" ;
exit(EXIT_FAILURE);
return aPtr;
}
// TODO: implicitly only deals with 32-bit DWARF
// Called from other edit functions to deal with blocks that contain location expressions.
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocExpr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
Dwarf_Unsigned length = 0;
bool locExpr = false;
Dwarf_Byte_Ptr block = aPtr;
if (aForm == DW_FORM_block1) {
locExpr = true;
length = block[0];
block++;
aPtr += (length + 1);
} else if (aForm == DW_FORM_block2) {
locExpr = true;
length = READ_UNALIGNED2(block);
block += 2;
aPtr += (length + 2);
} else if (aForm == DW_FORM_block4) {
locExpr = true;
length = READ_UNALIGNED4(block);
block += 4;
aPtr += (length + 4);
} else if (aForm == DW_FORM_block) {
locExpr = true;
size_t leb_length = 0;
length = DecodeUnsignedLeb128(block, leb_length);
block += leb_length;
aPtr += (length + leb_length);
}
if (locExpr){
EditLocationExpression (block, aManager.iAddressSize, length, aPair);
return aPtr;
} else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditLocExpr(aManager, aPtr+indir_len, form_indirect, aPair);
} else
return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
}
// TODO: implicitly only deals with 32-bit DWARF
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditAddress(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
if (aForm == DW_FORM_addr){
LinearAddr addr = READ_UNALIGNED4(aPtr);
LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr);
WRITE_UNALIGNED4(aPtr, relocatedAddr);
return aPtr + 4;
} else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditAddress(aManager, aPtr+indir_len, form_indirect, aPair);
} else
return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
}
// TODO: implicitly only deals with 32-bit DWARF
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLinePtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
if (aForm == DW_FORM_data4){
size_t offset = READ_UNALIGNED4(aPtr);
size_t newOffset = aManager.iDwarfManager.GetLineSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
if (offset != newOffset)
WRITE_UNALIGNED4(aPtr, newOffset);
return aPtr + 4;
} else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditLinePtr(aManager, aPtr+indir_len, form_indirect, aPair);
} else
return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
}
// TODO: implicitly only deals with 32-bit DWARF
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
if (aForm == DW_FORM_data4){
size_t offset = READ_UNALIGNED4(aPtr);
size_t newOffset = aManager.iDwarfManager.GetLocListSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
if (offset != newOffset)
WRITE_UNALIGNED4(aPtr, newOffset);
return aPtr + 4;
} else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditLocListPtr(aManager, aPtr+indir_len, form_indirect, aPair);
} else
//return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
return InfoEditLocExpr(aManager, aPtr, aForm, aPair);
}
// TODO: implicitly only deals with 32-bit DWARF
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditMacInfoPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
if (aForm == DW_FORM_data4){
size_t offset = READ_UNALIGNED4(aPtr);
size_t newOffset = aManager.iDwarfManager.GetMacInfoSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
if (offset != newOffset)
WRITE_UNALIGNED4(aPtr, newOffset);
return aPtr + 4;
} else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditMacInfoPtr(aManager, aPtr+indir_len, form_indirect, aPair);
} else
return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
}
// TODO: implicitly only deals with 32-bit DWARF
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditRangeListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
if (aForm == DW_FORM_data4){
size_t offset = READ_UNALIGNED4(aPtr);
size_t newOffset = aManager.iDwarfManager.GetRangesSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
if (offset != newOffset)
WRITE_UNALIGNED4(aPtr, newOffset);
return aPtr + 4;
} else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditRangeListPtr(aManager, aPtr+indir_len, form_indirect, aPair);
} else
return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
}
// TODO: implicitly only deals with 32-bit DWARF
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditString(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
if (aForm == DW_FORM_strp){
size_t offset = READ_UNALIGNED4(aPtr);
size_t newOffset = aManager.iDwarfManager.GetStrSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
if (offset != newOffset)
WRITE_UNALIGNED4(aPtr, newOffset);
return aPtr + 4;
} else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditString(aManager, aPtr+indir_len, form_indirect, aPair);
} else
return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
}
// TODO: implicitly only deals with 32-bit DWARF
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditReference(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
if (aForm == DW_FORM_ref_addr){
size_t offset = READ_UNALIGNED4(aPtr);
size_t newOffset = aManager.CheckNewOffset(aManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset);
if (offset != newOffset)
WRITE_UNALIGNED4(aPtr, newOffset);
return aPtr + 4;
} else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditReference(aManager, aPtr+indir_len, form_indirect, aPair);
} else
//return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
return InfoEditLocExpr(aManager, aPtr, aForm, aPair);
}
// TODO: implicitly only deals with 32-bit DWARF
// Explicitly check for *_address and *_strp then let the reference handler deal with the flag possiblity as s 'else'.
Dwarf_Byte_Ptr DwarfInfoManager::InfoEditTrampoline(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
if (aForm == DW_FORM_addr)
return InfoEditAddress(aManager, aPtr, aForm, aPair);
else if (aForm = DW_FORM_strp)
return InfoEditString(aManager, aPtr, aForm, aPair);
else if (aForm == DW_FORM_indirect){
size_t indir_len = 0;
Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
if (form_indirect == DW_FORM_indirect) {
/* Eek, should never happen */
cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
}
return InfoEditTrampoline(aManager, aPtr+indir_len, form_indirect, aPair);
}
else
return InfoEditReference(aManager, aPtr, aForm, aPair);
}
DwarfInfoManager::InfoEditFn DwarfInfoManager::iInfoEditFn [] = {
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0 so this should never be called
DwarfInfoManager::InfoEditReference, // DW_AT_sibling 0x01
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_location 0x02
DwarfInfoManager::InfoEditString, // DW_AT_name 0x03
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 4 so this should never be called
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 5 so this should never be called
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 6 so this should never be called
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 7 so this should never be called
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 8 so this should never be called
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_ordering 0x09
// TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_subscr_data 0x0a
DwarfInfoManager::InfoEditReference, // DW_AT_byte_size 0x0b
DwarfInfoManager::InfoEditReference, // DW_AT_bit_offset 0x0c
DwarfInfoManager::InfoEditReference, // DW_AT_bit_size 0x0d
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x0e so this should never be called
// TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_element_list 0x0f
DwarfInfoManager::InfoEditLinePtr, // DW_AT_stmt_list 0x10
DwarfInfoManager::InfoEditAddress, // DW_AT_low_pc 0x11
DwarfInfoManager::InfoEditAddress, // DW_AT_high_pc 0x12
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_language 0x13
// TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_member 0x14
DwarfInfoManager::InfoEditReference, // DW_AT_discr 0x15
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_discr_value 0x16
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_visibility 0x17
DwarfInfoManager::InfoEditReference, // DW_AT_import 0x18
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_string_length 0x19
DwarfInfoManager::InfoEditReference, // DW_AT_common_reference 0x1a
DwarfInfoManager::InfoEditString, // DW_AT_comp_dir 0x1b
DwarfInfoManager::InfoEditString, // DW_AT_const_value 0x1c
DwarfInfoManager::InfoEditReference, // DW_AT_containing_type 0x1d
DwarfInfoManager::InfoEditReference, // DW_AT_default_value 0x1e
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x1f so this should never be called
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_inline 0x20
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_is_optional 0x21
DwarfInfoManager::InfoEditReference, // DW_AT_lower_bound 0x22
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x23 so this should never be called
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x24 so this should never be called
DwarfInfoManager::InfoEditString, // DW_AT_producer 0x25
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x26 so this should never be called
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_prototyped 0x27
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x28 so this should never be called
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x29 so this should never be called
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_return_addr 0x2a
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x2b so this should never be called
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_start_scope 0x2c
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x2d so this should never be called
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_bit_stride 0x2e /* DWARF3 name */
DwarfInfoManager::InfoEditReference, // DW_AT_upper_bound 0x2f
DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x30 so this should never be called
DwarfInfoManager::InfoEditReference, // DW_AT_abstract_origin 0x31
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_accessibility 0x32
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_address_class 0x33
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_artificial 0x34
DwarfInfoManager::InfoEditReference, // DW_AT_base_types 0x35
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_calling_convention 0x36
DwarfInfoManager::InfoEditReference, // DW_AT_count 0x37
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_data_member_location 0x38
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_column 0x39
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_file 0x3a
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_line 0x3b
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_declaration 0x3c
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_discr_list 0x3d
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_encoding 0x3e
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_external 0x3f
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_frame_base 0x40
DwarfInfoManager::InfoEditReference, // DW_AT_friend 0x41
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_identifier_case 0x42
DwarfInfoManager::InfoEditMacInfoPtr, // DW_AT_macro_info 0x43
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_namelist_item 0x44
DwarfInfoManager::InfoEditReference, // DW_AT_priority 0x45
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_segment 0x46
DwarfInfoManager::InfoEditReference, // DW_AT_specification 0x47
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_static_link 0x48
DwarfInfoManager::InfoEditReference, // DW_AT_type 0x49
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_use_location 0x4a
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_variable_parameter 0x4b
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_virtuality 0x4c
DwarfInfoManager::InfoEditLocListPtr, // DW_AT_vtable_elem_location 0x4d
DwarfInfoManager::InfoEditReference, // DW_AT_allocated 0x4e /* DWARF3 */
DwarfInfoManager::InfoEditReference, // DW_AT_associated 0x4f /* DWARF3 */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_data_location 0x50 /* DWARF3 */
DwarfInfoManager::InfoEditReference, // DW_AT_byte_stride 0x51 /* DWARF3f */
DwarfInfoManager::InfoEditAddress, // DW_AT_entry_pc 0x52 /* DWARF3 */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_use_UTF8 0x53 /* DWARF3 */
DwarfInfoManager::InfoEditReference, // DW_AT_extension 0x54 /* DWARF3 */
DwarfInfoManager::InfoEditRangeListPtr, // DW_AT_ranges 0x55 /* DWARF3 */
DwarfInfoManager::InfoEditTrampoline, // DW_AT_trampoline 0x56 /* DWARF3 */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_column 0x57 /* DWARF3 */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_file 0x58 /* DWARF3 */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_line 0x59 /* DWARF3 */
DwarfInfoManager::InfoEditString, // DW_AT_description 0x5a /* DWARF3 */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_binary_scale 0x5b /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decimal_scale 0x5c /* DWARF3f */
DwarfInfoManager::InfoEditReference, // DW_AT_small 0x5d /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decimal_sign 0x5e /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_digit_count 0x5f /* DWARF3f */
DwarfInfoManager::InfoEditString, // DW_AT_picture_string 0x60 /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_mutable 0x61 /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_threads_scaled 0x62 /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_explicit 0x63 /* DWARF3f */
DwarfInfoManager::InfoEditReference, // DW_AT_object_pointer 0x64 /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_endianity 0x65 /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_elemental 0x66 /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_pure 0x67 /* DWARF3f */
DwarfInfoManager::DefaultInfoEditFn, // DW_AT_recursive 0x68 /* DWARF3f */
};