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
_dwarf_loc_fill_loc(Dwarf_Debug dbg,Dwarf_Locdesc * lbuf,uint8_t pointer_size,uint8_t offset_size,uint8_t version,uint8_t * p,int len)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
_dwarf_loc_expr_add_atom(Dwarf_Debug dbg,uint8_t * out,uint8_t * end,Dwarf_Small atom,Dwarf_Unsigned operand1,Dwarf_Unsigned operand2,int * length,Dwarf_Error * error)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
_dwarf_loc_fill_locdesc(Dwarf_Debug dbg,Dwarf_Locdesc * llbuf,uint8_t * in,uint64_t in_len,uint8_t pointer_size,uint8_t offset_size,uint8_t version,Dwarf_Error * error)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
_dwarf_loc_fill_locexpr(Dwarf_Debug dbg,Dwarf_Locdesc ** ret_llbuf,uint8_t * in,uint64_t in_len,uint8_t pointer_size,uint8_t offset_size,uint8_t version,Dwarf_Error * error)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
_dwarf_loc_add(Dwarf_Die die,Dwarf_Attribute at,Dwarf_Error * error)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