1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. 5*7fd79137SRobert Mustacchi 6*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 7*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 8*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 9*7fd79137SRobert Mustacchi 10*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 11*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 12*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13*7fd79137SRobert Mustacchi 14*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 15*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 16*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 17*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 18*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 19*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 20*7fd79137SRobert Mustacchi 21*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 22*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 23*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 24*7fd79137SRobert Mustacchi USA. 25*7fd79137SRobert Mustacchi 26*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 27*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 28*7fd79137SRobert Mustacchi 29*7fd79137SRobert Mustacchi http://www.sgi.com 30*7fd79137SRobert Mustacchi 31*7fd79137SRobert Mustacchi For further information regarding this notice, see: 32*7fd79137SRobert Mustacchi 33*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 34*7fd79137SRobert Mustacchi 35*7fd79137SRobert Mustacchi */ 36*7fd79137SRobert Mustacchi 37*7fd79137SRobert Mustacchi 38*7fd79137SRobert Mustacchi 39*7fd79137SRobert Mustacchi #include "config.h" 40*7fd79137SRobert Mustacchi #include "libdwarfdefs.h" 41*7fd79137SRobert Mustacchi #include <stdio.h> 42*7fd79137SRobert Mustacchi #include <string.h> 43*7fd79137SRobert Mustacchi #include <sys/types.h> 44*7fd79137SRobert Mustacchi #include "pro_incl.h" 45*7fd79137SRobert Mustacchi #include "pro_expr.h" 46*7fd79137SRobert Mustacchi 47*7fd79137SRobert Mustacchi /* 48*7fd79137SRobert Mustacchi This function creates a new expression 49*7fd79137SRobert Mustacchi struct that can be used to build up a 50*7fd79137SRobert Mustacchi location expression. 51*7fd79137SRobert Mustacchi */ 52*7fd79137SRobert Mustacchi Dwarf_P_Expr 53*7fd79137SRobert Mustacchi dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error) 54*7fd79137SRobert Mustacchi { 55*7fd79137SRobert Mustacchi Dwarf_P_Expr ret_expr; 56*7fd79137SRobert Mustacchi 57*7fd79137SRobert Mustacchi if (dbg == NULL) { 58*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 59*7fd79137SRobert Mustacchi return (NULL); 60*7fd79137SRobert Mustacchi } 61*7fd79137SRobert Mustacchi 62*7fd79137SRobert Mustacchi ret_expr = (Dwarf_P_Expr) 63*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s)); 64*7fd79137SRobert Mustacchi if (ret_expr == NULL) { 65*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 66*7fd79137SRobert Mustacchi return (NULL); 67*7fd79137SRobert Mustacchi } 68*7fd79137SRobert Mustacchi 69*7fd79137SRobert Mustacchi ret_expr->ex_dbg = dbg; 70*7fd79137SRobert Mustacchi 71*7fd79137SRobert Mustacchi return (ret_expr); 72*7fd79137SRobert Mustacchi } 73*7fd79137SRobert Mustacchi 74*7fd79137SRobert Mustacchi 75*7fd79137SRobert Mustacchi Dwarf_Unsigned 76*7fd79137SRobert Mustacchi dwarf_add_expr_gen(Dwarf_P_Expr expr, 77*7fd79137SRobert Mustacchi Dwarf_Small opcode, 78*7fd79137SRobert Mustacchi Dwarf_Unsigned val1, 79*7fd79137SRobert Mustacchi Dwarf_Unsigned val2, Dwarf_Error * error) 80*7fd79137SRobert Mustacchi { 81*7fd79137SRobert Mustacchi char encode_buffer[2 * ENCODE_SPACE_NEEDED]; /* 2* since 82*7fd79137SRobert Mustacchi used to 83*7fd79137SRobert Mustacchi concatenate 84*7fd79137SRobert Mustacchi 2 leb's 85*7fd79137SRobert Mustacchi below */ 86*7fd79137SRobert Mustacchi char encode_buffer2[ENCODE_SPACE_NEEDED]; 87*7fd79137SRobert Mustacchi int res; 88*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg = expr->ex_dbg; 89*7fd79137SRobert Mustacchi 90*7fd79137SRobert Mustacchi /* 91*7fd79137SRobert Mustacchi Give the buffer where the operands are first going to be 92*7fd79137SRobert Mustacchi assembled the largest alignment. */ 93*7fd79137SRobert Mustacchi Dwarf_Unsigned operand_buffer[10]; 94*7fd79137SRobert Mustacchi 95*7fd79137SRobert Mustacchi /* 96*7fd79137SRobert Mustacchi Size of the byte stream buffer that needs to be memcpy-ed. */ 97*7fd79137SRobert Mustacchi int operand_size; 98*7fd79137SRobert Mustacchi 99*7fd79137SRobert Mustacchi /* 100*7fd79137SRobert Mustacchi Points to the byte stream for the first operand, and finally to 101*7fd79137SRobert Mustacchi the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */ 102*7fd79137SRobert Mustacchi Dwarf_Small *operand; 103*7fd79137SRobert Mustacchi 104*7fd79137SRobert Mustacchi /* Size of the byte stream for second operand. */ 105*7fd79137SRobert Mustacchi int operand2_size; 106*7fd79137SRobert Mustacchi 107*7fd79137SRobert Mustacchi /* Points to next byte to be written in Dwarf_P_Expr_s struct. */ 108*7fd79137SRobert Mustacchi Dwarf_Small *next_byte_ptr; 109*7fd79137SRobert Mustacchi 110*7fd79137SRobert Mustacchi /* Offset past the last byte written into Dwarf_P_Expr_s. */ 111*7fd79137SRobert Mustacchi int next_byte_offset; 112*7fd79137SRobert Mustacchi 113*7fd79137SRobert Mustacchi /* ***** BEGIN CODE ***** */ 114*7fd79137SRobert Mustacchi 115*7fd79137SRobert Mustacchi if (expr == NULL) { 116*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 117*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 118*7fd79137SRobert Mustacchi } 119*7fd79137SRobert Mustacchi 120*7fd79137SRobert Mustacchi if (expr->ex_dbg == NULL) { 121*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 122*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 123*7fd79137SRobert Mustacchi } 124*7fd79137SRobert Mustacchi 125*7fd79137SRobert Mustacchi operand = NULL; 126*7fd79137SRobert Mustacchi operand_size = 0; 127*7fd79137SRobert Mustacchi 128*7fd79137SRobert Mustacchi switch (opcode) { 129*7fd79137SRobert Mustacchi case DW_OP_reg0: 130*7fd79137SRobert Mustacchi case DW_OP_reg1: 131*7fd79137SRobert Mustacchi case DW_OP_reg2: 132*7fd79137SRobert Mustacchi case DW_OP_reg3: 133*7fd79137SRobert Mustacchi case DW_OP_reg4: 134*7fd79137SRobert Mustacchi case DW_OP_reg5: 135*7fd79137SRobert Mustacchi case DW_OP_reg6: 136*7fd79137SRobert Mustacchi case DW_OP_reg7: 137*7fd79137SRobert Mustacchi case DW_OP_reg8: 138*7fd79137SRobert Mustacchi case DW_OP_reg9: 139*7fd79137SRobert Mustacchi case DW_OP_reg10: 140*7fd79137SRobert Mustacchi case DW_OP_reg11: 141*7fd79137SRobert Mustacchi case DW_OP_reg12: 142*7fd79137SRobert Mustacchi case DW_OP_reg13: 143*7fd79137SRobert Mustacchi case DW_OP_reg14: 144*7fd79137SRobert Mustacchi case DW_OP_reg15: 145*7fd79137SRobert Mustacchi case DW_OP_reg16: 146*7fd79137SRobert Mustacchi case DW_OP_reg17: 147*7fd79137SRobert Mustacchi case DW_OP_reg18: 148*7fd79137SRobert Mustacchi case DW_OP_reg19: 149*7fd79137SRobert Mustacchi case DW_OP_reg20: 150*7fd79137SRobert Mustacchi case DW_OP_reg21: 151*7fd79137SRobert Mustacchi case DW_OP_reg22: 152*7fd79137SRobert Mustacchi case DW_OP_reg23: 153*7fd79137SRobert Mustacchi case DW_OP_reg24: 154*7fd79137SRobert Mustacchi case DW_OP_reg25: 155*7fd79137SRobert Mustacchi case DW_OP_reg26: 156*7fd79137SRobert Mustacchi case DW_OP_reg27: 157*7fd79137SRobert Mustacchi case DW_OP_reg28: 158*7fd79137SRobert Mustacchi case DW_OP_reg29: 159*7fd79137SRobert Mustacchi case DW_OP_reg30: 160*7fd79137SRobert Mustacchi case DW_OP_reg31: 161*7fd79137SRobert Mustacchi break; 162*7fd79137SRobert Mustacchi 163*7fd79137SRobert Mustacchi case DW_OP_breg0: 164*7fd79137SRobert Mustacchi case DW_OP_breg1: 165*7fd79137SRobert Mustacchi case DW_OP_breg2: 166*7fd79137SRobert Mustacchi case DW_OP_breg3: 167*7fd79137SRobert Mustacchi case DW_OP_breg4: 168*7fd79137SRobert Mustacchi case DW_OP_breg5: 169*7fd79137SRobert Mustacchi case DW_OP_breg6: 170*7fd79137SRobert Mustacchi case DW_OP_breg7: 171*7fd79137SRobert Mustacchi case DW_OP_breg8: 172*7fd79137SRobert Mustacchi case DW_OP_breg9: 173*7fd79137SRobert Mustacchi case DW_OP_breg10: 174*7fd79137SRobert Mustacchi case DW_OP_breg11: 175*7fd79137SRobert Mustacchi case DW_OP_breg12: 176*7fd79137SRobert Mustacchi case DW_OP_breg13: 177*7fd79137SRobert Mustacchi case DW_OP_breg14: 178*7fd79137SRobert Mustacchi case DW_OP_breg15: 179*7fd79137SRobert Mustacchi case DW_OP_breg16: 180*7fd79137SRobert Mustacchi case DW_OP_breg17: 181*7fd79137SRobert Mustacchi case DW_OP_breg18: 182*7fd79137SRobert Mustacchi case DW_OP_breg19: 183*7fd79137SRobert Mustacchi case DW_OP_breg20: 184*7fd79137SRobert Mustacchi case DW_OP_breg21: 185*7fd79137SRobert Mustacchi case DW_OP_breg22: 186*7fd79137SRobert Mustacchi case DW_OP_breg23: 187*7fd79137SRobert Mustacchi case DW_OP_breg24: 188*7fd79137SRobert Mustacchi case DW_OP_breg25: 189*7fd79137SRobert Mustacchi case DW_OP_breg26: 190*7fd79137SRobert Mustacchi case DW_OP_breg27: 191*7fd79137SRobert Mustacchi case DW_OP_breg28: 192*7fd79137SRobert Mustacchi case DW_OP_breg29: 193*7fd79137SRobert Mustacchi case DW_OP_breg30: 194*7fd79137SRobert Mustacchi case DW_OP_breg31: 195*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(val1, 196*7fd79137SRobert Mustacchi &operand_size, 197*7fd79137SRobert Mustacchi encode_buffer, 198*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 199*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 200*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 201*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 202*7fd79137SRobert Mustacchi } 203*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 204*7fd79137SRobert Mustacchi break; 205*7fd79137SRobert Mustacchi 206*7fd79137SRobert Mustacchi case DW_OP_regx: 207*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 208*7fd79137SRobert Mustacchi encode_buffer, 209*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 210*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 211*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 212*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 213*7fd79137SRobert Mustacchi } 214*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 215*7fd79137SRobert Mustacchi break; 216*7fd79137SRobert Mustacchi 217*7fd79137SRobert Mustacchi case DW_OP_lit0: 218*7fd79137SRobert Mustacchi case DW_OP_lit1: 219*7fd79137SRobert Mustacchi case DW_OP_lit2: 220*7fd79137SRobert Mustacchi case DW_OP_lit3: 221*7fd79137SRobert Mustacchi case DW_OP_lit4: 222*7fd79137SRobert Mustacchi case DW_OP_lit5: 223*7fd79137SRobert Mustacchi case DW_OP_lit6: 224*7fd79137SRobert Mustacchi case DW_OP_lit7: 225*7fd79137SRobert Mustacchi case DW_OP_lit8: 226*7fd79137SRobert Mustacchi case DW_OP_lit9: 227*7fd79137SRobert Mustacchi case DW_OP_lit10: 228*7fd79137SRobert Mustacchi case DW_OP_lit11: 229*7fd79137SRobert Mustacchi case DW_OP_lit12: 230*7fd79137SRobert Mustacchi case DW_OP_lit13: 231*7fd79137SRobert Mustacchi case DW_OP_lit14: 232*7fd79137SRobert Mustacchi case DW_OP_lit15: 233*7fd79137SRobert Mustacchi case DW_OP_lit16: 234*7fd79137SRobert Mustacchi case DW_OP_lit17: 235*7fd79137SRobert Mustacchi case DW_OP_lit18: 236*7fd79137SRobert Mustacchi case DW_OP_lit19: 237*7fd79137SRobert Mustacchi case DW_OP_lit20: 238*7fd79137SRobert Mustacchi case DW_OP_lit21: 239*7fd79137SRobert Mustacchi case DW_OP_lit22: 240*7fd79137SRobert Mustacchi case DW_OP_lit23: 241*7fd79137SRobert Mustacchi case DW_OP_lit24: 242*7fd79137SRobert Mustacchi case DW_OP_lit25: 243*7fd79137SRobert Mustacchi case DW_OP_lit26: 244*7fd79137SRobert Mustacchi case DW_OP_lit27: 245*7fd79137SRobert Mustacchi case DW_OP_lit28: 246*7fd79137SRobert Mustacchi case DW_OP_lit29: 247*7fd79137SRobert Mustacchi case DW_OP_lit30: 248*7fd79137SRobert Mustacchi case DW_OP_lit31: 249*7fd79137SRobert Mustacchi break; 250*7fd79137SRobert Mustacchi 251*7fd79137SRobert Mustacchi case DW_OP_addr: 252*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 253*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 254*7fd79137SRobert Mustacchi 255*7fd79137SRobert Mustacchi case DW_OP_const1u: 256*7fd79137SRobert Mustacchi case DW_OP_const1s: 257*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 258*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1); 259*7fd79137SRobert Mustacchi operand_size = 1; 260*7fd79137SRobert Mustacchi break; 261*7fd79137SRobert Mustacchi 262*7fd79137SRobert Mustacchi case DW_OP_const2u: 263*7fd79137SRobert Mustacchi case DW_OP_const2s: 264*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 265*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); 266*7fd79137SRobert Mustacchi operand_size = 2; 267*7fd79137SRobert Mustacchi break; 268*7fd79137SRobert Mustacchi 269*7fd79137SRobert Mustacchi case DW_OP_const4u: 270*7fd79137SRobert Mustacchi case DW_OP_const4s: 271*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 272*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4); 273*7fd79137SRobert Mustacchi operand_size = 4; 274*7fd79137SRobert Mustacchi break; 275*7fd79137SRobert Mustacchi 276*7fd79137SRobert Mustacchi case DW_OP_const8u: 277*7fd79137SRobert Mustacchi case DW_OP_const8s: 278*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 279*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8); 280*7fd79137SRobert Mustacchi operand_size = 8; 281*7fd79137SRobert Mustacchi break; 282*7fd79137SRobert Mustacchi 283*7fd79137SRobert Mustacchi case DW_OP_constu: 284*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, 285*7fd79137SRobert Mustacchi &operand_size, 286*7fd79137SRobert Mustacchi encode_buffer, 287*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 288*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 289*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 290*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 291*7fd79137SRobert Mustacchi } 292*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 293*7fd79137SRobert Mustacchi break; 294*7fd79137SRobert Mustacchi 295*7fd79137SRobert Mustacchi case DW_OP_consts: 296*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(val1, 297*7fd79137SRobert Mustacchi &operand_size, 298*7fd79137SRobert Mustacchi encode_buffer, 299*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 300*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 301*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 302*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 303*7fd79137SRobert Mustacchi } 304*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 305*7fd79137SRobert Mustacchi break; 306*7fd79137SRobert Mustacchi 307*7fd79137SRobert Mustacchi case DW_OP_fbreg: 308*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(val1, 309*7fd79137SRobert Mustacchi &operand_size, 310*7fd79137SRobert Mustacchi encode_buffer, 311*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 312*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 313*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 314*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 315*7fd79137SRobert Mustacchi } 316*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 317*7fd79137SRobert Mustacchi break; 318*7fd79137SRobert Mustacchi 319*7fd79137SRobert Mustacchi case DW_OP_bregx: 320*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 321*7fd79137SRobert Mustacchi encode_buffer, 322*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 323*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 324*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 325*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 326*7fd79137SRobert Mustacchi } 327*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 328*7fd79137SRobert Mustacchi /* put this one directly into 'operand' at tail of prev value */ 329*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size, 330*7fd79137SRobert Mustacchi ((char *) operand) + 331*7fd79137SRobert Mustacchi operand_size, 332*7fd79137SRobert Mustacchi sizeof 333*7fd79137SRobert Mustacchi (encode_buffer2)); 334*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 335*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 336*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 337*7fd79137SRobert Mustacchi } 338*7fd79137SRobert Mustacchi operand_size += operand2_size; 339*7fd79137SRobert Mustacchi 340*7fd79137SRobert Mustacchi case DW_OP_dup: 341*7fd79137SRobert Mustacchi case DW_OP_drop: 342*7fd79137SRobert Mustacchi break; 343*7fd79137SRobert Mustacchi 344*7fd79137SRobert Mustacchi case DW_OP_pick: 345*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 346*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, (const void *) &val1, 347*7fd79137SRobert Mustacchi sizeof(val1), 1); 348*7fd79137SRobert Mustacchi operand_size = 1; 349*7fd79137SRobert Mustacchi break; 350*7fd79137SRobert Mustacchi 351*7fd79137SRobert Mustacchi case DW_OP_over: 352*7fd79137SRobert Mustacchi case DW_OP_swap: 353*7fd79137SRobert Mustacchi case DW_OP_rot: 354*7fd79137SRobert Mustacchi case DW_OP_deref: 355*7fd79137SRobert Mustacchi case DW_OP_xderef: 356*7fd79137SRobert Mustacchi break; 357*7fd79137SRobert Mustacchi 358*7fd79137SRobert Mustacchi case DW_OP_deref_size: 359*7fd79137SRobert Mustacchi case DW_OP_xderef_size: 360*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 361*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, (const void *) &val1, 362*7fd79137SRobert Mustacchi sizeof(val1), 1); 363*7fd79137SRobert Mustacchi operand_size = 1; 364*7fd79137SRobert Mustacchi break; 365*7fd79137SRobert Mustacchi 366*7fd79137SRobert Mustacchi case DW_OP_abs: 367*7fd79137SRobert Mustacchi case DW_OP_and: 368*7fd79137SRobert Mustacchi case DW_OP_div: 369*7fd79137SRobert Mustacchi case DW_OP_minus: 370*7fd79137SRobert Mustacchi case DW_OP_mod: 371*7fd79137SRobert Mustacchi case DW_OP_mul: 372*7fd79137SRobert Mustacchi case DW_OP_neg: 373*7fd79137SRobert Mustacchi case DW_OP_not: 374*7fd79137SRobert Mustacchi case DW_OP_or: 375*7fd79137SRobert Mustacchi case DW_OP_plus: 376*7fd79137SRobert Mustacchi break; 377*7fd79137SRobert Mustacchi 378*7fd79137SRobert Mustacchi case DW_OP_plus_uconst: 379*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 380*7fd79137SRobert Mustacchi encode_buffer, 381*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 382*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 383*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 384*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 385*7fd79137SRobert Mustacchi } 386*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 387*7fd79137SRobert Mustacchi break; 388*7fd79137SRobert Mustacchi 389*7fd79137SRobert Mustacchi case DW_OP_shl: 390*7fd79137SRobert Mustacchi case DW_OP_shr: 391*7fd79137SRobert Mustacchi case DW_OP_shra: 392*7fd79137SRobert Mustacchi case DW_OP_xor: 393*7fd79137SRobert Mustacchi break; 394*7fd79137SRobert Mustacchi 395*7fd79137SRobert Mustacchi case DW_OP_le: 396*7fd79137SRobert Mustacchi case DW_OP_ge: 397*7fd79137SRobert Mustacchi case DW_OP_eq: 398*7fd79137SRobert Mustacchi case DW_OP_lt: 399*7fd79137SRobert Mustacchi case DW_OP_gt: 400*7fd79137SRobert Mustacchi case DW_OP_ne: 401*7fd79137SRobert Mustacchi break; 402*7fd79137SRobert Mustacchi 403*7fd79137SRobert Mustacchi case DW_OP_skip: 404*7fd79137SRobert Mustacchi case DW_OP_bra: 405*7fd79137SRobert Mustacchi /* FIX: unhandled! OP_bra, OP_skip! */ 406*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 407*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 408*7fd79137SRobert Mustacchi 409*7fd79137SRobert Mustacchi case DW_OP_piece: 410*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 411*7fd79137SRobert Mustacchi encode_buffer, 412*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 413*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 414*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 415*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 416*7fd79137SRobert Mustacchi } 417*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 418*7fd79137SRobert Mustacchi break; 419*7fd79137SRobert Mustacchi 420*7fd79137SRobert Mustacchi case DW_OP_nop: 421*7fd79137SRobert Mustacchi break; 422*7fd79137SRobert Mustacchi case DW_OP_push_object_address: /* DWARF3 */ 423*7fd79137SRobert Mustacchi break; 424*7fd79137SRobert Mustacchi case DW_OP_call2: /* DWARF3 */ 425*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 426*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); 427*7fd79137SRobert Mustacchi operand_size = 2; 428*7fd79137SRobert Mustacchi break; 429*7fd79137SRobert Mustacchi 430*7fd79137SRobert Mustacchi case DW_OP_call4: /* DWARF3 */ 431*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 432*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4); 433*7fd79137SRobert Mustacchi operand_size = 4; 434*7fd79137SRobert Mustacchi break; 435*7fd79137SRobert Mustacchi 436*7fd79137SRobert Mustacchi case DW_OP_call_ref: /* DWARF3 */ 437*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) & operand_buffer[0]; 438*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 439*7fd79137SRobert Mustacchi dbg->de_offset_size); 440*7fd79137SRobert Mustacchi operand_size = dbg->de_offset_size; 441*7fd79137SRobert Mustacchi break; 442*7fd79137SRobert Mustacchi case DW_OP_form_tls_address: /* DWARF3f */ 443*7fd79137SRobert Mustacchi break; 444*7fd79137SRobert Mustacchi case DW_OP_call_frame_cfa: /* DWARF3f */ 445*7fd79137SRobert Mustacchi break; 446*7fd79137SRobert Mustacchi case DW_OP_bit_piece: /* DWARF3f */ 447*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 448*7fd79137SRobert Mustacchi encode_buffer, 449*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 450*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 451*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 452*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 453*7fd79137SRobert Mustacchi } 454*7fd79137SRobert Mustacchi operand = (Dwarf_Small *) encode_buffer; 455*7fd79137SRobert Mustacchi /* put this one directly into 'operand' at tail of prev value */ 456*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size, 457*7fd79137SRobert Mustacchi ((char *) operand) + 458*7fd79137SRobert Mustacchi operand_size, 459*7fd79137SRobert Mustacchi sizeof(encode_buffer2)); 460*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 461*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 462*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 463*7fd79137SRobert Mustacchi } 464*7fd79137SRobert Mustacchi operand_size += operand2_size; 465*7fd79137SRobert Mustacchi 466*7fd79137SRobert Mustacchi 467*7fd79137SRobert Mustacchi default: 468*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 469*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 470*7fd79137SRobert Mustacchi } 471*7fd79137SRobert Mustacchi 472*7fd79137SRobert Mustacchi next_byte_offset = expr->ex_next_byte_offset + operand_size + 1; 473*7fd79137SRobert Mustacchi 474*7fd79137SRobert Mustacchi if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { 475*7fd79137SRobert Mustacchi _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 476*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 477*7fd79137SRobert Mustacchi } 478*7fd79137SRobert Mustacchi 479*7fd79137SRobert Mustacchi next_byte_ptr = 480*7fd79137SRobert Mustacchi &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; 481*7fd79137SRobert Mustacchi 482*7fd79137SRobert Mustacchi *next_byte_ptr = opcode; 483*7fd79137SRobert Mustacchi next_byte_ptr++; 484*7fd79137SRobert Mustacchi memcpy(next_byte_ptr, operand, operand_size); 485*7fd79137SRobert Mustacchi 486*7fd79137SRobert Mustacchi expr->ex_next_byte_offset = next_byte_offset; 487*7fd79137SRobert Mustacchi return (next_byte_offset); 488*7fd79137SRobert Mustacchi } 489*7fd79137SRobert Mustacchi 490*7fd79137SRobert Mustacchi Dwarf_Unsigned 491*7fd79137SRobert Mustacchi dwarf_add_expr_addr_b(Dwarf_P_Expr expr, 492*7fd79137SRobert Mustacchi Dwarf_Unsigned addr, 493*7fd79137SRobert Mustacchi Dwarf_Unsigned sym_index, Dwarf_Error * error) 494*7fd79137SRobert Mustacchi { 495*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg; 496*7fd79137SRobert Mustacchi Dwarf_Small *next_byte_ptr; 497*7fd79137SRobert Mustacchi Dwarf_Unsigned next_byte_offset; 498*7fd79137SRobert Mustacchi int upointer_size; 499*7fd79137SRobert Mustacchi 500*7fd79137SRobert Mustacchi if (expr == NULL) { 501*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 502*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 503*7fd79137SRobert Mustacchi } 504*7fd79137SRobert Mustacchi 505*7fd79137SRobert Mustacchi dbg = expr->ex_dbg; 506*7fd79137SRobert Mustacchi if (dbg == NULL) { 507*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 508*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 509*7fd79137SRobert Mustacchi } 510*7fd79137SRobert Mustacchi 511*7fd79137SRobert Mustacchi upointer_size = dbg->de_pointer_size; 512*7fd79137SRobert Mustacchi next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1; 513*7fd79137SRobert Mustacchi if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { 514*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); 515*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 516*7fd79137SRobert Mustacchi } 517*7fd79137SRobert Mustacchi 518*7fd79137SRobert Mustacchi next_byte_ptr = 519*7fd79137SRobert Mustacchi &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; 520*7fd79137SRobert Mustacchi 521*7fd79137SRobert Mustacchi *next_byte_ptr = DW_OP_addr; 522*7fd79137SRobert Mustacchi next_byte_ptr++; 523*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr, 524*7fd79137SRobert Mustacchi sizeof(addr), upointer_size); 525*7fd79137SRobert Mustacchi 526*7fd79137SRobert Mustacchi if (expr->ex_reloc_offset != 0) { 527*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR); 528*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 529*7fd79137SRobert Mustacchi } 530*7fd79137SRobert Mustacchi 531*7fd79137SRobert Mustacchi expr->ex_reloc_sym_index = sym_index; 532*7fd79137SRobert Mustacchi expr->ex_reloc_offset = expr->ex_next_byte_offset + 1; 533*7fd79137SRobert Mustacchi 534*7fd79137SRobert Mustacchi expr->ex_next_byte_offset = next_byte_offset; 535*7fd79137SRobert Mustacchi return (next_byte_offset); 536*7fd79137SRobert Mustacchi } 537*7fd79137SRobert Mustacchi 538*7fd79137SRobert Mustacchi Dwarf_Unsigned 539*7fd79137SRobert Mustacchi dwarf_add_expr_addr(Dwarf_P_Expr expr, 540*7fd79137SRobert Mustacchi Dwarf_Unsigned addr, 541*7fd79137SRobert Mustacchi Dwarf_Signed sym_index, Dwarf_Error * error) 542*7fd79137SRobert Mustacchi { 543*7fd79137SRobert Mustacchi return 544*7fd79137SRobert Mustacchi dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index, 545*7fd79137SRobert Mustacchi error); 546*7fd79137SRobert Mustacchi } 547*7fd79137SRobert Mustacchi 548*7fd79137SRobert Mustacchi 549*7fd79137SRobert Mustacchi Dwarf_Unsigned 550*7fd79137SRobert Mustacchi dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error) 551*7fd79137SRobert Mustacchi { 552*7fd79137SRobert Mustacchi if (expr == NULL) { 553*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 554*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 555*7fd79137SRobert Mustacchi } 556*7fd79137SRobert Mustacchi 557*7fd79137SRobert Mustacchi if (expr->ex_dbg == NULL) { 558*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 559*7fd79137SRobert Mustacchi return (DW_DLV_NOCOUNT); 560*7fd79137SRobert Mustacchi } 561*7fd79137SRobert Mustacchi 562*7fd79137SRobert Mustacchi return (expr->ex_next_byte_offset); 563*7fd79137SRobert Mustacchi } 564*7fd79137SRobert Mustacchi 565*7fd79137SRobert Mustacchi void 566*7fd79137SRobert Mustacchi dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error) 567*7fd79137SRobert Mustacchi { 568*7fd79137SRobert Mustacchi if (expr == NULL) { 569*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 570*7fd79137SRobert Mustacchi return; 571*7fd79137SRobert Mustacchi } 572*7fd79137SRobert Mustacchi expr->ex_next_byte_offset=0; 573*7fd79137SRobert Mustacchi } 574*7fd79137SRobert Mustacchi 575*7fd79137SRobert Mustacchi 576*7fd79137SRobert Mustacchi Dwarf_Addr 577*7fd79137SRobert Mustacchi dwarf_expr_into_block(Dwarf_P_Expr expr, 578*7fd79137SRobert Mustacchi Dwarf_Unsigned * length, Dwarf_Error * error) 579*7fd79137SRobert Mustacchi { 580*7fd79137SRobert Mustacchi if (expr == NULL) { 581*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 582*7fd79137SRobert Mustacchi return (DW_DLV_BADADDR); 583*7fd79137SRobert Mustacchi } 584*7fd79137SRobert Mustacchi 585*7fd79137SRobert Mustacchi if (expr->ex_dbg == NULL) { 586*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 587*7fd79137SRobert Mustacchi return (DW_DLV_BADADDR); 588*7fd79137SRobert Mustacchi } 589*7fd79137SRobert Mustacchi 590*7fd79137SRobert Mustacchi if (length != NULL) 591*7fd79137SRobert Mustacchi *length = expr->ex_next_byte_offset; 592*7fd79137SRobert Mustacchi /* The following cast from pointer to integer is ok as long as 593*7fd79137SRobert Mustacchi Dwarf_Addr is at least as large as a pointer. Which is a 594*7fd79137SRobert Mustacchi requirement of libdwarf so must be satisfied (some compilers 595*7fd79137SRobert Mustacchi emit a warning about the following line). */ 596*7fd79137SRobert Mustacchi return ((Dwarf_Addr)(uintptr_t) &(expr->ex_byte_stream[0])); 597*7fd79137SRobert Mustacchi } 598