Backed out changeset b6c206049d8a
The nvmemmory library depends on a modification to qemu; this change
is therefore backed out in order to allow NVM functionality to be
merged into graphics-phase-3 by transplanting individual commits.
/*
* 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 DwarfLineManager::iLineSectionName(".debug_line");
inline static size_t process_extended_line_op (FileShdrPair & aPair, Dwarf_Byte_Ptr data)
{
size_t bytes_read;
size_t len = (size_t)ULEB128(data, bytes_read);
if (len == 0){
cerr << "badly formed extended line op encountered!\n";
// a length of 0 indicates a badly formed op and will force everything to be ignored until 'end_of_sequence'.
return 0;
}
len += bytes_read;
unsigned char op_code = *data++;
switch (op_code){
case DW_LNE_end_sequence:
break;
case DW_LNE_set_address: {
size_t size = len - bytes_read - 1;
LinearAddr addr = GetValue(data, size);
LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr);
if (addr != relocatedAddress)
WriteValue(data, relocatedAddress, size);
break;
}
case DW_LNE_define_file:
ULEB128(data, bytes_read);
ULEB128(data, bytes_read);
ULEB128(data, bytes_read);
break;
default:
break;
}
return len;
}
void DwarfLineManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
Dwarf_Byte_Ptr start = aStart;
Dwarf_Byte_Ptr end = aEnd;
size_t bytes_read = 0;
while (start < end){
Dwarf_Byte_Ptr hdrptr = start;
size_t offset_size, initial_length_size;
Dwarf_Word length = READ_UNALIGNED4(hdrptr);
hdrptr += 4;
if (length >= 0xfffffff0u) {
cerr << "Error: 64 bit DWARF not supported\n";
exit(EXIT_FAILURE);
} else {
offset_size = 4;
initial_length_size = 4;
}
Dwarf_Byte_Ptr end_of_sequence = start + length + initial_length_size;
Dwarf_Half version = READ_UNALIGNED2(hdrptr);
hdrptr += 2;
if (version != 2 && version != 3){
static bool warned = false;
if (!warned){
cerr << "Only DWARF 2 and 3 aranges are currently supported\n";
warned = true;
}
return;
}
hdrptr += offset_size;
#if 0
// Don't need the next four fields
Dwarf_Ubyte min_insn_length = *hdrptr++;
Dwarf_Ubyte default_is_stmt = *hdrptr++;
Dwarf_Ubyte line_base = *hdrptr++;
Dwarf_Ubyte line_range = *hdrptr++;
#endif
hdrptr +=4;
Dwarf_Ubyte opcode_base = *hdrptr++;
/* Skip the contents of the Opcodes table. */
Dwarf_Byte_Ptr standard_opcodes = hdrptr;
start = standard_opcodes + opcode_base - 1;
/* skip the contents of the Directory table. */
while (*start != 0){
start += strlen ((char *) start) + 1;
}
/* Skip the NUL at the end of the table. */
start++;
/* skip the contents of the File Name table. */
while (*start != 0){
start += strlen ((char *) start) + 1;
ULEB128(start, bytes_read);
ULEB128(start, bytes_read);
ULEB128(start, bytes_read);
}
/* Skip the NUL at the end of the table. */
start++;
while (start < end_of_sequence){
unsigned char op_code = *start++;
if (op_code >= opcode_base){
continue;
} else {
switch (op_code){
// missing from dwarf.h - first byte of extended op codes is '0x0'
#define DW_LNS_extended_op 0x0
case DW_LNS_extended_op:
size_t n = process_extended_line_op (aPair, start);
// if we don't understand the extended op skip to the end of the sequence :-(
if (n == 0)
start = end_of_sequence;
else
start += n;
break;
case DW_LNS_copy:
break;
case DW_LNS_advance_pc:
case DW_LNS_advance_line:
case DW_LNS_set_file:
case DW_LNS_set_column:
ULEB128(start, bytes_read);
break;
case DW_LNS_negate_stmt:
case DW_LNS_set_basic_block:
case DW_LNS_const_add_pc:
break;
case DW_LNS_fixed_advance_pc:
start += 2;
break;
case DW_LNS_set_prologue_end:
case DW_LNS_set_epilogue_begin:
break;
case DW_LNS_set_isa:
ULEB128(start, bytes_read);
break;
default:
for (int i = standard_opcodes[op_code - 1]; i > 0 ; --i){
ULEB128(start, bytes_read);
}
break;
}
}
}
// !! eek ARM seems to require header word aligned - at least for Dwarf 2
if (aPair.iXIPFileDetails.iRVCTProduced && (version == 2))
start = (Dwarf_Byte_Ptr)(((unsigned long)start + 3) & ~3);
}
}