149d3bc91SRichard Lowe /* 207dc1947SRichard Lowe Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. 307dc1947SRichard Lowe Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. 4*4d9fdb46SRobert Mustacchi Portions Copyright 2011-2019 David Anderson. All rights reserved. 5*4d9fdb46SRobert Mustacchi 6*4d9fdb46SRobert Mustacchi This program is free software; you can redistribute it 7*4d9fdb46SRobert Mustacchi and/or modify it under the terms of version 2.1 of the 8*4d9fdb46SRobert Mustacchi GNU Lesser General Public License as published by the Free 9*4d9fdb46SRobert Mustacchi Software Foundation. 10*4d9fdb46SRobert Mustacchi 11*4d9fdb46SRobert Mustacchi This program is distributed in the hope that it would be 12*4d9fdb46SRobert Mustacchi useful, but WITHOUT ANY WARRANTY; without even the implied 13*4d9fdb46SRobert Mustacchi warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 14*4d9fdb46SRobert Mustacchi PURPOSE. 15*4d9fdb46SRobert Mustacchi 16*4d9fdb46SRobert Mustacchi Further, this software is distributed without any warranty 17*4d9fdb46SRobert Mustacchi that it is free of the rightful claim of any third person 18*4d9fdb46SRobert Mustacchi regarding infringement or the like. Any license provided 19*4d9fdb46SRobert Mustacchi herein, whether implied or otherwise, applies only to this 20*4d9fdb46SRobert Mustacchi software file. Patent licenses, if any, provided herein 21*4d9fdb46SRobert Mustacchi do not apply to combinations of this program with other 22*4d9fdb46SRobert Mustacchi software, or any other product whatsoever. 23*4d9fdb46SRobert Mustacchi 24*4d9fdb46SRobert Mustacchi You should have received a copy of the GNU Lesser General 25*4d9fdb46SRobert Mustacchi Public License along with this program; if not, write the 26*4d9fdb46SRobert Mustacchi Free Software Foundation, Inc., 51 Franklin Street - Fifth 27*4d9fdb46SRobert Mustacchi Floor, Boston MA 02110-1301, USA. 2849d3bc91SRichard Lowe 2949d3bc91SRichard Lowe */ 3049d3bc91SRichard Lowe 3149d3bc91SRichard Lowe #include "config.h" 3249d3bc91SRichard Lowe #include "libdwarfdefs.h" 3349d3bc91SRichard Lowe #include <stdio.h> 3449d3bc91SRichard Lowe #include <string.h> 35*4d9fdb46SRobert Mustacchi #include <stddef.h> 36*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDINT_H 37*4d9fdb46SRobert Mustacchi #include <stdint.h> /* For uintptr_t */ 38*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDINT_H */ 3949d3bc91SRichard Lowe #include "pro_incl.h" 40*4d9fdb46SRobert Mustacchi #include "dwarf.h" 41*4d9fdb46SRobert Mustacchi #include "libdwarf.h" 42*4d9fdb46SRobert Mustacchi #include "pro_opaque.h" 43*4d9fdb46SRobert Mustacchi #include "pro_error.h" 44*4d9fdb46SRobert Mustacchi #include "pro_encode_nm.h" 45*4d9fdb46SRobert Mustacchi #include "pro_alloc.h" 4649d3bc91SRichard Lowe #include "pro_expr.h" 4749d3bc91SRichard Lowe 48*4d9fdb46SRobert Mustacchi #define SIZEOFT16 2 49*4d9fdb46SRobert Mustacchi #define SIZEOFT32 4 50*4d9fdb46SRobert Mustacchi #define SIZEOFT64 8 51*4d9fdb46SRobert Mustacchi 5249d3bc91SRichard Lowe /* 53*4d9fdb46SRobert Mustacchi This function creates a new expression 5449d3bc91SRichard Lowe struct that can be used to build up a 5549d3bc91SRichard Lowe location expression. 5649d3bc91SRichard Lowe */ 5749d3bc91SRichard Lowe Dwarf_P_Expr 5849d3bc91SRichard Lowe dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error) 5949d3bc91SRichard Lowe { 6049d3bc91SRichard Lowe Dwarf_P_Expr ret_expr; 6149d3bc91SRichard Lowe 6249d3bc91SRichard Lowe if (dbg == NULL) { 6307dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 6407dc1947SRichard Lowe return (NULL); 6549d3bc91SRichard Lowe } 6649d3bc91SRichard Lowe 6749d3bc91SRichard Lowe ret_expr = (Dwarf_P_Expr) 6807dc1947SRichard Lowe _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s)); 6949d3bc91SRichard Lowe if (ret_expr == NULL) { 7007dc1947SRichard Lowe _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 7107dc1947SRichard Lowe return (NULL); 7249d3bc91SRichard Lowe } 7349d3bc91SRichard Lowe 7449d3bc91SRichard Lowe ret_expr->ex_dbg = dbg; 7549d3bc91SRichard Lowe 7649d3bc91SRichard Lowe return (ret_expr); 7749d3bc91SRichard Lowe } 7849d3bc91SRichard Lowe 7949d3bc91SRichard Lowe Dwarf_Unsigned 8049d3bc91SRichard Lowe dwarf_add_expr_gen(Dwarf_P_Expr expr, 81*4d9fdb46SRobert Mustacchi Dwarf_Small opcode, 82*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val1, 83*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val2, Dwarf_Error * error) 84*4d9fdb46SRobert Mustacchi { 85*4d9fdb46SRobert Mustacchi Dwarf_Unsigned len = 0; 86*4d9fdb46SRobert Mustacchi int res = 0; 87*4d9fdb46SRobert Mustacchi 88*4d9fdb46SRobert Mustacchi res = dwarf_add_expr_gen_a(expr,opcode, 89*4d9fdb46SRobert Mustacchi val1,val2,&len,error); 90*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) { 91*4d9fdb46SRobert Mustacchi return DW_DLV_NOCOUNT; 92*4d9fdb46SRobert Mustacchi } 93*4d9fdb46SRobert Mustacchi return len; 94*4d9fdb46SRobert Mustacchi 95*4d9fdb46SRobert Mustacchi } 96*4d9fdb46SRobert Mustacchi 97*4d9fdb46SRobert Mustacchi int 98*4d9fdb46SRobert Mustacchi dwarf_add_expr_gen_a(Dwarf_P_Expr expr, 99*4d9fdb46SRobert Mustacchi Dwarf_Small opcode, 100*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val1, 101*4d9fdb46SRobert Mustacchi Dwarf_Unsigned val2, 102*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *stream_length_out, 103*4d9fdb46SRobert Mustacchi Dwarf_Error * error) 10449d3bc91SRichard Lowe { 105*4d9fdb46SRobert Mustacchi /* 2* since used to concatenate 2 leb's below */ 106*4d9fdb46SRobert Mustacchi char encode_buffer[2 * ENCODE_SPACE_NEEDED]; 107*4d9fdb46SRobert Mustacchi 10849d3bc91SRichard Lowe char encode_buffer2[ENCODE_SPACE_NEEDED]; 109*4d9fdb46SRobert Mustacchi int res = 0; 110*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg = 0; 11149d3bc91SRichard Lowe 112*4d9fdb46SRobert Mustacchi /* Give the buffer where the operands are first going to be 113*4d9fdb46SRobert Mustacchi assembled the largest alignment. */ 11449d3bc91SRichard Lowe Dwarf_Unsigned operand_buffer[10]; 11549d3bc91SRichard Lowe 116*4d9fdb46SRobert Mustacchi /* Size of the byte stream buffer that needs to be memcpy-ed. */ 117*4d9fdb46SRobert Mustacchi int operand_size = 0; 11849d3bc91SRichard Lowe 119*4d9fdb46SRobert Mustacchi /* Points to the byte stream for the first operand, and finally to 120*4d9fdb46SRobert Mustacchi the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */ 121*4d9fdb46SRobert Mustacchi Dwarf_Small *operand = 0; 12249d3bc91SRichard Lowe 123*4d9fdb46SRobert Mustacchi /* Size of the byte stream for second operand. */ 124*4d9fdb46SRobert Mustacchi int operand2_size = 0; 12549d3bc91SRichard Lowe 126*4d9fdb46SRobert Mustacchi /* Points to next byte to be written in Dwarf_P_Expr_s struct. */ 127*4d9fdb46SRobert Mustacchi Dwarf_Small *next_byte_ptr = 0; 12849d3bc91SRichard Lowe 129*4d9fdb46SRobert Mustacchi /* Offset past the last byte written into Dwarf_P_Expr_s. */ 130*4d9fdb46SRobert Mustacchi int next_byte_offset = 0; 13149d3bc91SRichard Lowe 13249d3bc91SRichard Lowe /* ***** BEGIN CODE ***** */ 13349d3bc91SRichard Lowe 13449d3bc91SRichard Lowe if (expr == NULL) { 13507dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 136*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 13749d3bc91SRichard Lowe } 138*4d9fdb46SRobert Mustacchi dbg = expr->ex_dbg; 13949d3bc91SRichard Lowe 14049d3bc91SRichard Lowe if (expr->ex_dbg == NULL) { 14107dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 142*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 14349d3bc91SRichard Lowe } 14449d3bc91SRichard Lowe 14549d3bc91SRichard Lowe operand = NULL; 14649d3bc91SRichard Lowe operand_size = 0; 14749d3bc91SRichard Lowe 14849d3bc91SRichard Lowe switch (opcode) { 14949d3bc91SRichard Lowe case DW_OP_reg0: 15049d3bc91SRichard Lowe case DW_OP_reg1: 15149d3bc91SRichard Lowe case DW_OP_reg2: 15249d3bc91SRichard Lowe case DW_OP_reg3: 15349d3bc91SRichard Lowe case DW_OP_reg4: 15449d3bc91SRichard Lowe case DW_OP_reg5: 15549d3bc91SRichard Lowe case DW_OP_reg6: 15649d3bc91SRichard Lowe case DW_OP_reg7: 15749d3bc91SRichard Lowe case DW_OP_reg8: 15849d3bc91SRichard Lowe case DW_OP_reg9: 15949d3bc91SRichard Lowe case DW_OP_reg10: 16049d3bc91SRichard Lowe case DW_OP_reg11: 16149d3bc91SRichard Lowe case DW_OP_reg12: 16249d3bc91SRichard Lowe case DW_OP_reg13: 16349d3bc91SRichard Lowe case DW_OP_reg14: 16449d3bc91SRichard Lowe case DW_OP_reg15: 16549d3bc91SRichard Lowe case DW_OP_reg16: 16649d3bc91SRichard Lowe case DW_OP_reg17: 16749d3bc91SRichard Lowe case DW_OP_reg18: 16849d3bc91SRichard Lowe case DW_OP_reg19: 16949d3bc91SRichard Lowe case DW_OP_reg20: 17049d3bc91SRichard Lowe case DW_OP_reg21: 17149d3bc91SRichard Lowe case DW_OP_reg22: 17249d3bc91SRichard Lowe case DW_OP_reg23: 17349d3bc91SRichard Lowe case DW_OP_reg24: 17449d3bc91SRichard Lowe case DW_OP_reg25: 17549d3bc91SRichard Lowe case DW_OP_reg26: 17649d3bc91SRichard Lowe case DW_OP_reg27: 17749d3bc91SRichard Lowe case DW_OP_reg28: 17849d3bc91SRichard Lowe case DW_OP_reg29: 17949d3bc91SRichard Lowe case DW_OP_reg30: 18049d3bc91SRichard Lowe case DW_OP_reg31: 18107dc1947SRichard Lowe break; 18249d3bc91SRichard Lowe 18349d3bc91SRichard Lowe case DW_OP_breg0: 18449d3bc91SRichard Lowe case DW_OP_breg1: 18549d3bc91SRichard Lowe case DW_OP_breg2: 18649d3bc91SRichard Lowe case DW_OP_breg3: 18749d3bc91SRichard Lowe case DW_OP_breg4: 18849d3bc91SRichard Lowe case DW_OP_breg5: 18949d3bc91SRichard Lowe case DW_OP_breg6: 19049d3bc91SRichard Lowe case DW_OP_breg7: 19149d3bc91SRichard Lowe case DW_OP_breg8: 19249d3bc91SRichard Lowe case DW_OP_breg9: 19349d3bc91SRichard Lowe case DW_OP_breg10: 19449d3bc91SRichard Lowe case DW_OP_breg11: 19549d3bc91SRichard Lowe case DW_OP_breg12: 19649d3bc91SRichard Lowe case DW_OP_breg13: 19749d3bc91SRichard Lowe case DW_OP_breg14: 19849d3bc91SRichard Lowe case DW_OP_breg15: 19949d3bc91SRichard Lowe case DW_OP_breg16: 20049d3bc91SRichard Lowe case DW_OP_breg17: 20149d3bc91SRichard Lowe case DW_OP_breg18: 20249d3bc91SRichard Lowe case DW_OP_breg19: 20349d3bc91SRichard Lowe case DW_OP_breg20: 20449d3bc91SRichard Lowe case DW_OP_breg21: 20549d3bc91SRichard Lowe case DW_OP_breg22: 20649d3bc91SRichard Lowe case DW_OP_breg23: 20749d3bc91SRichard Lowe case DW_OP_breg24: 20849d3bc91SRichard Lowe case DW_OP_breg25: 20949d3bc91SRichard Lowe case DW_OP_breg26: 21049d3bc91SRichard Lowe case DW_OP_breg27: 21149d3bc91SRichard Lowe case DW_OP_breg28: 21249d3bc91SRichard Lowe case DW_OP_breg29: 21349d3bc91SRichard Lowe case DW_OP_breg30: 21449d3bc91SRichard Lowe case DW_OP_breg31: 21507dc1947SRichard Lowe res = _dwarf_pro_encode_signed_leb128_nm(val1, 216*4d9fdb46SRobert Mustacchi &operand_size, encode_buffer, sizeof(encode_buffer)); 21707dc1947SRichard Lowe if (res != DW_DLV_OK) { 21807dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 219*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 22007dc1947SRichard Lowe } 22107dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 22207dc1947SRichard Lowe break; 22349d3bc91SRichard Lowe 22449d3bc91SRichard Lowe case DW_OP_regx: 22507dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 226*4d9fdb46SRobert Mustacchi encode_buffer, sizeof(encode_buffer)); 22707dc1947SRichard Lowe if (res != DW_DLV_OK) { 22807dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 229*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 23007dc1947SRichard Lowe } 23107dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 23207dc1947SRichard Lowe break; 23349d3bc91SRichard Lowe 23449d3bc91SRichard Lowe case DW_OP_lit0: 23549d3bc91SRichard Lowe case DW_OP_lit1: 23649d3bc91SRichard Lowe case DW_OP_lit2: 23749d3bc91SRichard Lowe case DW_OP_lit3: 23849d3bc91SRichard Lowe case DW_OP_lit4: 23949d3bc91SRichard Lowe case DW_OP_lit5: 24049d3bc91SRichard Lowe case DW_OP_lit6: 24149d3bc91SRichard Lowe case DW_OP_lit7: 24249d3bc91SRichard Lowe case DW_OP_lit8: 24349d3bc91SRichard Lowe case DW_OP_lit9: 24449d3bc91SRichard Lowe case DW_OP_lit10: 24549d3bc91SRichard Lowe case DW_OP_lit11: 24649d3bc91SRichard Lowe case DW_OP_lit12: 24749d3bc91SRichard Lowe case DW_OP_lit13: 24849d3bc91SRichard Lowe case DW_OP_lit14: 24949d3bc91SRichard Lowe case DW_OP_lit15: 25049d3bc91SRichard Lowe case DW_OP_lit16: 25149d3bc91SRichard Lowe case DW_OP_lit17: 25249d3bc91SRichard Lowe case DW_OP_lit18: 25349d3bc91SRichard Lowe case DW_OP_lit19: 25449d3bc91SRichard Lowe case DW_OP_lit20: 25549d3bc91SRichard Lowe case DW_OP_lit21: 25649d3bc91SRichard Lowe case DW_OP_lit22: 25749d3bc91SRichard Lowe case DW_OP_lit23: 25849d3bc91SRichard Lowe case DW_OP_lit24: 25949d3bc91SRichard Lowe case DW_OP_lit25: 26049d3bc91SRichard Lowe case DW_OP_lit26: 26149d3bc91SRichard Lowe case DW_OP_lit27: 26249d3bc91SRichard Lowe case DW_OP_lit28: 26349d3bc91SRichard Lowe case DW_OP_lit29: 26449d3bc91SRichard Lowe case DW_OP_lit30: 26549d3bc91SRichard Lowe case DW_OP_lit31: 26607dc1947SRichard Lowe break; 26749d3bc91SRichard Lowe 26849d3bc91SRichard Lowe case DW_OP_addr: 26907dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 270*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 27149d3bc91SRichard Lowe 27249d3bc91SRichard Lowe case DW_OP_const1u: 27349d3bc91SRichard Lowe case DW_OP_const1s: 27407dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 27507dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1); 27607dc1947SRichard Lowe operand_size = 1; 27707dc1947SRichard Lowe break; 27849d3bc91SRichard Lowe 27949d3bc91SRichard Lowe case DW_OP_const2u: 28049d3bc91SRichard Lowe case DW_OP_const2s: 28107dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 28207dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); 28307dc1947SRichard Lowe operand_size = 2; 28407dc1947SRichard Lowe break; 28549d3bc91SRichard Lowe 28649d3bc91SRichard Lowe case DW_OP_const4u: 28749d3bc91SRichard Lowe case DW_OP_const4s: 28807dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 289*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 290*4d9fdb46SRobert Mustacchi SIZEOFT32); 291*4d9fdb46SRobert Mustacchi operand_size = SIZEOFT32; 29207dc1947SRichard Lowe break; 29349d3bc91SRichard Lowe 29449d3bc91SRichard Lowe case DW_OP_const8u: 29549d3bc91SRichard Lowe case DW_OP_const8s: 29607dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 29707dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8); 29807dc1947SRichard Lowe operand_size = 8; 29907dc1947SRichard Lowe break; 30049d3bc91SRichard Lowe 30149d3bc91SRichard Lowe case DW_OP_constu: 30207dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, 303*4d9fdb46SRobert Mustacchi &operand_size, encode_buffer, sizeof(encode_buffer)); 30407dc1947SRichard Lowe if (res != DW_DLV_OK) { 30507dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 306*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 30707dc1947SRichard Lowe } 30807dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 30907dc1947SRichard Lowe break; 31049d3bc91SRichard Lowe 31149d3bc91SRichard Lowe case DW_OP_consts: 31207dc1947SRichard Lowe res = _dwarf_pro_encode_signed_leb128_nm(val1, 313*4d9fdb46SRobert Mustacchi &operand_size, 314*4d9fdb46SRobert Mustacchi encode_buffer, 315*4d9fdb46SRobert Mustacchi sizeof(encode_buffer)); 31607dc1947SRichard Lowe if (res != DW_DLV_OK) { 31707dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 318*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 31907dc1947SRichard Lowe } 32007dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 32107dc1947SRichard Lowe break; 32249d3bc91SRichard Lowe 32349d3bc91SRichard Lowe case DW_OP_fbreg: 32407dc1947SRichard Lowe res = _dwarf_pro_encode_signed_leb128_nm(val1, 325*4d9fdb46SRobert Mustacchi &operand_size, 326*4d9fdb46SRobert Mustacchi encode_buffer, 327*4d9fdb46SRobert Mustacchi sizeof(encode_buffer)); 32807dc1947SRichard Lowe if (res != DW_DLV_OK) { 32907dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 330*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 33107dc1947SRichard Lowe } 33207dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 33307dc1947SRichard Lowe break; 33449d3bc91SRichard Lowe 33549d3bc91SRichard Lowe case DW_OP_bregx: 33607dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 337*4d9fdb46SRobert Mustacchi encode_buffer, 338*4d9fdb46SRobert Mustacchi sizeof(encode_buffer)); 33907dc1947SRichard Lowe if (res != DW_DLV_OK) { 34007dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 341*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 34207dc1947SRichard Lowe } 34307dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 34407dc1947SRichard Lowe /* put this one directly into 'operand' at tail of prev value */ 34507dc1947SRichard Lowe res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size, 346*4d9fdb46SRobert Mustacchi ((char *) operand) + 347*4d9fdb46SRobert Mustacchi operand_size, 348*4d9fdb46SRobert Mustacchi sizeof(encode_buffer2)); 34907dc1947SRichard Lowe if (res != DW_DLV_OK) { 35007dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 351*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 35207dc1947SRichard Lowe } 35307dc1947SRichard Lowe operand_size += operand2_size; 35449d3bc91SRichard Lowe 35549d3bc91SRichard Lowe case DW_OP_dup: 35649d3bc91SRichard Lowe case DW_OP_drop: 35707dc1947SRichard Lowe break; 35849d3bc91SRichard Lowe 35949d3bc91SRichard Lowe case DW_OP_pick: 36007dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 36107dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, (const void *) &val1, 362*4d9fdb46SRobert Mustacchi sizeof(val1), 1); 36307dc1947SRichard Lowe operand_size = 1; 36407dc1947SRichard Lowe break; 36549d3bc91SRichard Lowe 36649d3bc91SRichard Lowe case DW_OP_over: 36749d3bc91SRichard Lowe case DW_OP_swap: 36849d3bc91SRichard Lowe case DW_OP_rot: 36949d3bc91SRichard Lowe case DW_OP_deref: 37049d3bc91SRichard Lowe case DW_OP_xderef: 37107dc1947SRichard Lowe break; 37249d3bc91SRichard Lowe 37349d3bc91SRichard Lowe case DW_OP_deref_size: 37449d3bc91SRichard Lowe case DW_OP_xderef_size: 37507dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 37607dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, (const void *) &val1, 377*4d9fdb46SRobert Mustacchi sizeof(val1), 1); 37807dc1947SRichard Lowe operand_size = 1; 37907dc1947SRichard Lowe break; 38049d3bc91SRichard Lowe 38149d3bc91SRichard Lowe case DW_OP_abs: 38249d3bc91SRichard Lowe case DW_OP_and: 38349d3bc91SRichard Lowe case DW_OP_div: 38449d3bc91SRichard Lowe case DW_OP_minus: 38549d3bc91SRichard Lowe case DW_OP_mod: 38649d3bc91SRichard Lowe case DW_OP_mul: 38749d3bc91SRichard Lowe case DW_OP_neg: 38849d3bc91SRichard Lowe case DW_OP_not: 38949d3bc91SRichard Lowe case DW_OP_or: 39049d3bc91SRichard Lowe case DW_OP_plus: 39107dc1947SRichard Lowe break; 39249d3bc91SRichard Lowe 39349d3bc91SRichard Lowe case DW_OP_plus_uconst: 39407dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 395*4d9fdb46SRobert Mustacchi encode_buffer, 396*4d9fdb46SRobert Mustacchi sizeof(encode_buffer)); 39707dc1947SRichard Lowe if (res != DW_DLV_OK) { 39807dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 399*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 40007dc1947SRichard Lowe } 40107dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 40207dc1947SRichard Lowe break; 40349d3bc91SRichard Lowe 40449d3bc91SRichard Lowe case DW_OP_shl: 40549d3bc91SRichard Lowe case DW_OP_shr: 40649d3bc91SRichard Lowe case DW_OP_shra: 40749d3bc91SRichard Lowe case DW_OP_xor: 40807dc1947SRichard Lowe break; 40949d3bc91SRichard Lowe 41049d3bc91SRichard Lowe case DW_OP_le: 41149d3bc91SRichard Lowe case DW_OP_ge: 41249d3bc91SRichard Lowe case DW_OP_eq: 41349d3bc91SRichard Lowe case DW_OP_lt: 41449d3bc91SRichard Lowe case DW_OP_gt: 41549d3bc91SRichard Lowe case DW_OP_ne: 41607dc1947SRichard Lowe break; 41749d3bc91SRichard Lowe 41849d3bc91SRichard Lowe case DW_OP_skip: 41949d3bc91SRichard Lowe case DW_OP_bra: 42007dc1947SRichard Lowe /* FIX: unhandled! OP_bra, OP_skip! */ 42107dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 422*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 42349d3bc91SRichard Lowe 42449d3bc91SRichard Lowe case DW_OP_piece: 42507dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 426*4d9fdb46SRobert Mustacchi encode_buffer, 427*4d9fdb46SRobert Mustacchi sizeof(encode_buffer)); 42807dc1947SRichard Lowe if (res != DW_DLV_OK) { 42907dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 430*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 43107dc1947SRichard Lowe } 43207dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 43307dc1947SRichard Lowe break; 43449d3bc91SRichard Lowe 43549d3bc91SRichard Lowe case DW_OP_nop: 43607dc1947SRichard Lowe break; 43707dc1947SRichard Lowe case DW_OP_push_object_address: /* DWARF3 */ 43807dc1947SRichard Lowe break; 43907dc1947SRichard Lowe case DW_OP_call2: /* DWARF3 */ 44007dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 441*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT16); 442*4d9fdb46SRobert Mustacchi operand_size = SIZEOFT16; 44307dc1947SRichard Lowe break; 44407dc1947SRichard Lowe 44507dc1947SRichard Lowe case DW_OP_call4: /* DWARF3 */ 44607dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 447*4d9fdb46SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT32); 448*4d9fdb46SRobert Mustacchi operand_size = SIZEOFT32; 44907dc1947SRichard Lowe break; 45007dc1947SRichard Lowe 45107dc1947SRichard Lowe case DW_OP_call_ref: /* DWARF3 */ 45207dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0]; 45307dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 454*4d9fdb46SRobert Mustacchi dbg->de_dwarf_offset_size); 455*4d9fdb46SRobert Mustacchi operand_size = dbg->de_dwarf_offset_size; 45607dc1947SRichard Lowe break; 45707dc1947SRichard Lowe case DW_OP_form_tls_address: /* DWARF3f */ 45807dc1947SRichard Lowe break; 45907dc1947SRichard Lowe case DW_OP_call_frame_cfa: /* DWARF3f */ 46007dc1947SRichard Lowe break; 46107dc1947SRichard Lowe case DW_OP_bit_piece: /* DWARF3f */ 46207dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 463*4d9fdb46SRobert Mustacchi encode_buffer, 464*4d9fdb46SRobert Mustacchi sizeof(encode_buffer)); 46507dc1947SRichard Lowe if (res != DW_DLV_OK) { 46607dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 467*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 46807dc1947SRichard Lowe } 46907dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer; 47007dc1947SRichard Lowe /* put this one directly into 'operand' at tail of prev value */ 47107dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size, 472*4d9fdb46SRobert Mustacchi ((char *) operand) + 473*4d9fdb46SRobert Mustacchi operand_size, 474*4d9fdb46SRobert Mustacchi sizeof(encode_buffer2)); 47507dc1947SRichard Lowe if (res != DW_DLV_OK) { 47607dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 477*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 47807dc1947SRichard Lowe } 47907dc1947SRichard Lowe operand_size += operand2_size; 480*4d9fdb46SRobert Mustacchi break; 48149d3bc91SRichard Lowe default: 48207dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 483*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 48449d3bc91SRichard Lowe } 48549d3bc91SRichard Lowe 48649d3bc91SRichard Lowe next_byte_offset = expr->ex_next_byte_offset + operand_size + 1; 48749d3bc91SRichard Lowe 48849d3bc91SRichard Lowe if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { 48907dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 490*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 49149d3bc91SRichard Lowe } 49249d3bc91SRichard Lowe 49349d3bc91SRichard Lowe next_byte_ptr = 49407dc1947SRichard Lowe &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; 49549d3bc91SRichard Lowe 49649d3bc91SRichard Lowe *next_byte_ptr = opcode; 49749d3bc91SRichard Lowe next_byte_ptr++; 498*4d9fdb46SRobert Mustacchi if (operand) { 499*4d9fdb46SRobert Mustacchi memcpy(next_byte_ptr, operand, operand_size); 500*4d9fdb46SRobert Mustacchi } 50149d3bc91SRichard Lowe 50249d3bc91SRichard Lowe expr->ex_next_byte_offset = next_byte_offset; 503*4d9fdb46SRobert Mustacchi *stream_length_out = next_byte_offset; 504*4d9fdb46SRobert Mustacchi return DW_DLV_OK; 50549d3bc91SRichard Lowe } 50649d3bc91SRichard Lowe 50749d3bc91SRichard Lowe Dwarf_Unsigned 50849d3bc91SRichard Lowe dwarf_add_expr_addr_b(Dwarf_P_Expr expr, 509*4d9fdb46SRobert Mustacchi Dwarf_Unsigned addr, 510*4d9fdb46SRobert Mustacchi Dwarf_Unsigned sym_index, 511*4d9fdb46SRobert Mustacchi Dwarf_Error * error) 512*4d9fdb46SRobert Mustacchi { 513*4d9fdb46SRobert Mustacchi Dwarf_Unsigned length = 0; 514*4d9fdb46SRobert Mustacchi int res = 0; 515*4d9fdb46SRobert Mustacchi 516*4d9fdb46SRobert Mustacchi res = dwarf_add_expr_addr_c(expr,addr,sym_index, 517*4d9fdb46SRobert Mustacchi &length,error); 518*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) { 519*4d9fdb46SRobert Mustacchi return DW_DLV_NOCOUNT; 520*4d9fdb46SRobert Mustacchi } 521*4d9fdb46SRobert Mustacchi return length; 522*4d9fdb46SRobert Mustacchi 523*4d9fdb46SRobert Mustacchi } 524*4d9fdb46SRobert Mustacchi int 525*4d9fdb46SRobert Mustacchi dwarf_add_expr_addr_c(Dwarf_P_Expr expr, 526*4d9fdb46SRobert Mustacchi Dwarf_Unsigned addr, 527*4d9fdb46SRobert Mustacchi Dwarf_Unsigned sym_index, 528*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *stream_length_out, 529*4d9fdb46SRobert Mustacchi Dwarf_Error * error) 53049d3bc91SRichard Lowe { 53149d3bc91SRichard Lowe Dwarf_P_Debug dbg; 53249d3bc91SRichard Lowe Dwarf_Small *next_byte_ptr; 53349d3bc91SRichard Lowe Dwarf_Unsigned next_byte_offset; 53449d3bc91SRichard Lowe int upointer_size; 53549d3bc91SRichard Lowe 53649d3bc91SRichard Lowe if (expr == NULL) { 53707dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 538*4d9fdb46SRobert Mustacchi return (DW_DLV_ERROR); 53949d3bc91SRichard Lowe } 54049d3bc91SRichard Lowe 54149d3bc91SRichard Lowe dbg = expr->ex_dbg; 54249d3bc91SRichard Lowe if (dbg == NULL) { 54307dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 544*4d9fdb46SRobert Mustacchi return (DW_DLV_ERROR); 54549d3bc91SRichard Lowe } 54649d3bc91SRichard Lowe 54749d3bc91SRichard Lowe upointer_size = dbg->de_pointer_size; 54849d3bc91SRichard Lowe next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1; 54949d3bc91SRichard Lowe if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { 55007dc1947SRichard Lowe _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); 551*4d9fdb46SRobert Mustacchi return (DW_DLV_ERROR); 55249d3bc91SRichard Lowe } 55349d3bc91SRichard Lowe 55449d3bc91SRichard Lowe next_byte_ptr = 55507dc1947SRichard Lowe &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; 55649d3bc91SRichard Lowe 55749d3bc91SRichard Lowe *next_byte_ptr = DW_OP_addr; 55849d3bc91SRichard Lowe next_byte_ptr++; 55949d3bc91SRichard Lowe WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr, 560*4d9fdb46SRobert Mustacchi sizeof(addr), upointer_size); 56149d3bc91SRichard Lowe 56249d3bc91SRichard Lowe if (expr->ex_reloc_offset != 0) { 56307dc1947SRichard Lowe _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR); 564*4d9fdb46SRobert Mustacchi return (DW_DLV_ERROR); 56549d3bc91SRichard Lowe } 56649d3bc91SRichard Lowe 56749d3bc91SRichard Lowe expr->ex_reloc_sym_index = sym_index; 56849d3bc91SRichard Lowe expr->ex_reloc_offset = expr->ex_next_byte_offset + 1; 56949d3bc91SRichard Lowe 57049d3bc91SRichard Lowe expr->ex_next_byte_offset = next_byte_offset; 571*4d9fdb46SRobert Mustacchi *stream_length_out = next_byte_offset; 572*4d9fdb46SRobert Mustacchi return DW_DLV_OK; 57349d3bc91SRichard Lowe } 57449d3bc91SRichard Lowe 57549d3bc91SRichard Lowe Dwarf_Unsigned 57649d3bc91SRichard Lowe dwarf_add_expr_addr(Dwarf_P_Expr expr, 577*4d9fdb46SRobert Mustacchi Dwarf_Unsigned addr, 578*4d9fdb46SRobert Mustacchi Dwarf_Signed sym_index, 579*4d9fdb46SRobert Mustacchi Dwarf_Error * error) 58049d3bc91SRichard Lowe { 581*4d9fdb46SRobert Mustacchi Dwarf_Unsigned length = 0; 582*4d9fdb46SRobert Mustacchi int res = 0; 583*4d9fdb46SRobert Mustacchi Dwarf_P_Debug dbg = 0; 584*4d9fdb46SRobert Mustacchi 585*4d9fdb46SRobert Mustacchi if (sym_index < 0) { 586*4d9fdb46SRobert Mustacchi _dwarf_p_error(dbg, error, 587*4d9fdb46SRobert Mustacchi DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD); 588*4d9fdb46SRobert Mustacchi return DW_DLV_NOCOUNT; 589*4d9fdb46SRobert Mustacchi } 590*4d9fdb46SRobert Mustacchi res = dwarf_add_expr_addr_c(expr, 591*4d9fdb46SRobert Mustacchi (Dwarf_Unsigned)addr, 592*4d9fdb46SRobert Mustacchi (Dwarf_Unsigned)sym_index, 593*4d9fdb46SRobert Mustacchi &length,error); 594*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) { 595*4d9fdb46SRobert Mustacchi return (Dwarf_Unsigned)DW_DLV_NOCOUNT; 596*4d9fdb46SRobert Mustacchi } 597*4d9fdb46SRobert Mustacchi return length; 59849d3bc91SRichard Lowe } 59949d3bc91SRichard Lowe 60049d3bc91SRichard Lowe Dwarf_Unsigned 60149d3bc91SRichard Lowe dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error) 602*4d9fdb46SRobert Mustacchi { 603*4d9fdb46SRobert Mustacchi Dwarf_Unsigned l = 0; 604*4d9fdb46SRobert Mustacchi int res = 0; 605*4d9fdb46SRobert Mustacchi 606*4d9fdb46SRobert Mustacchi res = dwarf_expr_current_offset_a(expr,&l,error); 607*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) { 608*4d9fdb46SRobert Mustacchi return (DW_DLV_NOCOUNT); 609*4d9fdb46SRobert Mustacchi } 610*4d9fdb46SRobert Mustacchi return l; 611*4d9fdb46SRobert Mustacchi } 612*4d9fdb46SRobert Mustacchi 613*4d9fdb46SRobert Mustacchi int 614*4d9fdb46SRobert Mustacchi dwarf_expr_current_offset_a(Dwarf_P_Expr expr, 615*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * stream_length_out, 616*4d9fdb46SRobert Mustacchi Dwarf_Error * error) 61749d3bc91SRichard Lowe { 61849d3bc91SRichard Lowe if (expr == NULL) { 61907dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 620*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 62149d3bc91SRichard Lowe } 62249d3bc91SRichard Lowe 62349d3bc91SRichard Lowe if (expr->ex_dbg == NULL) { 62407dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 625*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 62649d3bc91SRichard Lowe } 627*4d9fdb46SRobert Mustacchi *stream_length_out = expr->ex_next_byte_offset; 628*4d9fdb46SRobert Mustacchi return DW_DLV_OK; 62949d3bc91SRichard Lowe } 63049d3bc91SRichard Lowe 63107dc1947SRichard Lowe void 63207dc1947SRichard Lowe dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error) 63307dc1947SRichard Lowe { 634*4d9fdb46SRobert Mustacchi if (expr == NULL) { 635*4d9fdb46SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 636*4d9fdb46SRobert Mustacchi return; 637*4d9fdb46SRobert Mustacchi } 638*4d9fdb46SRobert Mustacchi expr->ex_next_byte_offset=0; 63907dc1947SRichard Lowe } 64007dc1947SRichard Lowe 64149d3bc91SRichard Lowe Dwarf_Addr 64249d3bc91SRichard Lowe dwarf_expr_into_block(Dwarf_P_Expr expr, 643*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * length, 644*4d9fdb46SRobert Mustacchi Dwarf_Error * error) 645*4d9fdb46SRobert Mustacchi { 646*4d9fdb46SRobert Mustacchi Dwarf_Small *addr = 0; 647*4d9fdb46SRobert Mustacchi int res = 0; 648*4d9fdb46SRobert Mustacchi 649*4d9fdb46SRobert Mustacchi res = dwarf_expr_into_block_a(expr,length,&addr,error); 650*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) { 651*4d9fdb46SRobert Mustacchi return (DW_DLV_BADADDR); 652*4d9fdb46SRobert Mustacchi } 653*4d9fdb46SRobert Mustacchi return (Dwarf_Addr)(uintptr_t)addr; 654*4d9fdb46SRobert Mustacchi } 655*4d9fdb46SRobert Mustacchi 656*4d9fdb46SRobert Mustacchi 657*4d9fdb46SRobert Mustacchi int 658*4d9fdb46SRobert Mustacchi dwarf_expr_into_block_a(Dwarf_P_Expr expr, 659*4d9fdb46SRobert Mustacchi Dwarf_Unsigned * length, 660*4d9fdb46SRobert Mustacchi Dwarf_Small ** address, 661*4d9fdb46SRobert Mustacchi Dwarf_Error * error) 66249d3bc91SRichard Lowe { 66349d3bc91SRichard Lowe if (expr == NULL) { 66407dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 665*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 66649d3bc91SRichard Lowe } 66749d3bc91SRichard Lowe 66849d3bc91SRichard Lowe if (expr->ex_dbg == NULL) { 66907dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 670*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR; 67149d3bc91SRichard Lowe } 67249d3bc91SRichard Lowe 67349d3bc91SRichard Lowe if (length != NULL) 67407dc1947SRichard Lowe *length = expr->ex_next_byte_offset; 675*4d9fdb46SRobert Mustacchi *address = &(expr->ex_byte_stream[0]); 676*4d9fdb46SRobert Mustacchi return DW_DLV_OK; 67749d3bc91SRichard Lowe } 678