libdwarf_loc.c revision 260684
1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3260684Skaiw * All rights reserved. 4260684Skaiw * 5260684Skaiw * Redistribution and use in source and binary forms, with or without 6260684Skaiw * modification, are permitted provided that the following conditions 7260684Skaiw * are met: 8260684Skaiw * 1. Redistributions of source code must retain the above copyright 9260684Skaiw * notice, this list of conditions and the following disclaimer. 10260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 11260684Skaiw * notice, this list of conditions and the following disclaimer in the 12260684Skaiw * documentation and/or other materials provided with the distribution. 13260684Skaiw * 14260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17260684Skaiw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24260684Skaiw * SUCH DAMAGE. 25260684Skaiw */ 26260684Skaiw 27260684Skaiw#include "_libdwarf.h" 28260684Skaiw 29260684SkaiwELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $"); 30260684Skaiw 31260684Skaiw/* 32260684Skaiw * Given an array of bytes of length 'len' representing a 33260684Skaiw * DWARF expression, compute the number of operations based 34260684Skaiw * on there being one byte describing the operation and 35260684Skaiw * zero or more bytes of operands as defined in the standard 36260684Skaiw * for each operation type. Also, if lbuf is non-null, store 37260684Skaiw * the opcode and oprand in it. 38260684Skaiw */ 39260684Skaiwstatic int 40260684Skaiw_dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, 41260684Skaiw uint8_t *p, int len) 42260684Skaiw{ 43260684Skaiw int count; 44260684Skaiw uint64_t operand1; 45260684Skaiw uint64_t operand2; 46260684Skaiw uint8_t *ps, *pe; 47260684Skaiw 48260684Skaiw count = 0; 49260684Skaiw ps = p; 50260684Skaiw pe = p + len; 51260684Skaiw 52260684Skaiw /* 53260684Skaiw * Process each byte. If an error occurs, then the 54260684Skaiw * count will be set to -1. 55260684Skaiw */ 56260684Skaiw while (p < pe) { 57260684Skaiw 58260684Skaiw operand1 = 0; 59260684Skaiw operand2 = 0; 60260684Skaiw 61260684Skaiw if (lbuf != NULL) { 62260684Skaiw lbuf->ld_s[count].lr_atom = *p; 63260684Skaiw lbuf->ld_s[count].lr_offset = p - ps; 64260684Skaiw } 65260684Skaiw 66260684Skaiw switch (*p++) { 67260684Skaiw /* Operations with no operands. */ 68260684Skaiw case DW_OP_deref: 69260684Skaiw case DW_OP_reg0: 70260684Skaiw case DW_OP_reg1: 71260684Skaiw case DW_OP_reg2: 72260684Skaiw case DW_OP_reg3: 73260684Skaiw case DW_OP_reg4: 74260684Skaiw case DW_OP_reg5: 75260684Skaiw case DW_OP_reg6: 76260684Skaiw case DW_OP_reg7: 77260684Skaiw case DW_OP_reg8: 78260684Skaiw case DW_OP_reg9: 79260684Skaiw case DW_OP_reg10: 80260684Skaiw case DW_OP_reg11: 81260684Skaiw case DW_OP_reg12: 82260684Skaiw case DW_OP_reg13: 83260684Skaiw case DW_OP_reg14: 84260684Skaiw case DW_OP_reg15: 85260684Skaiw case DW_OP_reg16: 86260684Skaiw case DW_OP_reg17: 87260684Skaiw case DW_OP_reg18: 88260684Skaiw case DW_OP_reg19: 89260684Skaiw case DW_OP_reg20: 90260684Skaiw case DW_OP_reg21: 91260684Skaiw case DW_OP_reg22: 92260684Skaiw case DW_OP_reg23: 93260684Skaiw case DW_OP_reg24: 94260684Skaiw case DW_OP_reg25: 95260684Skaiw case DW_OP_reg26: 96260684Skaiw case DW_OP_reg27: 97260684Skaiw case DW_OP_reg28: 98260684Skaiw case DW_OP_reg29: 99260684Skaiw case DW_OP_reg30: 100260684Skaiw case DW_OP_reg31: 101260684Skaiw 102260684Skaiw case DW_OP_lit0: 103260684Skaiw case DW_OP_lit1: 104260684Skaiw case DW_OP_lit2: 105260684Skaiw case DW_OP_lit3: 106260684Skaiw case DW_OP_lit4: 107260684Skaiw case DW_OP_lit5: 108260684Skaiw case DW_OP_lit6: 109260684Skaiw case DW_OP_lit7: 110260684Skaiw case DW_OP_lit8: 111260684Skaiw case DW_OP_lit9: 112260684Skaiw case DW_OP_lit10: 113260684Skaiw case DW_OP_lit11: 114260684Skaiw case DW_OP_lit12: 115260684Skaiw case DW_OP_lit13: 116260684Skaiw case DW_OP_lit14: 117260684Skaiw case DW_OP_lit15: 118260684Skaiw case DW_OP_lit16: 119260684Skaiw case DW_OP_lit17: 120260684Skaiw case DW_OP_lit18: 121260684Skaiw case DW_OP_lit19: 122260684Skaiw case DW_OP_lit20: 123260684Skaiw case DW_OP_lit21: 124260684Skaiw case DW_OP_lit22: 125260684Skaiw case DW_OP_lit23: 126260684Skaiw case DW_OP_lit24: 127260684Skaiw case DW_OP_lit25: 128260684Skaiw case DW_OP_lit26: 129260684Skaiw case DW_OP_lit27: 130260684Skaiw case DW_OP_lit28: 131260684Skaiw case DW_OP_lit29: 132260684Skaiw case DW_OP_lit30: 133260684Skaiw case DW_OP_lit31: 134260684Skaiw 135260684Skaiw case DW_OP_dup: 136260684Skaiw case DW_OP_drop: 137260684Skaiw 138260684Skaiw case DW_OP_over: 139260684Skaiw 140260684Skaiw case DW_OP_swap: 141260684Skaiw case DW_OP_rot: 142260684Skaiw case DW_OP_xderef: 143260684Skaiw 144260684Skaiw case DW_OP_abs: 145260684Skaiw case DW_OP_and: 146260684Skaiw case DW_OP_div: 147260684Skaiw case DW_OP_minus: 148260684Skaiw case DW_OP_mod: 149260684Skaiw case DW_OP_mul: 150260684Skaiw case DW_OP_neg: 151260684Skaiw case DW_OP_not: 152260684Skaiw case DW_OP_or: 153260684Skaiw case DW_OP_plus: 154260684Skaiw 155260684Skaiw case DW_OP_shl: 156260684Skaiw case DW_OP_shr: 157260684Skaiw case DW_OP_shra: 158260684Skaiw case DW_OP_xor: 159260684Skaiw 160260684Skaiw case DW_OP_eq: 161260684Skaiw case DW_OP_ge: 162260684Skaiw case DW_OP_gt: 163260684Skaiw case DW_OP_le: 164260684Skaiw case DW_OP_lt: 165260684Skaiw case DW_OP_ne: 166260684Skaiw 167260684Skaiw case DW_OP_nop: 168260684Skaiw case DW_OP_form_tls_address: 169260684Skaiw case DW_OP_call_frame_cfa: 170260684Skaiw case DW_OP_stack_value: 171260684Skaiw case DW_OP_GNU_push_tls_address: 172260684Skaiw break; 173260684Skaiw 174260684Skaiw /* Operations with 1-byte operands. */ 175260684Skaiw case DW_OP_const1u: 176260684Skaiw case DW_OP_const1s: 177260684Skaiw case DW_OP_pick: 178260684Skaiw case DW_OP_deref_size: 179260684Skaiw case DW_OP_xderef_size: 180260684Skaiw operand1 = *p++; 181260684Skaiw break; 182260684Skaiw 183260684Skaiw /* Operations with 2-byte operands. */ 184260684Skaiw case DW_OP_call2: 185260684Skaiw case DW_OP_const2u: 186260684Skaiw case DW_OP_const2s: 187260684Skaiw case DW_OP_bra: 188260684Skaiw case DW_OP_skip: 189260684Skaiw operand1 = dbg->decode(&p, 2); 190260684Skaiw break; 191260684Skaiw 192260684Skaiw /* Operations with 4-byte operands. */ 193260684Skaiw case DW_OP_call4: 194260684Skaiw case DW_OP_const4u: 195260684Skaiw case DW_OP_const4s: 196260684Skaiw operand1 = dbg->decode(&p, 4); 197260684Skaiw break; 198260684Skaiw 199260684Skaiw /* Operations with 8-byte operands. */ 200260684Skaiw case DW_OP_const8u: 201260684Skaiw case DW_OP_const8s: 202260684Skaiw operand1 = dbg->decode(&p, 8); 203260684Skaiw break; 204260684Skaiw 205260684Skaiw /* Operations with an unsigned LEB128 operand. */ 206260684Skaiw case DW_OP_constu: 207260684Skaiw case DW_OP_plus_uconst: 208260684Skaiw case DW_OP_regx: 209260684Skaiw case DW_OP_piece: 210260684Skaiw operand1 = _dwarf_decode_uleb128(&p); 211260684Skaiw break; 212260684Skaiw 213260684Skaiw /* Operations with a signed LEB128 operand. */ 214260684Skaiw case DW_OP_consts: 215260684Skaiw case DW_OP_breg0: 216260684Skaiw case DW_OP_breg1: 217260684Skaiw case DW_OP_breg2: 218260684Skaiw case DW_OP_breg3: 219260684Skaiw case DW_OP_breg4: 220260684Skaiw case DW_OP_breg5: 221260684Skaiw case DW_OP_breg6: 222260684Skaiw case DW_OP_breg7: 223260684Skaiw case DW_OP_breg8: 224260684Skaiw case DW_OP_breg9: 225260684Skaiw case DW_OP_breg10: 226260684Skaiw case DW_OP_breg11: 227260684Skaiw case DW_OP_breg12: 228260684Skaiw case DW_OP_breg13: 229260684Skaiw case DW_OP_breg14: 230260684Skaiw case DW_OP_breg15: 231260684Skaiw case DW_OP_breg16: 232260684Skaiw case DW_OP_breg17: 233260684Skaiw case DW_OP_breg18: 234260684Skaiw case DW_OP_breg19: 235260684Skaiw case DW_OP_breg20: 236260684Skaiw case DW_OP_breg21: 237260684Skaiw case DW_OP_breg22: 238260684Skaiw case DW_OP_breg23: 239260684Skaiw case DW_OP_breg24: 240260684Skaiw case DW_OP_breg25: 241260684Skaiw case DW_OP_breg26: 242260684Skaiw case DW_OP_breg27: 243260684Skaiw case DW_OP_breg28: 244260684Skaiw case DW_OP_breg29: 245260684Skaiw case DW_OP_breg30: 246260684Skaiw case DW_OP_breg31: 247260684Skaiw case DW_OP_fbreg: 248260684Skaiw operand1 = _dwarf_decode_sleb128(&p); 249260684Skaiw break; 250260684Skaiw 251260684Skaiw /* 252260684Skaiw * Oeration with two unsigned LEB128 operands. 253260684Skaiw */ 254260684Skaiw case DW_OP_bit_piece: 255260684Skaiw operand1 = _dwarf_decode_uleb128(&p); 256260684Skaiw operand2 = _dwarf_decode_uleb128(&p); 257260684Skaiw break; 258260684Skaiw 259260684Skaiw /* 260260684Skaiw * Operations with an unsigned LEB128 operand 261260684Skaiw * followed by a signed LEB128 operand. 262260684Skaiw */ 263260684Skaiw case DW_OP_bregx: 264260684Skaiw operand1 = _dwarf_decode_uleb128(&p); 265260684Skaiw operand2 = _dwarf_decode_sleb128(&p); 266260684Skaiw break; 267260684Skaiw 268260684Skaiw /* 269260684Skaiw * Operation with an unsigned LEB128 operand 270260684Skaiw * followed by a block. Store a pointer to the 271260684Skaiw * block in the operand2. 272260684Skaiw */ 273260684Skaiw case DW_OP_implicit_value: 274260684Skaiw operand1 = _dwarf_decode_uleb128(&p); 275260684Skaiw operand2 = (Dwarf_Unsigned) (uintptr_t) p; 276260684Skaiw p += operand1; 277260684Skaiw break; 278260684Skaiw 279260684Skaiw /* Target address size operand. */ 280260684Skaiw case DW_OP_addr: 281260684Skaiw operand1 = dbg->decode(&p, pointer_size); 282260684Skaiw break; 283260684Skaiw 284260684Skaiw /* 285260684Skaiw * XXX Opcode DW_OP_call_ref has an operand with size 286260684Skaiw * "dwarf_size". Here we use dbg->dbg_offset_size 287260684Skaiw * as "dwarf_size" to be compatible with SGI libdwarf. 288260684Skaiw * However note that dbg->dbg_offset_size is just 289260684Skaiw * a "guess" value so the parsing result of 290260684Skaiw * DW_OP_call_ref might not be correct at all. XXX 291260684Skaiw */ 292260684Skaiw case DW_OP_call_ref: 293260684Skaiw operand1 = dbg->decode(&p, dbg->dbg_offset_size); 294260684Skaiw break; 295260684Skaiw 296260684Skaiw /* All other operations cause an error. */ 297260684Skaiw default: 298260684Skaiw count = -1; 299260684Skaiw break; 300260684Skaiw } 301260684Skaiw 302260684Skaiw if (lbuf != NULL) { 303260684Skaiw lbuf->ld_s[count].lr_number = operand1; 304260684Skaiw lbuf->ld_s[count].lr_number2 = operand2; 305260684Skaiw } 306260684Skaiw 307260684Skaiw count++; 308260684Skaiw } 309260684Skaiw 310260684Skaiw return (count); 311260684Skaiw} 312260684Skaiw 313260684Skaiwint 314260684Skaiw_dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end, 315260684Skaiw Dwarf_Small atom, Dwarf_Unsigned operand1, Dwarf_Unsigned operand2, 316260684Skaiw int *length, Dwarf_Error *error) 317260684Skaiw{ 318260684Skaiw uint8_t buf[64]; 319260684Skaiw uint8_t *p, *pe; 320260684Skaiw uint64_t offset; 321260684Skaiw int len; 322260684Skaiw 323260684Skaiw if (out != NULL && end != NULL) { 324260684Skaiw p = out; 325260684Skaiw pe = end; 326260684Skaiw } else { 327260684Skaiw p = out = buf; 328260684Skaiw pe = &buf[sizeof(buf)]; 329260684Skaiw } 330260684Skaiw 331260684Skaiw switch (atom) { 332260684Skaiw /* Operations with no operands. */ 333260684Skaiw case DW_OP_deref: 334260684Skaiw case DW_OP_reg0: 335260684Skaiw case DW_OP_reg1: 336260684Skaiw case DW_OP_reg2: 337260684Skaiw case DW_OP_reg3: 338260684Skaiw case DW_OP_reg4: 339260684Skaiw case DW_OP_reg5: 340260684Skaiw case DW_OP_reg6: 341260684Skaiw case DW_OP_reg7: 342260684Skaiw case DW_OP_reg8: 343260684Skaiw case DW_OP_reg9: 344260684Skaiw case DW_OP_reg10: 345260684Skaiw case DW_OP_reg11: 346260684Skaiw case DW_OP_reg12: 347260684Skaiw case DW_OP_reg13: 348260684Skaiw case DW_OP_reg14: 349260684Skaiw case DW_OP_reg15: 350260684Skaiw case DW_OP_reg16: 351260684Skaiw case DW_OP_reg17: 352260684Skaiw case DW_OP_reg18: 353260684Skaiw case DW_OP_reg19: 354260684Skaiw case DW_OP_reg20: 355260684Skaiw case DW_OP_reg21: 356260684Skaiw case DW_OP_reg22: 357260684Skaiw case DW_OP_reg23: 358260684Skaiw case DW_OP_reg24: 359260684Skaiw case DW_OP_reg25: 360260684Skaiw case DW_OP_reg26: 361260684Skaiw case DW_OP_reg27: 362260684Skaiw case DW_OP_reg28: 363260684Skaiw case DW_OP_reg29: 364260684Skaiw case DW_OP_reg30: 365260684Skaiw case DW_OP_reg31: 366260684Skaiw 367260684Skaiw case DW_OP_lit0: 368260684Skaiw case DW_OP_lit1: 369260684Skaiw case DW_OP_lit2: 370260684Skaiw case DW_OP_lit3: 371260684Skaiw case DW_OP_lit4: 372260684Skaiw case DW_OP_lit5: 373260684Skaiw case DW_OP_lit6: 374260684Skaiw case DW_OP_lit7: 375260684Skaiw case DW_OP_lit8: 376260684Skaiw case DW_OP_lit9: 377260684Skaiw case DW_OP_lit10: 378260684Skaiw case DW_OP_lit11: 379260684Skaiw case DW_OP_lit12: 380260684Skaiw case DW_OP_lit13: 381260684Skaiw case DW_OP_lit14: 382260684Skaiw case DW_OP_lit15: 383260684Skaiw case DW_OP_lit16: 384260684Skaiw case DW_OP_lit17: 385260684Skaiw case DW_OP_lit18: 386260684Skaiw case DW_OP_lit19: 387260684Skaiw case DW_OP_lit20: 388260684Skaiw case DW_OP_lit21: 389260684Skaiw case DW_OP_lit22: 390260684Skaiw case DW_OP_lit23: 391260684Skaiw case DW_OP_lit24: 392260684Skaiw case DW_OP_lit25: 393260684Skaiw case DW_OP_lit26: 394260684Skaiw case DW_OP_lit27: 395260684Skaiw case DW_OP_lit28: 396260684Skaiw case DW_OP_lit29: 397260684Skaiw case DW_OP_lit30: 398260684Skaiw case DW_OP_lit31: 399260684Skaiw 400260684Skaiw case DW_OP_dup: 401260684Skaiw case DW_OP_drop: 402260684Skaiw 403260684Skaiw case DW_OP_over: 404260684Skaiw 405260684Skaiw case DW_OP_swap: 406260684Skaiw case DW_OP_rot: 407260684Skaiw case DW_OP_xderef: 408260684Skaiw 409260684Skaiw case DW_OP_abs: 410260684Skaiw case DW_OP_and: 411260684Skaiw case DW_OP_div: 412260684Skaiw case DW_OP_minus: 413260684Skaiw case DW_OP_mod: 414260684Skaiw case DW_OP_mul: 415260684Skaiw case DW_OP_neg: 416260684Skaiw case DW_OP_not: 417260684Skaiw case DW_OP_or: 418260684Skaiw case DW_OP_plus: 419260684Skaiw 420260684Skaiw case DW_OP_shl: 421260684Skaiw case DW_OP_shr: 422260684Skaiw case DW_OP_shra: 423260684Skaiw case DW_OP_xor: 424260684Skaiw 425260684Skaiw case DW_OP_eq: 426260684Skaiw case DW_OP_ge: 427260684Skaiw case DW_OP_gt: 428260684Skaiw case DW_OP_le: 429260684Skaiw case DW_OP_lt: 430260684Skaiw case DW_OP_ne: 431260684Skaiw 432260684Skaiw case DW_OP_nop: 433260684Skaiw case DW_OP_GNU_push_tls_address: 434260684Skaiw *p++ = atom; 435260684Skaiw break; 436260684Skaiw 437260684Skaiw /* Operations with 1-byte operands. */ 438260684Skaiw case DW_OP_const1u: 439260684Skaiw case DW_OP_const1s: 440260684Skaiw case DW_OP_pick: 441260684Skaiw case DW_OP_deref_size: 442260684Skaiw case DW_OP_xderef_size: 443260684Skaiw *p++ = atom; 444260684Skaiw *p++ = (uint8_t) operand1; 445260684Skaiw break; 446260684Skaiw 447260684Skaiw /* Operations with 2-byte operands. */ 448260684Skaiw case DW_OP_const2u: 449260684Skaiw case DW_OP_const2s: 450260684Skaiw case DW_OP_bra: 451260684Skaiw case DW_OP_skip: 452260684Skaiw *p++ = atom; 453260684Skaiw offset = 0; 454260684Skaiw dbg->write(p, &offset, operand1, 2); 455260684Skaiw p += 2; 456260684Skaiw break; 457260684Skaiw 458260684Skaiw /* Operations with 4-byte operands. */ 459260684Skaiw case DW_OP_const4u: 460260684Skaiw case DW_OP_const4s: 461260684Skaiw *p++ = atom; 462260684Skaiw offset = 0; 463260684Skaiw dbg->write(p, &offset, operand1, 4); 464260684Skaiw p += 4; 465260684Skaiw break; 466260684Skaiw 467260684Skaiw /* Operations with 8-byte operands. */ 468260684Skaiw case DW_OP_const8u: 469260684Skaiw case DW_OP_const8s: 470260684Skaiw *p++ = atom; 471260684Skaiw offset = 0; 472260684Skaiw dbg->write(p, &offset, operand1, 8); 473260684Skaiw p += 8; 474260684Skaiw break; 475260684Skaiw 476260684Skaiw /* Operations with an unsigned LEB128 operand. */ 477260684Skaiw case DW_OP_constu: 478260684Skaiw case DW_OP_plus_uconst: 479260684Skaiw case DW_OP_regx: 480260684Skaiw case DW_OP_piece: 481260684Skaiw *p++ = atom; 482260684Skaiw len = _dwarf_write_uleb128(p, pe, operand1); 483260684Skaiw assert(len > 0); 484260684Skaiw p += len; 485260684Skaiw break; 486260684Skaiw 487260684Skaiw /* Operations with a signed LEB128 operand. */ 488260684Skaiw case DW_OP_consts: 489260684Skaiw case DW_OP_breg0: 490260684Skaiw case DW_OP_breg1: 491260684Skaiw case DW_OP_breg2: 492260684Skaiw case DW_OP_breg3: 493260684Skaiw case DW_OP_breg4: 494260684Skaiw case DW_OP_breg5: 495260684Skaiw case DW_OP_breg6: 496260684Skaiw case DW_OP_breg7: 497260684Skaiw case DW_OP_breg8: 498260684Skaiw case DW_OP_breg9: 499260684Skaiw case DW_OP_breg10: 500260684Skaiw case DW_OP_breg11: 501260684Skaiw case DW_OP_breg12: 502260684Skaiw case DW_OP_breg13: 503260684Skaiw case DW_OP_breg14: 504260684Skaiw case DW_OP_breg15: 505260684Skaiw case DW_OP_breg16: 506260684Skaiw case DW_OP_breg17: 507260684Skaiw case DW_OP_breg18: 508260684Skaiw case DW_OP_breg19: 509260684Skaiw case DW_OP_breg20: 510260684Skaiw case DW_OP_breg21: 511260684Skaiw case DW_OP_breg22: 512260684Skaiw case DW_OP_breg23: 513260684Skaiw case DW_OP_breg24: 514260684Skaiw case DW_OP_breg25: 515260684Skaiw case DW_OP_breg26: 516260684Skaiw case DW_OP_breg27: 517260684Skaiw case DW_OP_breg28: 518260684Skaiw case DW_OP_breg29: 519260684Skaiw case DW_OP_breg30: 520260684Skaiw case DW_OP_breg31: 521260684Skaiw case DW_OP_fbreg: 522260684Skaiw *p++ = atom; 523260684Skaiw len = _dwarf_write_sleb128(p, pe, operand1); 524260684Skaiw assert(len > 0); 525260684Skaiw p += len; 526260684Skaiw break; 527260684Skaiw 528260684Skaiw /* 529260684Skaiw * Operations with an unsigned LEB128 operand 530260684Skaiw * followed by a signed LEB128 operand. 531260684Skaiw */ 532260684Skaiw case DW_OP_bregx: 533260684Skaiw *p++ = atom; 534260684Skaiw len = _dwarf_write_uleb128(p, pe, operand1); 535260684Skaiw assert(len > 0); 536260684Skaiw p += len; 537260684Skaiw len = _dwarf_write_sleb128(p, pe, operand2); 538260684Skaiw assert(len > 0); 539260684Skaiw p += len; 540260684Skaiw break; 541260684Skaiw 542260684Skaiw /* Target address size operand. */ 543260684Skaiw case DW_OP_addr: 544260684Skaiw *p++ = atom; 545260684Skaiw offset = 0; 546260684Skaiw dbg->write(p, &offset, operand1, dbg->dbg_pointer_size); 547260684Skaiw p += dbg->dbg_pointer_size; 548260684Skaiw break; 549260684Skaiw 550260684Skaiw /* All other operations cause an error. */ 551260684Skaiw default: 552260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); 553260684Skaiw return (DW_DLE_LOC_EXPR_BAD); 554260684Skaiw } 555260684Skaiw 556260684Skaiw if (length) 557260684Skaiw *length = p - out; 558260684Skaiw 559260684Skaiw return (DW_DLE_NONE); 560260684Skaiw} 561260684Skaiw 562260684Skaiwint 563260684Skaiw_dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, 564260684Skaiw uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) 565260684Skaiw{ 566260684Skaiw int num; 567260684Skaiw 568260684Skaiw assert(llbuf != NULL); 569260684Skaiw assert(in != NULL); 570260684Skaiw assert(in_len > 0); 571260684Skaiw 572260684Skaiw /* Compute the number of locations. */ 573260684Skaiw if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, in, in_len)) < 574260684Skaiw 0) { 575260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); 576260684Skaiw return (DW_DLE_LOC_EXPR_BAD); 577260684Skaiw } 578260684Skaiw 579260684Skaiw llbuf->ld_cents = num; 580260684Skaiw if (num <= 0) 581260684Skaiw return (DW_DLE_NONE); 582260684Skaiw 583260684Skaiw if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) { 584260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 585260684Skaiw return (DW_DLE_MEMORY); 586260684Skaiw } 587260684Skaiw 588260684Skaiw (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, in, in_len); 589260684Skaiw 590260684Skaiw return (DW_DLE_NONE); 591260684Skaiw} 592260684Skaiw 593260684Skaiwint 594260684Skaiw_dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, 595260684Skaiw uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) 596260684Skaiw{ 597260684Skaiw Dwarf_Locdesc *llbuf; 598260684Skaiw int ret; 599260684Skaiw 600260684Skaiw if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) { 601260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 602260684Skaiw return (DW_DLE_MEMORY); 603260684Skaiw } 604260684Skaiw llbuf->ld_lopc = 0; 605260684Skaiw llbuf->ld_hipc = ~0ULL; 606260684Skaiw llbuf->ld_s = NULL; 607260684Skaiw 608260684Skaiw ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, 609260684Skaiw error); 610260684Skaiw if (ret != DW_DLE_NONE) { 611260684Skaiw free(llbuf); 612260684Skaiw return (ret); 613260684Skaiw } 614260684Skaiw 615260684Skaiw *ret_llbuf = llbuf; 616260684Skaiw 617260684Skaiw return (ret); 618260684Skaiw} 619260684Skaiw 620260684Skaiwint 621260684Skaiw_dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error) 622260684Skaiw{ 623260684Skaiw Dwarf_Debug dbg; 624260684Skaiw Dwarf_CU cu; 625260684Skaiw int ret; 626260684Skaiw 627260684Skaiw assert(at->at_ld == NULL); 628260684Skaiw assert(at->u[1].u8p != NULL); 629260684Skaiw assert(at->u[0].u64 > 0); 630260684Skaiw 631260684Skaiw cu = die->die_cu; 632260684Skaiw assert(cu != NULL); 633260684Skaiw 634260684Skaiw dbg = cu->cu_dbg; 635260684Skaiw assert(dbg != NULL); 636260684Skaiw 637260684Skaiw ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p, 638260684Skaiw at->u[0].u64, cu->cu_pointer_size, error); 639260684Skaiw 640260684Skaiw return (ret); 641260684Skaiw} 642