tools/elf4rom/src/dwarflocexpr.cpp
changeset 34 92d87f2e53c2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarflocexpr.cpp	Fri Jan 15 09:07:44 2010 +0000
@@ -0,0 +1,271 @@
+/*
+* 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"
+
+void EditLocationExpression (Dwarf_Byte_Ptr data, unsigned int pointer_size, unsigned long length, FileShdrPair & aPair)
+{
+	unsigned op;
+	size_t bytes_read;
+	Dwarf_Byte_Ptr end = data + length;
+
+	while (data < end){
+		op = *data++;
+
+		switch (op){
+		case DW_OP_addr:
+			LinearAddr addr = READ_UNALIGNED4(data);
+			LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr);
+			WRITE_UNALIGNED4(data, relocatedAddr);
+			data += pointer_size;
+			break;
+		case DW_OP_deref:
+			break;
+		case DW_OP_const1u:
+		case DW_OP_const1s:
+			data++;
+			break;
+		case DW_OP_const2u:
+		case DW_OP_const2s:
+			data += 2;
+			break;
+		case DW_OP_const4u:
+		case DW_OP_const4s:
+			data += 4;
+			break;
+		case DW_OP_const8u:
+		case DW_OP_const8s:
+			data += 8;
+			break;
+		case DW_OP_constu:
+		case DW_OP_consts: 
+		{
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_dup:
+		case DW_OP_drop:
+		case DW_OP_over:
+			break;
+		case DW_OP_pick:
+			data++;
+			break;
+		case DW_OP_swap:
+		case DW_OP_rot:
+		case DW_OP_xderef:
+		case DW_OP_abs:
+		case DW_OP_and:
+		case DW_OP_div:
+		case DW_OP_minus:
+		case DW_OP_mod:
+		case DW_OP_mul:
+		case DW_OP_neg:
+		case DW_OP_not:
+		case DW_OP_or:
+		case DW_OP_plus:
+			break;
+		case DW_OP_plus_uconst:
+		{
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_shl:
+		case DW_OP_shr:
+		case DW_OP_shra:
+		case DW_OP_xor:
+			break;
+		case DW_OP_bra:
+			data += 2;
+			break;
+		case DW_OP_eq:
+		case DW_OP_ge:
+		case DW_OP_gt:
+		case DW_OP_le:
+		case DW_OP_lt:
+		case DW_OP_ne:
+			break;
+		case DW_OP_skip:
+			data += 2;
+			break;
+
+		case DW_OP_lit0:
+		case DW_OP_lit1:
+		case DW_OP_lit2:
+		case DW_OP_lit3:
+		case DW_OP_lit4:
+		case DW_OP_lit5:
+		case DW_OP_lit6:
+		case DW_OP_lit7:
+		case DW_OP_lit8:
+		case DW_OP_lit9:
+		case DW_OP_lit10:
+		case DW_OP_lit11:
+		case DW_OP_lit12:
+		case DW_OP_lit13:
+		case DW_OP_lit14:
+		case DW_OP_lit15:
+		case DW_OP_lit16:
+		case DW_OP_lit17:
+		case DW_OP_lit18:
+		case DW_OP_lit19:
+		case DW_OP_lit20:
+		case DW_OP_lit21:
+		case DW_OP_lit22:
+		case DW_OP_lit23:
+		case DW_OP_lit24:
+		case DW_OP_lit25:
+		case DW_OP_lit26:
+		case DW_OP_lit27:
+		case DW_OP_lit28:
+		case DW_OP_lit29:
+		case DW_OP_lit30:
+		case DW_OP_lit31:
+			break;
+
+		case DW_OP_reg0:
+		case DW_OP_reg1:
+		case DW_OP_reg2:
+		case DW_OP_reg3:
+		case DW_OP_reg4:
+		case DW_OP_reg5:
+		case DW_OP_reg6:
+		case DW_OP_reg7:
+		case DW_OP_reg8:
+		case DW_OP_reg9:
+		case DW_OP_reg10:
+		case DW_OP_reg11:
+		case DW_OP_reg12:
+		case DW_OP_reg13:
+		case DW_OP_reg14:
+		case DW_OP_reg15:
+		case DW_OP_reg16:
+		case DW_OP_reg17:
+		case DW_OP_reg18:
+		case DW_OP_reg19:
+		case DW_OP_reg20:
+		case DW_OP_reg21:
+		case DW_OP_reg22:
+		case DW_OP_reg23:
+		case DW_OP_reg24:
+		case DW_OP_reg25:
+		case DW_OP_reg26:
+		case DW_OP_reg27:
+		case DW_OP_reg28:
+		case DW_OP_reg29:
+		case DW_OP_reg30:
+		case DW_OP_reg31:
+			break;
+
+		case DW_OP_breg0:
+		case DW_OP_breg1:
+		case DW_OP_breg2:
+		case DW_OP_breg3:
+		case DW_OP_breg4:
+		case DW_OP_breg5:
+		case DW_OP_breg6:
+		case DW_OP_breg7:
+		case DW_OP_breg8:
+		case DW_OP_breg9:
+		case DW_OP_breg10:
+		case DW_OP_breg11:
+		case DW_OP_breg12:
+		case DW_OP_breg13:
+		case DW_OP_breg14:
+		case DW_OP_breg15:
+		case DW_OP_breg16:
+		case DW_OP_breg17:
+		case DW_OP_breg18:
+		case DW_OP_breg19:
+		case DW_OP_breg20:
+		case DW_OP_breg21:
+		case DW_OP_breg22:
+		case DW_OP_breg23:
+		case DW_OP_breg24:
+		case DW_OP_breg25:
+		case DW_OP_breg26:
+		case DW_OP_breg27:
+		case DW_OP_breg28:
+		case DW_OP_breg29:
+		case DW_OP_breg30:
+		case DW_OP_breg31:
+		case DW_OP_fbreg:
+		{
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_bregx:
+		{
+			ULEB128(data, bytes_read);
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_piece:
+		{
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_deref_size:
+		case DW_OP_xderef_size:
+			data++;
+			break;
+		case DW_OP_nop:
+		  /* DWARF 3 extensions.  */
+		case DW_OP_push_object_address:
+		  break;
+		case DW_OP_call2:
+		  /* XXX: Strictly speaking for 64-bit DWARF3 files
+		     this ought to be an 8-byte wide computation.  */
+		  data += 2;
+		  break;
+		case DW_OP_call4:
+		  /* XXX: Strictly speaking for 64-bit DWARF3 files
+		     this ought to be an 8-byte wide computation.  */
+		  data += 4;
+		  break;
+		case DW_OP_call_ref:
+		  /* XXX: Strictly speaking for 64-bit DWARF3 files
+		     this ought to be an 8-byte wide computation.  */
+		  data += 4;
+		  break;
+		case DW_OP_form_tls_address:
+		case DW_OP_call_frame_cfa:
+		  break;
+		case DW_OP_bit_piece:
+		{
+			// Handily the spec doesn't describe the operands - but by analogy with
+			// DW_OP_piece we assume these are ULEB128 encoded.
+			ULEB128(data, bytes_read);
+			ULEB128(data, bytes_read);
+			break;
+		}
+	
+		/* GNU extensions.  */
+		case DW_OP_GNU_push_tls_address:
+		//case DW_OP_GNU_uninit:
+			/* FIXME: Is there data associated with this OP ?  */
+			break;
+
+		default:
+			// bail - can't do anything else sensible here
+			cerr << "Warning: Unrecognized opcode " << op << " in Dwarf expression.\n";
+		  return;
+		}
+
+	}
+}