1*2de3b87aSKai Wang /*- 2*2de3b87aSKai Wang * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3*2de3b87aSKai Wang * All rights reserved. 4*2de3b87aSKai Wang * 5*2de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without 6*2de3b87aSKai Wang * modification, are permitted provided that the following conditions 7*2de3b87aSKai Wang * are met: 8*2de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright 9*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer. 10*2de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright 11*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the 12*2de3b87aSKai Wang * documentation and/or other materials provided with the distribution. 13*2de3b87aSKai Wang * 14*2de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*2de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*2de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*2de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*2de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*2de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*2de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*2de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*2de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*2de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*2de3b87aSKai Wang * SUCH DAMAGE. 25*2de3b87aSKai Wang */ 26*2de3b87aSKai Wang 27*2de3b87aSKai Wang #include "_libdwarf.h" 28*2de3b87aSKai Wang 29*2de3b87aSKai Wang ELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $"); 30*2de3b87aSKai Wang 31*2de3b87aSKai Wang /* 32*2de3b87aSKai Wang * Given an array of bytes of length 'len' representing a 33*2de3b87aSKai Wang * DWARF expression, compute the number of operations based 34*2de3b87aSKai Wang * on there being one byte describing the operation and 35*2de3b87aSKai Wang * zero or more bytes of operands as defined in the standard 36*2de3b87aSKai Wang * for each operation type. Also, if lbuf is non-null, store 37*2de3b87aSKai Wang * the opcode and oprand in it. 38*2de3b87aSKai Wang */ 39*2de3b87aSKai Wang static int 40*2de3b87aSKai Wang _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, 41*2de3b87aSKai Wang uint8_t *p, int len) 42*2de3b87aSKai Wang { 43*2de3b87aSKai Wang int count; 44*2de3b87aSKai Wang uint64_t operand1; 45*2de3b87aSKai Wang uint64_t operand2; 46*2de3b87aSKai Wang uint8_t *ps, *pe; 47*2de3b87aSKai Wang 48*2de3b87aSKai Wang count = 0; 49*2de3b87aSKai Wang ps = p; 50*2de3b87aSKai Wang pe = p + len; 51*2de3b87aSKai Wang 52*2de3b87aSKai Wang /* 53*2de3b87aSKai Wang * Process each byte. If an error occurs, then the 54*2de3b87aSKai Wang * count will be set to -1. 55*2de3b87aSKai Wang */ 56*2de3b87aSKai Wang while (p < pe) { 57*2de3b87aSKai Wang 58*2de3b87aSKai Wang operand1 = 0; 59*2de3b87aSKai Wang operand2 = 0; 60*2de3b87aSKai Wang 61*2de3b87aSKai Wang if (lbuf != NULL) { 62*2de3b87aSKai Wang lbuf->ld_s[count].lr_atom = *p; 63*2de3b87aSKai Wang lbuf->ld_s[count].lr_offset = p - ps; 64*2de3b87aSKai Wang } 65*2de3b87aSKai Wang 66*2de3b87aSKai Wang switch (*p++) { 67*2de3b87aSKai Wang /* Operations with no operands. */ 68*2de3b87aSKai Wang case DW_OP_deref: 69*2de3b87aSKai Wang case DW_OP_reg0: 70*2de3b87aSKai Wang case DW_OP_reg1: 71*2de3b87aSKai Wang case DW_OP_reg2: 72*2de3b87aSKai Wang case DW_OP_reg3: 73*2de3b87aSKai Wang case DW_OP_reg4: 74*2de3b87aSKai Wang case DW_OP_reg5: 75*2de3b87aSKai Wang case DW_OP_reg6: 76*2de3b87aSKai Wang case DW_OP_reg7: 77*2de3b87aSKai Wang case DW_OP_reg8: 78*2de3b87aSKai Wang case DW_OP_reg9: 79*2de3b87aSKai Wang case DW_OP_reg10: 80*2de3b87aSKai Wang case DW_OP_reg11: 81*2de3b87aSKai Wang case DW_OP_reg12: 82*2de3b87aSKai Wang case DW_OP_reg13: 83*2de3b87aSKai Wang case DW_OP_reg14: 84*2de3b87aSKai Wang case DW_OP_reg15: 85*2de3b87aSKai Wang case DW_OP_reg16: 86*2de3b87aSKai Wang case DW_OP_reg17: 87*2de3b87aSKai Wang case DW_OP_reg18: 88*2de3b87aSKai Wang case DW_OP_reg19: 89*2de3b87aSKai Wang case DW_OP_reg20: 90*2de3b87aSKai Wang case DW_OP_reg21: 91*2de3b87aSKai Wang case DW_OP_reg22: 92*2de3b87aSKai Wang case DW_OP_reg23: 93*2de3b87aSKai Wang case DW_OP_reg24: 94*2de3b87aSKai Wang case DW_OP_reg25: 95*2de3b87aSKai Wang case DW_OP_reg26: 96*2de3b87aSKai Wang case DW_OP_reg27: 97*2de3b87aSKai Wang case DW_OP_reg28: 98*2de3b87aSKai Wang case DW_OP_reg29: 99*2de3b87aSKai Wang case DW_OP_reg30: 100*2de3b87aSKai Wang case DW_OP_reg31: 101*2de3b87aSKai Wang 102*2de3b87aSKai Wang case DW_OP_lit0: 103*2de3b87aSKai Wang case DW_OP_lit1: 104*2de3b87aSKai Wang case DW_OP_lit2: 105*2de3b87aSKai Wang case DW_OP_lit3: 106*2de3b87aSKai Wang case DW_OP_lit4: 107*2de3b87aSKai Wang case DW_OP_lit5: 108*2de3b87aSKai Wang case DW_OP_lit6: 109*2de3b87aSKai Wang case DW_OP_lit7: 110*2de3b87aSKai Wang case DW_OP_lit8: 111*2de3b87aSKai Wang case DW_OP_lit9: 112*2de3b87aSKai Wang case DW_OP_lit10: 113*2de3b87aSKai Wang case DW_OP_lit11: 114*2de3b87aSKai Wang case DW_OP_lit12: 115*2de3b87aSKai Wang case DW_OP_lit13: 116*2de3b87aSKai Wang case DW_OP_lit14: 117*2de3b87aSKai Wang case DW_OP_lit15: 118*2de3b87aSKai Wang case DW_OP_lit16: 119*2de3b87aSKai Wang case DW_OP_lit17: 120*2de3b87aSKai Wang case DW_OP_lit18: 121*2de3b87aSKai Wang case DW_OP_lit19: 122*2de3b87aSKai Wang case DW_OP_lit20: 123*2de3b87aSKai Wang case DW_OP_lit21: 124*2de3b87aSKai Wang case DW_OP_lit22: 125*2de3b87aSKai Wang case DW_OP_lit23: 126*2de3b87aSKai Wang case DW_OP_lit24: 127*2de3b87aSKai Wang case DW_OP_lit25: 128*2de3b87aSKai Wang case DW_OP_lit26: 129*2de3b87aSKai Wang case DW_OP_lit27: 130*2de3b87aSKai Wang case DW_OP_lit28: 131*2de3b87aSKai Wang case DW_OP_lit29: 132*2de3b87aSKai Wang case DW_OP_lit30: 133*2de3b87aSKai Wang case DW_OP_lit31: 134*2de3b87aSKai Wang 135*2de3b87aSKai Wang case DW_OP_dup: 136*2de3b87aSKai Wang case DW_OP_drop: 137*2de3b87aSKai Wang 138*2de3b87aSKai Wang case DW_OP_over: 139*2de3b87aSKai Wang 140*2de3b87aSKai Wang case DW_OP_swap: 141*2de3b87aSKai Wang case DW_OP_rot: 142*2de3b87aSKai Wang case DW_OP_xderef: 143*2de3b87aSKai Wang 144*2de3b87aSKai Wang case DW_OP_abs: 145*2de3b87aSKai Wang case DW_OP_and: 146*2de3b87aSKai Wang case DW_OP_div: 147*2de3b87aSKai Wang case DW_OP_minus: 148*2de3b87aSKai Wang case DW_OP_mod: 149*2de3b87aSKai Wang case DW_OP_mul: 150*2de3b87aSKai Wang case DW_OP_neg: 151*2de3b87aSKai Wang case DW_OP_not: 152*2de3b87aSKai Wang case DW_OP_or: 153*2de3b87aSKai Wang case DW_OP_plus: 154*2de3b87aSKai Wang 155*2de3b87aSKai Wang case DW_OP_shl: 156*2de3b87aSKai Wang case DW_OP_shr: 157*2de3b87aSKai Wang case DW_OP_shra: 158*2de3b87aSKai Wang case DW_OP_xor: 159*2de3b87aSKai Wang 160*2de3b87aSKai Wang case DW_OP_eq: 161*2de3b87aSKai Wang case DW_OP_ge: 162*2de3b87aSKai Wang case DW_OP_gt: 163*2de3b87aSKai Wang case DW_OP_le: 164*2de3b87aSKai Wang case DW_OP_lt: 165*2de3b87aSKai Wang case DW_OP_ne: 166*2de3b87aSKai Wang 167*2de3b87aSKai Wang case DW_OP_nop: 168*2de3b87aSKai Wang case DW_OP_form_tls_address: 169*2de3b87aSKai Wang case DW_OP_call_frame_cfa: 170*2de3b87aSKai Wang case DW_OP_stack_value: 171*2de3b87aSKai Wang case DW_OP_GNU_push_tls_address: 172*2de3b87aSKai Wang break; 173*2de3b87aSKai Wang 174*2de3b87aSKai Wang /* Operations with 1-byte operands. */ 175*2de3b87aSKai Wang case DW_OP_const1u: 176*2de3b87aSKai Wang case DW_OP_const1s: 177*2de3b87aSKai Wang case DW_OP_pick: 178*2de3b87aSKai Wang case DW_OP_deref_size: 179*2de3b87aSKai Wang case DW_OP_xderef_size: 180*2de3b87aSKai Wang operand1 = *p++; 181*2de3b87aSKai Wang break; 182*2de3b87aSKai Wang 183*2de3b87aSKai Wang /* Operations with 2-byte operands. */ 184*2de3b87aSKai Wang case DW_OP_call2: 185*2de3b87aSKai Wang case DW_OP_const2u: 186*2de3b87aSKai Wang case DW_OP_const2s: 187*2de3b87aSKai Wang case DW_OP_bra: 188*2de3b87aSKai Wang case DW_OP_skip: 189*2de3b87aSKai Wang operand1 = dbg->decode(&p, 2); 190*2de3b87aSKai Wang break; 191*2de3b87aSKai Wang 192*2de3b87aSKai Wang /* Operations with 4-byte operands. */ 193*2de3b87aSKai Wang case DW_OP_call4: 194*2de3b87aSKai Wang case DW_OP_const4u: 195*2de3b87aSKai Wang case DW_OP_const4s: 196*2de3b87aSKai Wang operand1 = dbg->decode(&p, 4); 197*2de3b87aSKai Wang break; 198*2de3b87aSKai Wang 199*2de3b87aSKai Wang /* Operations with 8-byte operands. */ 200*2de3b87aSKai Wang case DW_OP_const8u: 201*2de3b87aSKai Wang case DW_OP_const8s: 202*2de3b87aSKai Wang operand1 = dbg->decode(&p, 8); 203*2de3b87aSKai Wang break; 204*2de3b87aSKai Wang 205*2de3b87aSKai Wang /* Operations with an unsigned LEB128 operand. */ 206*2de3b87aSKai Wang case DW_OP_constu: 207*2de3b87aSKai Wang case DW_OP_plus_uconst: 208*2de3b87aSKai Wang case DW_OP_regx: 209*2de3b87aSKai Wang case DW_OP_piece: 210*2de3b87aSKai Wang operand1 = _dwarf_decode_uleb128(&p); 211*2de3b87aSKai Wang break; 212*2de3b87aSKai Wang 213*2de3b87aSKai Wang /* Operations with a signed LEB128 operand. */ 214*2de3b87aSKai Wang case DW_OP_consts: 215*2de3b87aSKai Wang case DW_OP_breg0: 216*2de3b87aSKai Wang case DW_OP_breg1: 217*2de3b87aSKai Wang case DW_OP_breg2: 218*2de3b87aSKai Wang case DW_OP_breg3: 219*2de3b87aSKai Wang case DW_OP_breg4: 220*2de3b87aSKai Wang case DW_OP_breg5: 221*2de3b87aSKai Wang case DW_OP_breg6: 222*2de3b87aSKai Wang case DW_OP_breg7: 223*2de3b87aSKai Wang case DW_OP_breg8: 224*2de3b87aSKai Wang case DW_OP_breg9: 225*2de3b87aSKai Wang case DW_OP_breg10: 226*2de3b87aSKai Wang case DW_OP_breg11: 227*2de3b87aSKai Wang case DW_OP_breg12: 228*2de3b87aSKai Wang case DW_OP_breg13: 229*2de3b87aSKai Wang case DW_OP_breg14: 230*2de3b87aSKai Wang case DW_OP_breg15: 231*2de3b87aSKai Wang case DW_OP_breg16: 232*2de3b87aSKai Wang case DW_OP_breg17: 233*2de3b87aSKai Wang case DW_OP_breg18: 234*2de3b87aSKai Wang case DW_OP_breg19: 235*2de3b87aSKai Wang case DW_OP_breg20: 236*2de3b87aSKai Wang case DW_OP_breg21: 237*2de3b87aSKai Wang case DW_OP_breg22: 238*2de3b87aSKai Wang case DW_OP_breg23: 239*2de3b87aSKai Wang case DW_OP_breg24: 240*2de3b87aSKai Wang case DW_OP_breg25: 241*2de3b87aSKai Wang case DW_OP_breg26: 242*2de3b87aSKai Wang case DW_OP_breg27: 243*2de3b87aSKai Wang case DW_OP_breg28: 244*2de3b87aSKai Wang case DW_OP_breg29: 245*2de3b87aSKai Wang case DW_OP_breg30: 246*2de3b87aSKai Wang case DW_OP_breg31: 247*2de3b87aSKai Wang case DW_OP_fbreg: 248*2de3b87aSKai Wang operand1 = _dwarf_decode_sleb128(&p); 249*2de3b87aSKai Wang break; 250*2de3b87aSKai Wang 251*2de3b87aSKai Wang /* 252*2de3b87aSKai Wang * Oeration with two unsigned LEB128 operands. 253*2de3b87aSKai Wang */ 254*2de3b87aSKai Wang case DW_OP_bit_piece: 255*2de3b87aSKai Wang operand1 = _dwarf_decode_uleb128(&p); 256*2de3b87aSKai Wang operand2 = _dwarf_decode_uleb128(&p); 257*2de3b87aSKai Wang break; 258*2de3b87aSKai Wang 259*2de3b87aSKai Wang /* 260*2de3b87aSKai Wang * Operations with an unsigned LEB128 operand 261*2de3b87aSKai Wang * followed by a signed LEB128 operand. 262*2de3b87aSKai Wang */ 263*2de3b87aSKai Wang case DW_OP_bregx: 264*2de3b87aSKai Wang operand1 = _dwarf_decode_uleb128(&p); 265*2de3b87aSKai Wang operand2 = _dwarf_decode_sleb128(&p); 266*2de3b87aSKai Wang break; 267*2de3b87aSKai Wang 268*2de3b87aSKai Wang /* 269*2de3b87aSKai Wang * Operation with an unsigned LEB128 operand 270*2de3b87aSKai Wang * followed by a block. Store a pointer to the 271*2de3b87aSKai Wang * block in the operand2. 272*2de3b87aSKai Wang */ 273*2de3b87aSKai Wang case DW_OP_implicit_value: 274*2de3b87aSKai Wang operand1 = _dwarf_decode_uleb128(&p); 275*2de3b87aSKai Wang operand2 = (Dwarf_Unsigned) (uintptr_t) p; 276*2de3b87aSKai Wang p += operand1; 277*2de3b87aSKai Wang break; 278*2de3b87aSKai Wang 279*2de3b87aSKai Wang /* Target address size operand. */ 280*2de3b87aSKai Wang case DW_OP_addr: 281*2de3b87aSKai Wang operand1 = dbg->decode(&p, pointer_size); 282*2de3b87aSKai Wang break; 283*2de3b87aSKai Wang 284*2de3b87aSKai Wang /* 285*2de3b87aSKai Wang * XXX Opcode DW_OP_call_ref has an operand with size 286*2de3b87aSKai Wang * "dwarf_size". Here we use dbg->dbg_offset_size 287*2de3b87aSKai Wang * as "dwarf_size" to be compatible with SGI libdwarf. 288*2de3b87aSKai Wang * However note that dbg->dbg_offset_size is just 289*2de3b87aSKai Wang * a "guess" value so the parsing result of 290*2de3b87aSKai Wang * DW_OP_call_ref might not be correct at all. XXX 291*2de3b87aSKai Wang */ 292*2de3b87aSKai Wang case DW_OP_call_ref: 293*2de3b87aSKai Wang operand1 = dbg->decode(&p, dbg->dbg_offset_size); 294*2de3b87aSKai Wang break; 295*2de3b87aSKai Wang 296*2de3b87aSKai Wang /* All other operations cause an error. */ 297*2de3b87aSKai Wang default: 298*2de3b87aSKai Wang count = -1; 299*2de3b87aSKai Wang break; 300*2de3b87aSKai Wang } 301*2de3b87aSKai Wang 302*2de3b87aSKai Wang if (lbuf != NULL) { 303*2de3b87aSKai Wang lbuf->ld_s[count].lr_number = operand1; 304*2de3b87aSKai Wang lbuf->ld_s[count].lr_number2 = operand2; 305*2de3b87aSKai Wang } 306*2de3b87aSKai Wang 307*2de3b87aSKai Wang count++; 308*2de3b87aSKai Wang } 309*2de3b87aSKai Wang 310*2de3b87aSKai Wang return (count); 311*2de3b87aSKai Wang } 312*2de3b87aSKai Wang 313*2de3b87aSKai Wang int 314*2de3b87aSKai Wang _dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end, 315*2de3b87aSKai Wang Dwarf_Small atom, Dwarf_Unsigned operand1, Dwarf_Unsigned operand2, 316*2de3b87aSKai Wang int *length, Dwarf_Error *error) 317*2de3b87aSKai Wang { 318*2de3b87aSKai Wang uint8_t buf[64]; 319*2de3b87aSKai Wang uint8_t *p, *pe; 320*2de3b87aSKai Wang uint64_t offset; 321*2de3b87aSKai Wang int len; 322*2de3b87aSKai Wang 323*2de3b87aSKai Wang if (out != NULL && end != NULL) { 324*2de3b87aSKai Wang p = out; 325*2de3b87aSKai Wang pe = end; 326*2de3b87aSKai Wang } else { 327*2de3b87aSKai Wang p = out = buf; 328*2de3b87aSKai Wang pe = &buf[sizeof(buf)]; 329*2de3b87aSKai Wang } 330*2de3b87aSKai Wang 331*2de3b87aSKai Wang switch (atom) { 332*2de3b87aSKai Wang /* Operations with no operands. */ 333*2de3b87aSKai Wang case DW_OP_deref: 334*2de3b87aSKai Wang case DW_OP_reg0: 335*2de3b87aSKai Wang case DW_OP_reg1: 336*2de3b87aSKai Wang case DW_OP_reg2: 337*2de3b87aSKai Wang case DW_OP_reg3: 338*2de3b87aSKai Wang case DW_OP_reg4: 339*2de3b87aSKai Wang case DW_OP_reg5: 340*2de3b87aSKai Wang case DW_OP_reg6: 341*2de3b87aSKai Wang case DW_OP_reg7: 342*2de3b87aSKai Wang case DW_OP_reg8: 343*2de3b87aSKai Wang case DW_OP_reg9: 344*2de3b87aSKai Wang case DW_OP_reg10: 345*2de3b87aSKai Wang case DW_OP_reg11: 346*2de3b87aSKai Wang case DW_OP_reg12: 347*2de3b87aSKai Wang case DW_OP_reg13: 348*2de3b87aSKai Wang case DW_OP_reg14: 349*2de3b87aSKai Wang case DW_OP_reg15: 350*2de3b87aSKai Wang case DW_OP_reg16: 351*2de3b87aSKai Wang case DW_OP_reg17: 352*2de3b87aSKai Wang case DW_OP_reg18: 353*2de3b87aSKai Wang case DW_OP_reg19: 354*2de3b87aSKai Wang case DW_OP_reg20: 355*2de3b87aSKai Wang case DW_OP_reg21: 356*2de3b87aSKai Wang case DW_OP_reg22: 357*2de3b87aSKai Wang case DW_OP_reg23: 358*2de3b87aSKai Wang case DW_OP_reg24: 359*2de3b87aSKai Wang case DW_OP_reg25: 360*2de3b87aSKai Wang case DW_OP_reg26: 361*2de3b87aSKai Wang case DW_OP_reg27: 362*2de3b87aSKai Wang case DW_OP_reg28: 363*2de3b87aSKai Wang case DW_OP_reg29: 364*2de3b87aSKai Wang case DW_OP_reg30: 365*2de3b87aSKai Wang case DW_OP_reg31: 366*2de3b87aSKai Wang 367*2de3b87aSKai Wang case DW_OP_lit0: 368*2de3b87aSKai Wang case DW_OP_lit1: 369*2de3b87aSKai Wang case DW_OP_lit2: 370*2de3b87aSKai Wang case DW_OP_lit3: 371*2de3b87aSKai Wang case DW_OP_lit4: 372*2de3b87aSKai Wang case DW_OP_lit5: 373*2de3b87aSKai Wang case DW_OP_lit6: 374*2de3b87aSKai Wang case DW_OP_lit7: 375*2de3b87aSKai Wang case DW_OP_lit8: 376*2de3b87aSKai Wang case DW_OP_lit9: 377*2de3b87aSKai Wang case DW_OP_lit10: 378*2de3b87aSKai Wang case DW_OP_lit11: 379*2de3b87aSKai Wang case DW_OP_lit12: 380*2de3b87aSKai Wang case DW_OP_lit13: 381*2de3b87aSKai Wang case DW_OP_lit14: 382*2de3b87aSKai Wang case DW_OP_lit15: 383*2de3b87aSKai Wang case DW_OP_lit16: 384*2de3b87aSKai Wang case DW_OP_lit17: 385*2de3b87aSKai Wang case DW_OP_lit18: 386*2de3b87aSKai Wang case DW_OP_lit19: 387*2de3b87aSKai Wang case DW_OP_lit20: 388*2de3b87aSKai Wang case DW_OP_lit21: 389*2de3b87aSKai Wang case DW_OP_lit22: 390*2de3b87aSKai Wang case DW_OP_lit23: 391*2de3b87aSKai Wang case DW_OP_lit24: 392*2de3b87aSKai Wang case DW_OP_lit25: 393*2de3b87aSKai Wang case DW_OP_lit26: 394*2de3b87aSKai Wang case DW_OP_lit27: 395*2de3b87aSKai Wang case DW_OP_lit28: 396*2de3b87aSKai Wang case DW_OP_lit29: 397*2de3b87aSKai Wang case DW_OP_lit30: 398*2de3b87aSKai Wang case DW_OP_lit31: 399*2de3b87aSKai Wang 400*2de3b87aSKai Wang case DW_OP_dup: 401*2de3b87aSKai Wang case DW_OP_drop: 402*2de3b87aSKai Wang 403*2de3b87aSKai Wang case DW_OP_over: 404*2de3b87aSKai Wang 405*2de3b87aSKai Wang case DW_OP_swap: 406*2de3b87aSKai Wang case DW_OP_rot: 407*2de3b87aSKai Wang case DW_OP_xderef: 408*2de3b87aSKai Wang 409*2de3b87aSKai Wang case DW_OP_abs: 410*2de3b87aSKai Wang case DW_OP_and: 411*2de3b87aSKai Wang case DW_OP_div: 412*2de3b87aSKai Wang case DW_OP_minus: 413*2de3b87aSKai Wang case DW_OP_mod: 414*2de3b87aSKai Wang case DW_OP_mul: 415*2de3b87aSKai Wang case DW_OP_neg: 416*2de3b87aSKai Wang case DW_OP_not: 417*2de3b87aSKai Wang case DW_OP_or: 418*2de3b87aSKai Wang case DW_OP_plus: 419*2de3b87aSKai Wang 420*2de3b87aSKai Wang case DW_OP_shl: 421*2de3b87aSKai Wang case DW_OP_shr: 422*2de3b87aSKai Wang case DW_OP_shra: 423*2de3b87aSKai Wang case DW_OP_xor: 424*2de3b87aSKai Wang 425*2de3b87aSKai Wang case DW_OP_eq: 426*2de3b87aSKai Wang case DW_OP_ge: 427*2de3b87aSKai Wang case DW_OP_gt: 428*2de3b87aSKai Wang case DW_OP_le: 429*2de3b87aSKai Wang case DW_OP_lt: 430*2de3b87aSKai Wang case DW_OP_ne: 431*2de3b87aSKai Wang 432*2de3b87aSKai Wang case DW_OP_nop: 433*2de3b87aSKai Wang case DW_OP_GNU_push_tls_address: 434*2de3b87aSKai Wang *p++ = atom; 435*2de3b87aSKai Wang break; 436*2de3b87aSKai Wang 437*2de3b87aSKai Wang /* Operations with 1-byte operands. */ 438*2de3b87aSKai Wang case DW_OP_const1u: 439*2de3b87aSKai Wang case DW_OP_const1s: 440*2de3b87aSKai Wang case DW_OP_pick: 441*2de3b87aSKai Wang case DW_OP_deref_size: 442*2de3b87aSKai Wang case DW_OP_xderef_size: 443*2de3b87aSKai Wang *p++ = atom; 444*2de3b87aSKai Wang *p++ = (uint8_t) operand1; 445*2de3b87aSKai Wang break; 446*2de3b87aSKai Wang 447*2de3b87aSKai Wang /* Operations with 2-byte operands. */ 448*2de3b87aSKai Wang case DW_OP_const2u: 449*2de3b87aSKai Wang case DW_OP_const2s: 450*2de3b87aSKai Wang case DW_OP_bra: 451*2de3b87aSKai Wang case DW_OP_skip: 452*2de3b87aSKai Wang *p++ = atom; 453*2de3b87aSKai Wang offset = 0; 454*2de3b87aSKai Wang dbg->write(p, &offset, operand1, 2); 455*2de3b87aSKai Wang p += 2; 456*2de3b87aSKai Wang break; 457*2de3b87aSKai Wang 458*2de3b87aSKai Wang /* Operations with 4-byte operands. */ 459*2de3b87aSKai Wang case DW_OP_const4u: 460*2de3b87aSKai Wang case DW_OP_const4s: 461*2de3b87aSKai Wang *p++ = atom; 462*2de3b87aSKai Wang offset = 0; 463*2de3b87aSKai Wang dbg->write(p, &offset, operand1, 4); 464*2de3b87aSKai Wang p += 4; 465*2de3b87aSKai Wang break; 466*2de3b87aSKai Wang 467*2de3b87aSKai Wang /* Operations with 8-byte operands. */ 468*2de3b87aSKai Wang case DW_OP_const8u: 469*2de3b87aSKai Wang case DW_OP_const8s: 470*2de3b87aSKai Wang *p++ = atom; 471*2de3b87aSKai Wang offset = 0; 472*2de3b87aSKai Wang dbg->write(p, &offset, operand1, 8); 473*2de3b87aSKai Wang p += 8; 474*2de3b87aSKai Wang break; 475*2de3b87aSKai Wang 476*2de3b87aSKai Wang /* Operations with an unsigned LEB128 operand. */ 477*2de3b87aSKai Wang case DW_OP_constu: 478*2de3b87aSKai Wang case DW_OP_plus_uconst: 479*2de3b87aSKai Wang case DW_OP_regx: 480*2de3b87aSKai Wang case DW_OP_piece: 481*2de3b87aSKai Wang *p++ = atom; 482*2de3b87aSKai Wang len = _dwarf_write_uleb128(p, pe, operand1); 483*2de3b87aSKai Wang assert(len > 0); 484*2de3b87aSKai Wang p += len; 485*2de3b87aSKai Wang break; 486*2de3b87aSKai Wang 487*2de3b87aSKai Wang /* Operations with a signed LEB128 operand. */ 488*2de3b87aSKai Wang case DW_OP_consts: 489*2de3b87aSKai Wang case DW_OP_breg0: 490*2de3b87aSKai Wang case DW_OP_breg1: 491*2de3b87aSKai Wang case DW_OP_breg2: 492*2de3b87aSKai Wang case DW_OP_breg3: 493*2de3b87aSKai Wang case DW_OP_breg4: 494*2de3b87aSKai Wang case DW_OP_breg5: 495*2de3b87aSKai Wang case DW_OP_breg6: 496*2de3b87aSKai Wang case DW_OP_breg7: 497*2de3b87aSKai Wang case DW_OP_breg8: 498*2de3b87aSKai Wang case DW_OP_breg9: 499*2de3b87aSKai Wang case DW_OP_breg10: 500*2de3b87aSKai Wang case DW_OP_breg11: 501*2de3b87aSKai Wang case DW_OP_breg12: 502*2de3b87aSKai Wang case DW_OP_breg13: 503*2de3b87aSKai Wang case DW_OP_breg14: 504*2de3b87aSKai Wang case DW_OP_breg15: 505*2de3b87aSKai Wang case DW_OP_breg16: 506*2de3b87aSKai Wang case DW_OP_breg17: 507*2de3b87aSKai Wang case DW_OP_breg18: 508*2de3b87aSKai Wang case DW_OP_breg19: 509*2de3b87aSKai Wang case DW_OP_breg20: 510*2de3b87aSKai Wang case DW_OP_breg21: 511*2de3b87aSKai Wang case DW_OP_breg22: 512*2de3b87aSKai Wang case DW_OP_breg23: 513*2de3b87aSKai Wang case DW_OP_breg24: 514*2de3b87aSKai Wang case DW_OP_breg25: 515*2de3b87aSKai Wang case DW_OP_breg26: 516*2de3b87aSKai Wang case DW_OP_breg27: 517*2de3b87aSKai Wang case DW_OP_breg28: 518*2de3b87aSKai Wang case DW_OP_breg29: 519*2de3b87aSKai Wang case DW_OP_breg30: 520*2de3b87aSKai Wang case DW_OP_breg31: 521*2de3b87aSKai Wang case DW_OP_fbreg: 522*2de3b87aSKai Wang *p++ = atom; 523*2de3b87aSKai Wang len = _dwarf_write_sleb128(p, pe, operand1); 524*2de3b87aSKai Wang assert(len > 0); 525*2de3b87aSKai Wang p += len; 526*2de3b87aSKai Wang break; 527*2de3b87aSKai Wang 528*2de3b87aSKai Wang /* 529*2de3b87aSKai Wang * Operations with an unsigned LEB128 operand 530*2de3b87aSKai Wang * followed by a signed LEB128 operand. 531*2de3b87aSKai Wang */ 532*2de3b87aSKai Wang case DW_OP_bregx: 533*2de3b87aSKai Wang *p++ = atom; 534*2de3b87aSKai Wang len = _dwarf_write_uleb128(p, pe, operand1); 535*2de3b87aSKai Wang assert(len > 0); 536*2de3b87aSKai Wang p += len; 537*2de3b87aSKai Wang len = _dwarf_write_sleb128(p, pe, operand2); 538*2de3b87aSKai Wang assert(len > 0); 539*2de3b87aSKai Wang p += len; 540*2de3b87aSKai Wang break; 541*2de3b87aSKai Wang 542*2de3b87aSKai Wang /* Target address size operand. */ 543*2de3b87aSKai Wang case DW_OP_addr: 544*2de3b87aSKai Wang *p++ = atom; 545*2de3b87aSKai Wang offset = 0; 546*2de3b87aSKai Wang dbg->write(p, &offset, operand1, dbg->dbg_pointer_size); 547*2de3b87aSKai Wang p += dbg->dbg_pointer_size; 548*2de3b87aSKai Wang break; 549*2de3b87aSKai Wang 550*2de3b87aSKai Wang /* All other operations cause an error. */ 551*2de3b87aSKai Wang default: 552*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); 553*2de3b87aSKai Wang return (DW_DLE_LOC_EXPR_BAD); 554*2de3b87aSKai Wang } 555*2de3b87aSKai Wang 556*2de3b87aSKai Wang if (length) 557*2de3b87aSKai Wang *length = p - out; 558*2de3b87aSKai Wang 559*2de3b87aSKai Wang return (DW_DLE_NONE); 560*2de3b87aSKai Wang } 561*2de3b87aSKai Wang 562*2de3b87aSKai Wang int 563*2de3b87aSKai Wang _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, 564*2de3b87aSKai Wang uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) 565*2de3b87aSKai Wang { 566*2de3b87aSKai Wang int num; 567*2de3b87aSKai Wang 568*2de3b87aSKai Wang assert(llbuf != NULL); 569*2de3b87aSKai Wang assert(in != NULL); 570*2de3b87aSKai Wang assert(in_len > 0); 571*2de3b87aSKai Wang 572*2de3b87aSKai Wang /* Compute the number of locations. */ 573*2de3b87aSKai Wang if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, in, in_len)) < 574*2de3b87aSKai Wang 0) { 575*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); 576*2de3b87aSKai Wang return (DW_DLE_LOC_EXPR_BAD); 577*2de3b87aSKai Wang } 578*2de3b87aSKai Wang 579*2de3b87aSKai Wang llbuf->ld_cents = num; 580*2de3b87aSKai Wang if (num <= 0) 581*2de3b87aSKai Wang return (DW_DLE_NONE); 582*2de3b87aSKai Wang 583*2de3b87aSKai Wang if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) { 584*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 585*2de3b87aSKai Wang return (DW_DLE_MEMORY); 586*2de3b87aSKai Wang } 587*2de3b87aSKai Wang 588*2de3b87aSKai Wang (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, in, in_len); 589*2de3b87aSKai Wang 590*2de3b87aSKai Wang return (DW_DLE_NONE); 591*2de3b87aSKai Wang } 592*2de3b87aSKai Wang 593*2de3b87aSKai Wang int 594*2de3b87aSKai Wang _dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, 595*2de3b87aSKai Wang uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) 596*2de3b87aSKai Wang { 597*2de3b87aSKai Wang Dwarf_Locdesc *llbuf; 598*2de3b87aSKai Wang int ret; 599*2de3b87aSKai Wang 600*2de3b87aSKai Wang if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) { 601*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 602*2de3b87aSKai Wang return (DW_DLE_MEMORY); 603*2de3b87aSKai Wang } 604*2de3b87aSKai Wang llbuf->ld_lopc = 0; 605*2de3b87aSKai Wang llbuf->ld_hipc = ~0ULL; 606*2de3b87aSKai Wang llbuf->ld_s = NULL; 607*2de3b87aSKai Wang 608*2de3b87aSKai Wang ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, 609*2de3b87aSKai Wang error); 610*2de3b87aSKai Wang if (ret != DW_DLE_NONE) { 611*2de3b87aSKai Wang free(llbuf); 612*2de3b87aSKai Wang return (ret); 613*2de3b87aSKai Wang } 614*2de3b87aSKai Wang 615*2de3b87aSKai Wang *ret_llbuf = llbuf; 616*2de3b87aSKai Wang 617*2de3b87aSKai Wang return (ret); 618*2de3b87aSKai Wang } 619*2de3b87aSKai Wang 620*2de3b87aSKai Wang int 621*2de3b87aSKai Wang _dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error) 622*2de3b87aSKai Wang { 623*2de3b87aSKai Wang Dwarf_Debug dbg; 624*2de3b87aSKai Wang Dwarf_CU cu; 625*2de3b87aSKai Wang int ret; 626*2de3b87aSKai Wang 627*2de3b87aSKai Wang assert(at->at_ld == NULL); 628*2de3b87aSKai Wang assert(at->u[1].u8p != NULL); 629*2de3b87aSKai Wang assert(at->u[0].u64 > 0); 630*2de3b87aSKai Wang 631*2de3b87aSKai Wang cu = die->die_cu; 632*2de3b87aSKai Wang assert(cu != NULL); 633*2de3b87aSKai Wang 634*2de3b87aSKai Wang dbg = cu->cu_dbg; 635*2de3b87aSKai Wang assert(dbg != NULL); 636*2de3b87aSKai Wang 637*2de3b87aSKai Wang ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p, 638*2de3b87aSKai Wang at->u[0].u64, cu->cu_pointer_size, error); 639*2de3b87aSKai Wang 640*2de3b87aSKai Wang return (ret); 641*2de3b87aSKai Wang } 642