12de3b87aSKai Wang /*- 22de3b87aSKai Wang * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3*cf781b2eSEd Maste * Copyright (c) 2014 Kai Wang 42de3b87aSKai Wang * All rights reserved. 52de3b87aSKai Wang * 62de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without 72de3b87aSKai Wang * modification, are permitted provided that the following conditions 82de3b87aSKai Wang * are met: 92de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright 102de3b87aSKai Wang * notice, this list of conditions and the following disclaimer. 112de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright 122de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the 132de3b87aSKai Wang * documentation and/or other materials provided with the distribution. 142de3b87aSKai Wang * 152de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 162de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 172de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 182de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 192de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 202de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 212de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 222de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 232de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 242de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 252de3b87aSKai Wang * SUCH DAMAGE. 262de3b87aSKai Wang */ 272de3b87aSKai Wang 282de3b87aSKai Wang #include "_libdwarf.h" 292de3b87aSKai Wang 30*cf781b2eSEd Maste ELFTC_VCSID("$Id: libdwarf_loc.c 3070 2014-06-23 03:08:33Z kaiwang27 $"); 312de3b87aSKai Wang 322de3b87aSKai Wang /* 332de3b87aSKai Wang * Given an array of bytes of length 'len' representing a 342de3b87aSKai Wang * DWARF expression, compute the number of operations based 352de3b87aSKai Wang * on there being one byte describing the operation and 362de3b87aSKai Wang * zero or more bytes of operands as defined in the standard 372de3b87aSKai Wang * for each operation type. Also, if lbuf is non-null, store 382de3b87aSKai Wang * the opcode and oprand in it. 392de3b87aSKai Wang */ 402de3b87aSKai Wang static int 412de3b87aSKai Wang _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, 42*cf781b2eSEd Maste uint8_t offset_size, uint8_t version, uint8_t *p, int len) 432de3b87aSKai Wang { 442de3b87aSKai Wang int count; 452de3b87aSKai Wang uint64_t operand1; 462de3b87aSKai Wang uint64_t operand2; 47*cf781b2eSEd Maste uint8_t *ps, *pe, s; 482de3b87aSKai Wang 492de3b87aSKai Wang count = 0; 502de3b87aSKai Wang ps = p; 512de3b87aSKai Wang pe = p + len; 522de3b87aSKai Wang 532de3b87aSKai Wang /* 542de3b87aSKai Wang * Process each byte. If an error occurs, then the 552de3b87aSKai Wang * count will be set to -1. 562de3b87aSKai Wang */ 572de3b87aSKai Wang while (p < pe) { 582de3b87aSKai Wang 592de3b87aSKai Wang operand1 = 0; 602de3b87aSKai Wang operand2 = 0; 612de3b87aSKai Wang 622de3b87aSKai Wang if (lbuf != NULL) { 632de3b87aSKai Wang lbuf->ld_s[count].lr_atom = *p; 642de3b87aSKai Wang lbuf->ld_s[count].lr_offset = p - ps; 652de3b87aSKai Wang } 662de3b87aSKai Wang 672de3b87aSKai Wang switch (*p++) { 682de3b87aSKai Wang /* Operations with no operands. */ 692de3b87aSKai Wang case DW_OP_deref: 702de3b87aSKai Wang case DW_OP_reg0: 712de3b87aSKai Wang case DW_OP_reg1: 722de3b87aSKai Wang case DW_OP_reg2: 732de3b87aSKai Wang case DW_OP_reg3: 742de3b87aSKai Wang case DW_OP_reg4: 752de3b87aSKai Wang case DW_OP_reg5: 762de3b87aSKai Wang case DW_OP_reg6: 772de3b87aSKai Wang case DW_OP_reg7: 782de3b87aSKai Wang case DW_OP_reg8: 792de3b87aSKai Wang case DW_OP_reg9: 802de3b87aSKai Wang case DW_OP_reg10: 812de3b87aSKai Wang case DW_OP_reg11: 822de3b87aSKai Wang case DW_OP_reg12: 832de3b87aSKai Wang case DW_OP_reg13: 842de3b87aSKai Wang case DW_OP_reg14: 852de3b87aSKai Wang case DW_OP_reg15: 862de3b87aSKai Wang case DW_OP_reg16: 872de3b87aSKai Wang case DW_OP_reg17: 882de3b87aSKai Wang case DW_OP_reg18: 892de3b87aSKai Wang case DW_OP_reg19: 902de3b87aSKai Wang case DW_OP_reg20: 912de3b87aSKai Wang case DW_OP_reg21: 922de3b87aSKai Wang case DW_OP_reg22: 932de3b87aSKai Wang case DW_OP_reg23: 942de3b87aSKai Wang case DW_OP_reg24: 952de3b87aSKai Wang case DW_OP_reg25: 962de3b87aSKai Wang case DW_OP_reg26: 972de3b87aSKai Wang case DW_OP_reg27: 982de3b87aSKai Wang case DW_OP_reg28: 992de3b87aSKai Wang case DW_OP_reg29: 1002de3b87aSKai Wang case DW_OP_reg30: 1012de3b87aSKai Wang case DW_OP_reg31: 1022de3b87aSKai Wang 1032de3b87aSKai Wang case DW_OP_lit0: 1042de3b87aSKai Wang case DW_OP_lit1: 1052de3b87aSKai Wang case DW_OP_lit2: 1062de3b87aSKai Wang case DW_OP_lit3: 1072de3b87aSKai Wang case DW_OP_lit4: 1082de3b87aSKai Wang case DW_OP_lit5: 1092de3b87aSKai Wang case DW_OP_lit6: 1102de3b87aSKai Wang case DW_OP_lit7: 1112de3b87aSKai Wang case DW_OP_lit8: 1122de3b87aSKai Wang case DW_OP_lit9: 1132de3b87aSKai Wang case DW_OP_lit10: 1142de3b87aSKai Wang case DW_OP_lit11: 1152de3b87aSKai Wang case DW_OP_lit12: 1162de3b87aSKai Wang case DW_OP_lit13: 1172de3b87aSKai Wang case DW_OP_lit14: 1182de3b87aSKai Wang case DW_OP_lit15: 1192de3b87aSKai Wang case DW_OP_lit16: 1202de3b87aSKai Wang case DW_OP_lit17: 1212de3b87aSKai Wang case DW_OP_lit18: 1222de3b87aSKai Wang case DW_OP_lit19: 1232de3b87aSKai Wang case DW_OP_lit20: 1242de3b87aSKai Wang case DW_OP_lit21: 1252de3b87aSKai Wang case DW_OP_lit22: 1262de3b87aSKai Wang case DW_OP_lit23: 1272de3b87aSKai Wang case DW_OP_lit24: 1282de3b87aSKai Wang case DW_OP_lit25: 1292de3b87aSKai Wang case DW_OP_lit26: 1302de3b87aSKai Wang case DW_OP_lit27: 1312de3b87aSKai Wang case DW_OP_lit28: 1322de3b87aSKai Wang case DW_OP_lit29: 1332de3b87aSKai Wang case DW_OP_lit30: 1342de3b87aSKai Wang case DW_OP_lit31: 1352de3b87aSKai Wang 1362de3b87aSKai Wang case DW_OP_dup: 1372de3b87aSKai Wang case DW_OP_drop: 1382de3b87aSKai Wang 1392de3b87aSKai Wang case DW_OP_over: 1402de3b87aSKai Wang 1412de3b87aSKai Wang case DW_OP_swap: 1422de3b87aSKai Wang case DW_OP_rot: 1432de3b87aSKai Wang case DW_OP_xderef: 1442de3b87aSKai Wang 1452de3b87aSKai Wang case DW_OP_abs: 1462de3b87aSKai Wang case DW_OP_and: 1472de3b87aSKai Wang case DW_OP_div: 1482de3b87aSKai Wang case DW_OP_minus: 1492de3b87aSKai Wang case DW_OP_mod: 1502de3b87aSKai Wang case DW_OP_mul: 1512de3b87aSKai Wang case DW_OP_neg: 1522de3b87aSKai Wang case DW_OP_not: 1532de3b87aSKai Wang case DW_OP_or: 1542de3b87aSKai Wang case DW_OP_plus: 1552de3b87aSKai Wang 1562de3b87aSKai Wang case DW_OP_shl: 1572de3b87aSKai Wang case DW_OP_shr: 1582de3b87aSKai Wang case DW_OP_shra: 1592de3b87aSKai Wang case DW_OP_xor: 1602de3b87aSKai Wang 1612de3b87aSKai Wang case DW_OP_eq: 1622de3b87aSKai Wang case DW_OP_ge: 1632de3b87aSKai Wang case DW_OP_gt: 1642de3b87aSKai Wang case DW_OP_le: 1652de3b87aSKai Wang case DW_OP_lt: 1662de3b87aSKai Wang case DW_OP_ne: 1672de3b87aSKai Wang 1682de3b87aSKai Wang case DW_OP_nop: 169*cf781b2eSEd Maste case DW_OP_push_object_address: 1702de3b87aSKai Wang case DW_OP_form_tls_address: 1712de3b87aSKai Wang case DW_OP_call_frame_cfa: 1722de3b87aSKai Wang case DW_OP_stack_value: 1732de3b87aSKai Wang case DW_OP_GNU_push_tls_address: 174*cf781b2eSEd Maste case DW_OP_GNU_uninit: 1752de3b87aSKai Wang break; 1762de3b87aSKai Wang 1772de3b87aSKai Wang /* Operations with 1-byte operands. */ 1782de3b87aSKai Wang case DW_OP_const1u: 1792de3b87aSKai Wang case DW_OP_pick: 1802de3b87aSKai Wang case DW_OP_deref_size: 1812de3b87aSKai Wang case DW_OP_xderef_size: 1822de3b87aSKai Wang operand1 = *p++; 1832de3b87aSKai Wang break; 1842de3b87aSKai Wang 185*cf781b2eSEd Maste case DW_OP_const1s: 186*cf781b2eSEd Maste operand1 = (int8_t) *p++; 187*cf781b2eSEd Maste break; 188*cf781b2eSEd Maste 1892de3b87aSKai Wang /* Operations with 2-byte operands. */ 1902de3b87aSKai Wang case DW_OP_call2: 1912de3b87aSKai Wang case DW_OP_const2u: 1922de3b87aSKai Wang case DW_OP_bra: 1932de3b87aSKai Wang case DW_OP_skip: 1942de3b87aSKai Wang operand1 = dbg->decode(&p, 2); 1952de3b87aSKai Wang break; 1962de3b87aSKai Wang 197*cf781b2eSEd Maste case DW_OP_const2s: 198*cf781b2eSEd Maste operand1 = (int16_t) dbg->decode(&p, 2); 199*cf781b2eSEd Maste break; 200*cf781b2eSEd Maste 2012de3b87aSKai Wang /* Operations with 4-byte operands. */ 2022de3b87aSKai Wang case DW_OP_call4: 2032de3b87aSKai Wang case DW_OP_const4u: 204*cf781b2eSEd Maste case DW_OP_GNU_parameter_ref: 2052de3b87aSKai Wang operand1 = dbg->decode(&p, 4); 2062de3b87aSKai Wang break; 2072de3b87aSKai Wang 208*cf781b2eSEd Maste case DW_OP_const4s: 209*cf781b2eSEd Maste operand1 = (int32_t) dbg->decode(&p, 4); 210*cf781b2eSEd Maste break; 211*cf781b2eSEd Maste 2122de3b87aSKai Wang /* Operations with 8-byte operands. */ 2132de3b87aSKai Wang case DW_OP_const8u: 2142de3b87aSKai Wang case DW_OP_const8s: 2152de3b87aSKai Wang operand1 = dbg->decode(&p, 8); 2162de3b87aSKai Wang break; 2172de3b87aSKai Wang 2182de3b87aSKai Wang /* Operations with an unsigned LEB128 operand. */ 2192de3b87aSKai Wang case DW_OP_constu: 2202de3b87aSKai Wang case DW_OP_plus_uconst: 2212de3b87aSKai Wang case DW_OP_regx: 2222de3b87aSKai Wang case DW_OP_piece: 223*cf781b2eSEd Maste case DW_OP_GNU_deref_type: 224*cf781b2eSEd Maste case DW_OP_GNU_convert: 225*cf781b2eSEd Maste case DW_OP_GNU_reinterpret: 2262de3b87aSKai Wang operand1 = _dwarf_decode_uleb128(&p); 2272de3b87aSKai Wang break; 2282de3b87aSKai Wang 2292de3b87aSKai Wang /* Operations with a signed LEB128 operand. */ 2302de3b87aSKai Wang case DW_OP_consts: 2312de3b87aSKai Wang case DW_OP_breg0: 2322de3b87aSKai Wang case DW_OP_breg1: 2332de3b87aSKai Wang case DW_OP_breg2: 2342de3b87aSKai Wang case DW_OP_breg3: 2352de3b87aSKai Wang case DW_OP_breg4: 2362de3b87aSKai Wang case DW_OP_breg5: 2372de3b87aSKai Wang case DW_OP_breg6: 2382de3b87aSKai Wang case DW_OP_breg7: 2392de3b87aSKai Wang case DW_OP_breg8: 2402de3b87aSKai Wang case DW_OP_breg9: 2412de3b87aSKai Wang case DW_OP_breg10: 2422de3b87aSKai Wang case DW_OP_breg11: 2432de3b87aSKai Wang case DW_OP_breg12: 2442de3b87aSKai Wang case DW_OP_breg13: 2452de3b87aSKai Wang case DW_OP_breg14: 2462de3b87aSKai Wang case DW_OP_breg15: 2472de3b87aSKai Wang case DW_OP_breg16: 2482de3b87aSKai Wang case DW_OP_breg17: 2492de3b87aSKai Wang case DW_OP_breg18: 2502de3b87aSKai Wang case DW_OP_breg19: 2512de3b87aSKai Wang case DW_OP_breg20: 2522de3b87aSKai Wang case DW_OP_breg21: 2532de3b87aSKai Wang case DW_OP_breg22: 2542de3b87aSKai Wang case DW_OP_breg23: 2552de3b87aSKai Wang case DW_OP_breg24: 2562de3b87aSKai Wang case DW_OP_breg25: 2572de3b87aSKai Wang case DW_OP_breg26: 2582de3b87aSKai Wang case DW_OP_breg27: 2592de3b87aSKai Wang case DW_OP_breg28: 2602de3b87aSKai Wang case DW_OP_breg29: 2612de3b87aSKai Wang case DW_OP_breg30: 2622de3b87aSKai Wang case DW_OP_breg31: 2632de3b87aSKai Wang case DW_OP_fbreg: 2642de3b87aSKai Wang operand1 = _dwarf_decode_sleb128(&p); 2652de3b87aSKai Wang break; 2662de3b87aSKai Wang 2672de3b87aSKai Wang /* 2682de3b87aSKai Wang * Oeration with two unsigned LEB128 operands. 2692de3b87aSKai Wang */ 2702de3b87aSKai Wang case DW_OP_bit_piece: 271*cf781b2eSEd Maste case DW_OP_GNU_regval_type: 2722de3b87aSKai Wang operand1 = _dwarf_decode_uleb128(&p); 2732de3b87aSKai Wang operand2 = _dwarf_decode_uleb128(&p); 2742de3b87aSKai Wang break; 2752de3b87aSKai Wang 2762de3b87aSKai Wang /* 2772de3b87aSKai Wang * Operations with an unsigned LEB128 operand 2782de3b87aSKai Wang * followed by a signed LEB128 operand. 2792de3b87aSKai Wang */ 2802de3b87aSKai Wang case DW_OP_bregx: 2812de3b87aSKai Wang operand1 = _dwarf_decode_uleb128(&p); 2822de3b87aSKai Wang operand2 = _dwarf_decode_sleb128(&p); 2832de3b87aSKai Wang break; 2842de3b87aSKai Wang 2852de3b87aSKai Wang /* 2862de3b87aSKai Wang * Operation with an unsigned LEB128 operand 287*cf781b2eSEd Maste * representing the size of a block, followed 288*cf781b2eSEd Maste * by the block content. 289*cf781b2eSEd Maste * 290*cf781b2eSEd Maste * Store the size of the block in the operand1 291*cf781b2eSEd Maste * and a pointer to the block in the operand2. 2922de3b87aSKai Wang */ 2932de3b87aSKai Wang case DW_OP_implicit_value: 294*cf781b2eSEd Maste case DW_OP_GNU_entry_value: 2952de3b87aSKai Wang operand1 = _dwarf_decode_uleb128(&p); 2962de3b87aSKai Wang operand2 = (Dwarf_Unsigned) (uintptr_t) p; 2972de3b87aSKai Wang p += operand1; 2982de3b87aSKai Wang break; 2992de3b87aSKai Wang 3002de3b87aSKai Wang /* Target address size operand. */ 3012de3b87aSKai Wang case DW_OP_addr: 302*cf781b2eSEd Maste case DW_OP_GNU_addr_index: 303*cf781b2eSEd Maste case DW_OP_GNU_const_index: 3042de3b87aSKai Wang operand1 = dbg->decode(&p, pointer_size); 3052de3b87aSKai Wang break; 3062de3b87aSKai Wang 307*cf781b2eSEd Maste /* Offset size operand. */ 3082de3b87aSKai Wang case DW_OP_call_ref: 309*cf781b2eSEd Maste operand1 = dbg->decode(&p, offset_size); 310*cf781b2eSEd Maste break; 311*cf781b2eSEd Maste 312*cf781b2eSEd Maste /* 313*cf781b2eSEd Maste * The first byte is address byte length, followed by 314*cf781b2eSEd Maste * the address value. If the length is 0, the address 315*cf781b2eSEd Maste * size is the same as target pointer size. 316*cf781b2eSEd Maste */ 317*cf781b2eSEd Maste case DW_OP_GNU_encoded_addr: 318*cf781b2eSEd Maste s = *p++; 319*cf781b2eSEd Maste if (s == 0) 320*cf781b2eSEd Maste s = pointer_size; 321*cf781b2eSEd Maste operand1 = dbg->decode(&p, s); 322*cf781b2eSEd Maste break; 323*cf781b2eSEd Maste 324*cf781b2eSEd Maste /* 325*cf781b2eSEd Maste * Operand1: DIE offset (size depending on DWARF version) 326*cf781b2eSEd Maste * DWARF2: pointer size 327*cf781b2eSEd Maste * DWARF{3,4}: offset size 328*cf781b2eSEd Maste * 329*cf781b2eSEd Maste * Operand2: SLEB128 330*cf781b2eSEd Maste */ 331*cf781b2eSEd Maste case DW_OP_GNU_implicit_pointer: 332*cf781b2eSEd Maste if (version == 2) 333*cf781b2eSEd Maste operand1 = dbg->decode(&p, pointer_size); 334*cf781b2eSEd Maste else 335*cf781b2eSEd Maste operand1 = dbg->decode(&p, offset_size); 336*cf781b2eSEd Maste operand2 = _dwarf_decode_sleb128(&p); 337*cf781b2eSEd Maste break; 338*cf781b2eSEd Maste 339*cf781b2eSEd Maste /* 340*cf781b2eSEd Maste * Operand1: DIE offset (ULEB128) 341*cf781b2eSEd Maste * Operand2: pointer to a block. The block's first byte 342*cf781b2eSEd Maste * is its size. 343*cf781b2eSEd Maste */ 344*cf781b2eSEd Maste case DW_OP_GNU_const_type: 345*cf781b2eSEd Maste operand1 = _dwarf_decode_uleb128(&p); 346*cf781b2eSEd Maste operand2 = (Dwarf_Unsigned) (uintptr_t) p; 347*cf781b2eSEd Maste s = *p++; 348*cf781b2eSEd Maste p += s; 3492de3b87aSKai Wang break; 3502de3b87aSKai Wang 3512de3b87aSKai Wang /* All other operations cause an error. */ 3522de3b87aSKai Wang default: 3532de3b87aSKai Wang count = -1; 354*cf781b2eSEd Maste goto done; 3552de3b87aSKai Wang } 3562de3b87aSKai Wang 3572de3b87aSKai Wang if (lbuf != NULL) { 3582de3b87aSKai Wang lbuf->ld_s[count].lr_number = operand1; 3592de3b87aSKai Wang lbuf->ld_s[count].lr_number2 = operand2; 3602de3b87aSKai Wang } 3612de3b87aSKai Wang 3622de3b87aSKai Wang count++; 3632de3b87aSKai Wang } 3642de3b87aSKai Wang 365*cf781b2eSEd Maste done: 3662de3b87aSKai Wang return (count); 3672de3b87aSKai Wang } 3682de3b87aSKai Wang 3692de3b87aSKai Wang int 3702de3b87aSKai Wang _dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end, 3712de3b87aSKai Wang Dwarf_Small atom, Dwarf_Unsigned operand1, Dwarf_Unsigned operand2, 3722de3b87aSKai Wang int *length, Dwarf_Error *error) 3732de3b87aSKai Wang { 3742de3b87aSKai Wang uint8_t buf[64]; 3752de3b87aSKai Wang uint8_t *p, *pe; 3762de3b87aSKai Wang uint64_t offset; 3772de3b87aSKai Wang int len; 3782de3b87aSKai Wang 3792de3b87aSKai Wang if (out != NULL && end != NULL) { 3802de3b87aSKai Wang p = out; 3812de3b87aSKai Wang pe = end; 3822de3b87aSKai Wang } else { 3832de3b87aSKai Wang p = out = buf; 3842de3b87aSKai Wang pe = &buf[sizeof(buf)]; 3852de3b87aSKai Wang } 3862de3b87aSKai Wang 3872de3b87aSKai Wang switch (atom) { 3882de3b87aSKai Wang /* Operations with no operands. */ 3892de3b87aSKai Wang case DW_OP_deref: 3902de3b87aSKai Wang case DW_OP_reg0: 3912de3b87aSKai Wang case DW_OP_reg1: 3922de3b87aSKai Wang case DW_OP_reg2: 3932de3b87aSKai Wang case DW_OP_reg3: 3942de3b87aSKai Wang case DW_OP_reg4: 3952de3b87aSKai Wang case DW_OP_reg5: 3962de3b87aSKai Wang case DW_OP_reg6: 3972de3b87aSKai Wang case DW_OP_reg7: 3982de3b87aSKai Wang case DW_OP_reg8: 3992de3b87aSKai Wang case DW_OP_reg9: 4002de3b87aSKai Wang case DW_OP_reg10: 4012de3b87aSKai Wang case DW_OP_reg11: 4022de3b87aSKai Wang case DW_OP_reg12: 4032de3b87aSKai Wang case DW_OP_reg13: 4042de3b87aSKai Wang case DW_OP_reg14: 4052de3b87aSKai Wang case DW_OP_reg15: 4062de3b87aSKai Wang case DW_OP_reg16: 4072de3b87aSKai Wang case DW_OP_reg17: 4082de3b87aSKai Wang case DW_OP_reg18: 4092de3b87aSKai Wang case DW_OP_reg19: 4102de3b87aSKai Wang case DW_OP_reg20: 4112de3b87aSKai Wang case DW_OP_reg21: 4122de3b87aSKai Wang case DW_OP_reg22: 4132de3b87aSKai Wang case DW_OP_reg23: 4142de3b87aSKai Wang case DW_OP_reg24: 4152de3b87aSKai Wang case DW_OP_reg25: 4162de3b87aSKai Wang case DW_OP_reg26: 4172de3b87aSKai Wang case DW_OP_reg27: 4182de3b87aSKai Wang case DW_OP_reg28: 4192de3b87aSKai Wang case DW_OP_reg29: 4202de3b87aSKai Wang case DW_OP_reg30: 4212de3b87aSKai Wang case DW_OP_reg31: 4222de3b87aSKai Wang 4232de3b87aSKai Wang case DW_OP_lit0: 4242de3b87aSKai Wang case DW_OP_lit1: 4252de3b87aSKai Wang case DW_OP_lit2: 4262de3b87aSKai Wang case DW_OP_lit3: 4272de3b87aSKai Wang case DW_OP_lit4: 4282de3b87aSKai Wang case DW_OP_lit5: 4292de3b87aSKai Wang case DW_OP_lit6: 4302de3b87aSKai Wang case DW_OP_lit7: 4312de3b87aSKai Wang case DW_OP_lit8: 4322de3b87aSKai Wang case DW_OP_lit9: 4332de3b87aSKai Wang case DW_OP_lit10: 4342de3b87aSKai Wang case DW_OP_lit11: 4352de3b87aSKai Wang case DW_OP_lit12: 4362de3b87aSKai Wang case DW_OP_lit13: 4372de3b87aSKai Wang case DW_OP_lit14: 4382de3b87aSKai Wang case DW_OP_lit15: 4392de3b87aSKai Wang case DW_OP_lit16: 4402de3b87aSKai Wang case DW_OP_lit17: 4412de3b87aSKai Wang case DW_OP_lit18: 4422de3b87aSKai Wang case DW_OP_lit19: 4432de3b87aSKai Wang case DW_OP_lit20: 4442de3b87aSKai Wang case DW_OP_lit21: 4452de3b87aSKai Wang case DW_OP_lit22: 4462de3b87aSKai Wang case DW_OP_lit23: 4472de3b87aSKai Wang case DW_OP_lit24: 4482de3b87aSKai Wang case DW_OP_lit25: 4492de3b87aSKai Wang case DW_OP_lit26: 4502de3b87aSKai Wang case DW_OP_lit27: 4512de3b87aSKai Wang case DW_OP_lit28: 4522de3b87aSKai Wang case DW_OP_lit29: 4532de3b87aSKai Wang case DW_OP_lit30: 4542de3b87aSKai Wang case DW_OP_lit31: 4552de3b87aSKai Wang 4562de3b87aSKai Wang case DW_OP_dup: 4572de3b87aSKai Wang case DW_OP_drop: 4582de3b87aSKai Wang 4592de3b87aSKai Wang case DW_OP_over: 4602de3b87aSKai Wang 4612de3b87aSKai Wang case DW_OP_swap: 4622de3b87aSKai Wang case DW_OP_rot: 4632de3b87aSKai Wang case DW_OP_xderef: 4642de3b87aSKai Wang 4652de3b87aSKai Wang case DW_OP_abs: 4662de3b87aSKai Wang case DW_OP_and: 4672de3b87aSKai Wang case DW_OP_div: 4682de3b87aSKai Wang case DW_OP_minus: 4692de3b87aSKai Wang case DW_OP_mod: 4702de3b87aSKai Wang case DW_OP_mul: 4712de3b87aSKai Wang case DW_OP_neg: 4722de3b87aSKai Wang case DW_OP_not: 4732de3b87aSKai Wang case DW_OP_or: 4742de3b87aSKai Wang case DW_OP_plus: 4752de3b87aSKai Wang 4762de3b87aSKai Wang case DW_OP_shl: 4772de3b87aSKai Wang case DW_OP_shr: 4782de3b87aSKai Wang case DW_OP_shra: 4792de3b87aSKai Wang case DW_OP_xor: 4802de3b87aSKai Wang 4812de3b87aSKai Wang case DW_OP_eq: 4822de3b87aSKai Wang case DW_OP_ge: 4832de3b87aSKai Wang case DW_OP_gt: 4842de3b87aSKai Wang case DW_OP_le: 4852de3b87aSKai Wang case DW_OP_lt: 4862de3b87aSKai Wang case DW_OP_ne: 4872de3b87aSKai Wang 4882de3b87aSKai Wang case DW_OP_nop: 4892de3b87aSKai Wang case DW_OP_GNU_push_tls_address: 4902de3b87aSKai Wang *p++ = atom; 4912de3b87aSKai Wang break; 4922de3b87aSKai Wang 4932de3b87aSKai Wang /* Operations with 1-byte operands. */ 4942de3b87aSKai Wang case DW_OP_const1u: 4952de3b87aSKai Wang case DW_OP_const1s: 4962de3b87aSKai Wang case DW_OP_pick: 4972de3b87aSKai Wang case DW_OP_deref_size: 4982de3b87aSKai Wang case DW_OP_xderef_size: 4992de3b87aSKai Wang *p++ = atom; 5002de3b87aSKai Wang *p++ = (uint8_t) operand1; 5012de3b87aSKai Wang break; 5022de3b87aSKai Wang 5032de3b87aSKai Wang /* Operations with 2-byte operands. */ 5042de3b87aSKai Wang case DW_OP_const2u: 5052de3b87aSKai Wang case DW_OP_const2s: 5062de3b87aSKai Wang case DW_OP_bra: 5072de3b87aSKai Wang case DW_OP_skip: 5082de3b87aSKai Wang *p++ = atom; 5092de3b87aSKai Wang offset = 0; 5102de3b87aSKai Wang dbg->write(p, &offset, operand1, 2); 5112de3b87aSKai Wang p += 2; 5122de3b87aSKai Wang break; 5132de3b87aSKai Wang 5142de3b87aSKai Wang /* Operations with 4-byte operands. */ 5152de3b87aSKai Wang case DW_OP_const4u: 5162de3b87aSKai Wang case DW_OP_const4s: 5172de3b87aSKai Wang *p++ = atom; 5182de3b87aSKai Wang offset = 0; 5192de3b87aSKai Wang dbg->write(p, &offset, operand1, 4); 5202de3b87aSKai Wang p += 4; 5212de3b87aSKai Wang break; 5222de3b87aSKai Wang 5232de3b87aSKai Wang /* Operations with 8-byte operands. */ 5242de3b87aSKai Wang case DW_OP_const8u: 5252de3b87aSKai Wang case DW_OP_const8s: 5262de3b87aSKai Wang *p++ = atom; 5272de3b87aSKai Wang offset = 0; 5282de3b87aSKai Wang dbg->write(p, &offset, operand1, 8); 5292de3b87aSKai Wang p += 8; 5302de3b87aSKai Wang break; 5312de3b87aSKai Wang 5322de3b87aSKai Wang /* Operations with an unsigned LEB128 operand. */ 5332de3b87aSKai Wang case DW_OP_constu: 5342de3b87aSKai Wang case DW_OP_plus_uconst: 5352de3b87aSKai Wang case DW_OP_regx: 5362de3b87aSKai Wang case DW_OP_piece: 5372de3b87aSKai Wang *p++ = atom; 5382de3b87aSKai Wang len = _dwarf_write_uleb128(p, pe, operand1); 5392de3b87aSKai Wang assert(len > 0); 5402de3b87aSKai Wang p += len; 5412de3b87aSKai Wang break; 5422de3b87aSKai Wang 5432de3b87aSKai Wang /* Operations with a signed LEB128 operand. */ 5442de3b87aSKai Wang case DW_OP_consts: 5452de3b87aSKai Wang case DW_OP_breg0: 5462de3b87aSKai Wang case DW_OP_breg1: 5472de3b87aSKai Wang case DW_OP_breg2: 5482de3b87aSKai Wang case DW_OP_breg3: 5492de3b87aSKai Wang case DW_OP_breg4: 5502de3b87aSKai Wang case DW_OP_breg5: 5512de3b87aSKai Wang case DW_OP_breg6: 5522de3b87aSKai Wang case DW_OP_breg7: 5532de3b87aSKai Wang case DW_OP_breg8: 5542de3b87aSKai Wang case DW_OP_breg9: 5552de3b87aSKai Wang case DW_OP_breg10: 5562de3b87aSKai Wang case DW_OP_breg11: 5572de3b87aSKai Wang case DW_OP_breg12: 5582de3b87aSKai Wang case DW_OP_breg13: 5592de3b87aSKai Wang case DW_OP_breg14: 5602de3b87aSKai Wang case DW_OP_breg15: 5612de3b87aSKai Wang case DW_OP_breg16: 5622de3b87aSKai Wang case DW_OP_breg17: 5632de3b87aSKai Wang case DW_OP_breg18: 5642de3b87aSKai Wang case DW_OP_breg19: 5652de3b87aSKai Wang case DW_OP_breg20: 5662de3b87aSKai Wang case DW_OP_breg21: 5672de3b87aSKai Wang case DW_OP_breg22: 5682de3b87aSKai Wang case DW_OP_breg23: 5692de3b87aSKai Wang case DW_OP_breg24: 5702de3b87aSKai Wang case DW_OP_breg25: 5712de3b87aSKai Wang case DW_OP_breg26: 5722de3b87aSKai Wang case DW_OP_breg27: 5732de3b87aSKai Wang case DW_OP_breg28: 5742de3b87aSKai Wang case DW_OP_breg29: 5752de3b87aSKai Wang case DW_OP_breg30: 5762de3b87aSKai Wang case DW_OP_breg31: 5772de3b87aSKai Wang case DW_OP_fbreg: 5782de3b87aSKai Wang *p++ = atom; 5792de3b87aSKai Wang len = _dwarf_write_sleb128(p, pe, operand1); 5802de3b87aSKai Wang assert(len > 0); 5812de3b87aSKai Wang p += len; 5822de3b87aSKai Wang break; 5832de3b87aSKai Wang 5842de3b87aSKai Wang /* 5852de3b87aSKai Wang * Operations with an unsigned LEB128 operand 5862de3b87aSKai Wang * followed by a signed LEB128 operand. 5872de3b87aSKai Wang */ 5882de3b87aSKai Wang case DW_OP_bregx: 5892de3b87aSKai Wang *p++ = atom; 5902de3b87aSKai Wang len = _dwarf_write_uleb128(p, pe, operand1); 5912de3b87aSKai Wang assert(len > 0); 5922de3b87aSKai Wang p += len; 5932de3b87aSKai Wang len = _dwarf_write_sleb128(p, pe, operand2); 5942de3b87aSKai Wang assert(len > 0); 5952de3b87aSKai Wang p += len; 5962de3b87aSKai Wang break; 5972de3b87aSKai Wang 5982de3b87aSKai Wang /* Target address size operand. */ 5992de3b87aSKai Wang case DW_OP_addr: 6002de3b87aSKai Wang *p++ = atom; 6012de3b87aSKai Wang offset = 0; 6022de3b87aSKai Wang dbg->write(p, &offset, operand1, dbg->dbg_pointer_size); 6032de3b87aSKai Wang p += dbg->dbg_pointer_size; 6042de3b87aSKai Wang break; 6052de3b87aSKai Wang 6062de3b87aSKai Wang /* All other operations cause an error. */ 6072de3b87aSKai Wang default: 6082de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); 6092de3b87aSKai Wang return (DW_DLE_LOC_EXPR_BAD); 6102de3b87aSKai Wang } 6112de3b87aSKai Wang 6122de3b87aSKai Wang if (length) 6132de3b87aSKai Wang *length = p - out; 6142de3b87aSKai Wang 6152de3b87aSKai Wang return (DW_DLE_NONE); 6162de3b87aSKai Wang } 6172de3b87aSKai Wang 6182de3b87aSKai Wang int 6192de3b87aSKai Wang _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, 620*cf781b2eSEd Maste uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, 621*cf781b2eSEd Maste uint8_t version, Dwarf_Error *error) 6222de3b87aSKai Wang { 6232de3b87aSKai Wang int num; 6242de3b87aSKai Wang 6252de3b87aSKai Wang assert(llbuf != NULL); 6262de3b87aSKai Wang assert(in != NULL); 6272de3b87aSKai Wang assert(in_len > 0); 6282de3b87aSKai Wang 6292de3b87aSKai Wang /* Compute the number of locations. */ 630*cf781b2eSEd Maste if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, offset_size, 631*cf781b2eSEd Maste version, in, in_len)) < 0) { 6322de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); 6332de3b87aSKai Wang return (DW_DLE_LOC_EXPR_BAD); 6342de3b87aSKai Wang } 6352de3b87aSKai Wang 6362de3b87aSKai Wang llbuf->ld_cents = num; 6372de3b87aSKai Wang if (num <= 0) 6382de3b87aSKai Wang return (DW_DLE_NONE); 6392de3b87aSKai Wang 6402de3b87aSKai Wang if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) { 6412de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 6422de3b87aSKai Wang return (DW_DLE_MEMORY); 6432de3b87aSKai Wang } 6442de3b87aSKai Wang 645*cf781b2eSEd Maste (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, offset_size, 646*cf781b2eSEd Maste version, in, in_len); 6472de3b87aSKai Wang 6482de3b87aSKai Wang return (DW_DLE_NONE); 6492de3b87aSKai Wang } 6502de3b87aSKai Wang 6512de3b87aSKai Wang int 6522de3b87aSKai Wang _dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, 653*cf781b2eSEd Maste uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, 654*cf781b2eSEd Maste uint8_t version, Dwarf_Error *error) 6552de3b87aSKai Wang { 6562de3b87aSKai Wang Dwarf_Locdesc *llbuf; 6572de3b87aSKai Wang int ret; 6582de3b87aSKai Wang 6592de3b87aSKai Wang if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) { 6602de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 6612de3b87aSKai Wang return (DW_DLE_MEMORY); 6622de3b87aSKai Wang } 6632de3b87aSKai Wang llbuf->ld_lopc = 0; 6642de3b87aSKai Wang llbuf->ld_hipc = ~0ULL; 6652de3b87aSKai Wang llbuf->ld_s = NULL; 6662de3b87aSKai Wang 6672de3b87aSKai Wang ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, 668*cf781b2eSEd Maste offset_size, version, error); 6692de3b87aSKai Wang if (ret != DW_DLE_NONE) { 6702de3b87aSKai Wang free(llbuf); 6712de3b87aSKai Wang return (ret); 6722de3b87aSKai Wang } 6732de3b87aSKai Wang 6742de3b87aSKai Wang *ret_llbuf = llbuf; 6752de3b87aSKai Wang 6762de3b87aSKai Wang return (ret); 6772de3b87aSKai Wang } 6782de3b87aSKai Wang 6792de3b87aSKai Wang int 6802de3b87aSKai Wang _dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error) 6812de3b87aSKai Wang { 6822de3b87aSKai Wang Dwarf_Debug dbg; 6832de3b87aSKai Wang Dwarf_CU cu; 6842de3b87aSKai Wang int ret; 6852de3b87aSKai Wang 6862de3b87aSKai Wang assert(at->at_ld == NULL); 6872de3b87aSKai Wang assert(at->u[1].u8p != NULL); 6882de3b87aSKai Wang assert(at->u[0].u64 > 0); 6892de3b87aSKai Wang 6902de3b87aSKai Wang cu = die->die_cu; 6912de3b87aSKai Wang assert(cu != NULL); 6922de3b87aSKai Wang 6932de3b87aSKai Wang dbg = cu->cu_dbg; 6942de3b87aSKai Wang assert(dbg != NULL); 6952de3b87aSKai Wang 6962de3b87aSKai Wang ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p, 697*cf781b2eSEd Maste at->u[0].u64, cu->cu_pointer_size, cu->cu_length_size == 4 ? 4 : 8, 698*cf781b2eSEd Maste cu->cu_version, error); 6992de3b87aSKai Wang 7002de3b87aSKai Wang return (ret); 7012de3b87aSKai Wang } 702