libdwarf_loc.c revision 276371
1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3276371Semaste * Copyright (c) 2014 Kai Wang 4260684Skaiw * All rights reserved. 5260684Skaiw * 6260684Skaiw * Redistribution and use in source and binary forms, with or without 7260684Skaiw * modification, are permitted provided that the following conditions 8260684Skaiw * are met: 9260684Skaiw * 1. Redistributions of source code must retain the above copyright 10260684Skaiw * notice, this list of conditions and the following disclaimer. 11260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 12260684Skaiw * notice, this list of conditions and the following disclaimer in the 13260684Skaiw * documentation and/or other materials provided with the distribution. 14260684Skaiw * 15260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18260684Skaiw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25260684Skaiw * SUCH DAMAGE. 26260684Skaiw */ 27260684Skaiw 28260684Skaiw#include "_libdwarf.h" 29260684Skaiw 30276371SemasteELFTC_VCSID("$Id: libdwarf_loc.c 3070 2014-06-23 03:08:33Z kaiwang27 $"); 31260684Skaiw 32260684Skaiw/* 33260684Skaiw * Given an array of bytes of length 'len' representing a 34260684Skaiw * DWARF expression, compute the number of operations based 35260684Skaiw * on there being one byte describing the operation and 36260684Skaiw * zero or more bytes of operands as defined in the standard 37260684Skaiw * for each operation type. Also, if lbuf is non-null, store 38260684Skaiw * the opcode and oprand in it. 39260684Skaiw */ 40260684Skaiwstatic int 41260684Skaiw_dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, 42276371Semaste uint8_t offset_size, uint8_t version, uint8_t *p, int len) 43260684Skaiw{ 44260684Skaiw int count; 45260684Skaiw uint64_t operand1; 46260684Skaiw uint64_t operand2; 47276371Semaste uint8_t *ps, *pe, s; 48260684Skaiw 49260684Skaiw count = 0; 50260684Skaiw ps = p; 51260684Skaiw pe = p + len; 52260684Skaiw 53260684Skaiw /* 54260684Skaiw * Process each byte. If an error occurs, then the 55260684Skaiw * count will be set to -1. 56260684Skaiw */ 57260684Skaiw while (p < pe) { 58260684Skaiw 59260684Skaiw operand1 = 0; 60260684Skaiw operand2 = 0; 61260684Skaiw 62260684Skaiw if (lbuf != NULL) { 63260684Skaiw lbuf->ld_s[count].lr_atom = *p; 64260684Skaiw lbuf->ld_s[count].lr_offset = p - ps; 65260684Skaiw } 66260684Skaiw 67260684Skaiw switch (*p++) { 68260684Skaiw /* Operations with no operands. */ 69260684Skaiw case DW_OP_deref: 70260684Skaiw case DW_OP_reg0: 71260684Skaiw case DW_OP_reg1: 72260684Skaiw case DW_OP_reg2: 73260684Skaiw case DW_OP_reg3: 74260684Skaiw case DW_OP_reg4: 75260684Skaiw case DW_OP_reg5: 76260684Skaiw case DW_OP_reg6: 77260684Skaiw case DW_OP_reg7: 78260684Skaiw case DW_OP_reg8: 79260684Skaiw case DW_OP_reg9: 80260684Skaiw case DW_OP_reg10: 81260684Skaiw case DW_OP_reg11: 82260684Skaiw case DW_OP_reg12: 83260684Skaiw case DW_OP_reg13: 84260684Skaiw case DW_OP_reg14: 85260684Skaiw case DW_OP_reg15: 86260684Skaiw case DW_OP_reg16: 87260684Skaiw case DW_OP_reg17: 88260684Skaiw case DW_OP_reg18: 89260684Skaiw case DW_OP_reg19: 90260684Skaiw case DW_OP_reg20: 91260684Skaiw case DW_OP_reg21: 92260684Skaiw case DW_OP_reg22: 93260684Skaiw case DW_OP_reg23: 94260684Skaiw case DW_OP_reg24: 95260684Skaiw case DW_OP_reg25: 96260684Skaiw case DW_OP_reg26: 97260684Skaiw case DW_OP_reg27: 98260684Skaiw case DW_OP_reg28: 99260684Skaiw case DW_OP_reg29: 100260684Skaiw case DW_OP_reg30: 101260684Skaiw case DW_OP_reg31: 102260684Skaiw 103260684Skaiw case DW_OP_lit0: 104260684Skaiw case DW_OP_lit1: 105260684Skaiw case DW_OP_lit2: 106260684Skaiw case DW_OP_lit3: 107260684Skaiw case DW_OP_lit4: 108260684Skaiw case DW_OP_lit5: 109260684Skaiw case DW_OP_lit6: 110260684Skaiw case DW_OP_lit7: 111260684Skaiw case DW_OP_lit8: 112260684Skaiw case DW_OP_lit9: 113260684Skaiw case DW_OP_lit10: 114260684Skaiw case DW_OP_lit11: 115260684Skaiw case DW_OP_lit12: 116260684Skaiw case DW_OP_lit13: 117260684Skaiw case DW_OP_lit14: 118260684Skaiw case DW_OP_lit15: 119260684Skaiw case DW_OP_lit16: 120260684Skaiw case DW_OP_lit17: 121260684Skaiw case DW_OP_lit18: 122260684Skaiw case DW_OP_lit19: 123260684Skaiw case DW_OP_lit20: 124260684Skaiw case DW_OP_lit21: 125260684Skaiw case DW_OP_lit22: 126260684Skaiw case DW_OP_lit23: 127260684Skaiw case DW_OP_lit24: 128260684Skaiw case DW_OP_lit25: 129260684Skaiw case DW_OP_lit26: 130260684Skaiw case DW_OP_lit27: 131260684Skaiw case DW_OP_lit28: 132260684Skaiw case DW_OP_lit29: 133260684Skaiw case DW_OP_lit30: 134260684Skaiw case DW_OP_lit31: 135260684Skaiw 136260684Skaiw case DW_OP_dup: 137260684Skaiw case DW_OP_drop: 138260684Skaiw 139260684Skaiw case DW_OP_over: 140260684Skaiw 141260684Skaiw case DW_OP_swap: 142260684Skaiw case DW_OP_rot: 143260684Skaiw case DW_OP_xderef: 144260684Skaiw 145260684Skaiw case DW_OP_abs: 146260684Skaiw case DW_OP_and: 147260684Skaiw case DW_OP_div: 148260684Skaiw case DW_OP_minus: 149260684Skaiw case DW_OP_mod: 150260684Skaiw case DW_OP_mul: 151260684Skaiw case DW_OP_neg: 152260684Skaiw case DW_OP_not: 153260684Skaiw case DW_OP_or: 154260684Skaiw case DW_OP_plus: 155260684Skaiw 156260684Skaiw case DW_OP_shl: 157260684Skaiw case DW_OP_shr: 158260684Skaiw case DW_OP_shra: 159260684Skaiw case DW_OP_xor: 160260684Skaiw 161260684Skaiw case DW_OP_eq: 162260684Skaiw case DW_OP_ge: 163260684Skaiw case DW_OP_gt: 164260684Skaiw case DW_OP_le: 165260684Skaiw case DW_OP_lt: 166260684Skaiw case DW_OP_ne: 167260684Skaiw 168260684Skaiw case DW_OP_nop: 169276371Semaste case DW_OP_push_object_address: 170260684Skaiw case DW_OP_form_tls_address: 171260684Skaiw case DW_OP_call_frame_cfa: 172260684Skaiw case DW_OP_stack_value: 173260684Skaiw case DW_OP_GNU_push_tls_address: 174276371Semaste case DW_OP_GNU_uninit: 175260684Skaiw break; 176260684Skaiw 177260684Skaiw /* Operations with 1-byte operands. */ 178260684Skaiw case DW_OP_const1u: 179260684Skaiw case DW_OP_pick: 180260684Skaiw case DW_OP_deref_size: 181260684Skaiw case DW_OP_xderef_size: 182260684Skaiw operand1 = *p++; 183260684Skaiw break; 184260684Skaiw 185276371Semaste case DW_OP_const1s: 186276371Semaste operand1 = (int8_t) *p++; 187276371Semaste break; 188276371Semaste 189260684Skaiw /* Operations with 2-byte operands. */ 190260684Skaiw case DW_OP_call2: 191260684Skaiw case DW_OP_const2u: 192260684Skaiw case DW_OP_bra: 193260684Skaiw case DW_OP_skip: 194260684Skaiw operand1 = dbg->decode(&p, 2); 195260684Skaiw break; 196260684Skaiw 197276371Semaste case DW_OP_const2s: 198276371Semaste operand1 = (int16_t) dbg->decode(&p, 2); 199276371Semaste break; 200276371Semaste 201260684Skaiw /* Operations with 4-byte operands. */ 202260684Skaiw case DW_OP_call4: 203260684Skaiw case DW_OP_const4u: 204276371Semaste case DW_OP_GNU_parameter_ref: 205260684Skaiw operand1 = dbg->decode(&p, 4); 206260684Skaiw break; 207260684Skaiw 208276371Semaste case DW_OP_const4s: 209276371Semaste operand1 = (int32_t) dbg->decode(&p, 4); 210276371Semaste break; 211276371Semaste 212260684Skaiw /* Operations with 8-byte operands. */ 213260684Skaiw case DW_OP_const8u: 214260684Skaiw case DW_OP_const8s: 215260684Skaiw operand1 = dbg->decode(&p, 8); 216260684Skaiw break; 217260684Skaiw 218260684Skaiw /* Operations with an unsigned LEB128 operand. */ 219260684Skaiw case DW_OP_constu: 220260684Skaiw case DW_OP_plus_uconst: 221260684Skaiw case DW_OP_regx: 222260684Skaiw case DW_OP_piece: 223276371Semaste case DW_OP_GNU_deref_type: 224276371Semaste case DW_OP_GNU_convert: 225276371Semaste case DW_OP_GNU_reinterpret: 226260684Skaiw operand1 = _dwarf_decode_uleb128(&p); 227260684Skaiw break; 228260684Skaiw 229260684Skaiw /* Operations with a signed LEB128 operand. */ 230260684Skaiw case DW_OP_consts: 231260684Skaiw case DW_OP_breg0: 232260684Skaiw case DW_OP_breg1: 233260684Skaiw case DW_OP_breg2: 234260684Skaiw case DW_OP_breg3: 235260684Skaiw case DW_OP_breg4: 236260684Skaiw case DW_OP_breg5: 237260684Skaiw case DW_OP_breg6: 238260684Skaiw case DW_OP_breg7: 239260684Skaiw case DW_OP_breg8: 240260684Skaiw case DW_OP_breg9: 241260684Skaiw case DW_OP_breg10: 242260684Skaiw case DW_OP_breg11: 243260684Skaiw case DW_OP_breg12: 244260684Skaiw case DW_OP_breg13: 245260684Skaiw case DW_OP_breg14: 246260684Skaiw case DW_OP_breg15: 247260684Skaiw case DW_OP_breg16: 248260684Skaiw case DW_OP_breg17: 249260684Skaiw case DW_OP_breg18: 250260684Skaiw case DW_OP_breg19: 251260684Skaiw case DW_OP_breg20: 252260684Skaiw case DW_OP_breg21: 253260684Skaiw case DW_OP_breg22: 254260684Skaiw case DW_OP_breg23: 255260684Skaiw case DW_OP_breg24: 256260684Skaiw case DW_OP_breg25: 257260684Skaiw case DW_OP_breg26: 258260684Skaiw case DW_OP_breg27: 259260684Skaiw case DW_OP_breg28: 260260684Skaiw case DW_OP_breg29: 261260684Skaiw case DW_OP_breg30: 262260684Skaiw case DW_OP_breg31: 263260684Skaiw case DW_OP_fbreg: 264260684Skaiw operand1 = _dwarf_decode_sleb128(&p); 265260684Skaiw break; 266260684Skaiw 267260684Skaiw /* 268260684Skaiw * Oeration with two unsigned LEB128 operands. 269260684Skaiw */ 270260684Skaiw case DW_OP_bit_piece: 271276371Semaste case DW_OP_GNU_regval_type: 272260684Skaiw operand1 = _dwarf_decode_uleb128(&p); 273260684Skaiw operand2 = _dwarf_decode_uleb128(&p); 274260684Skaiw break; 275260684Skaiw 276260684Skaiw /* 277260684Skaiw * Operations with an unsigned LEB128 operand 278260684Skaiw * followed by a signed LEB128 operand. 279260684Skaiw */ 280260684Skaiw case DW_OP_bregx: 281260684Skaiw operand1 = _dwarf_decode_uleb128(&p); 282260684Skaiw operand2 = _dwarf_decode_sleb128(&p); 283260684Skaiw break; 284260684Skaiw 285260684Skaiw /* 286260684Skaiw * Operation with an unsigned LEB128 operand 287276371Semaste * representing the size of a block, followed 288276371Semaste * by the block content. 289276371Semaste * 290276371Semaste * Store the size of the block in the operand1 291276371Semaste * and a pointer to the block in the operand2. 292260684Skaiw */ 293260684Skaiw case DW_OP_implicit_value: 294276371Semaste case DW_OP_GNU_entry_value: 295260684Skaiw operand1 = _dwarf_decode_uleb128(&p); 296260684Skaiw operand2 = (Dwarf_Unsigned) (uintptr_t) p; 297260684Skaiw p += operand1; 298260684Skaiw break; 299260684Skaiw 300260684Skaiw /* Target address size operand. */ 301260684Skaiw case DW_OP_addr: 302276371Semaste case DW_OP_GNU_addr_index: 303276371Semaste case DW_OP_GNU_const_index: 304260684Skaiw operand1 = dbg->decode(&p, pointer_size); 305260684Skaiw break; 306260684Skaiw 307276371Semaste /* Offset size operand. */ 308276371Semaste case DW_OP_call_ref: 309276371Semaste operand1 = dbg->decode(&p, offset_size); 310276371Semaste break; 311276371Semaste 312260684Skaiw /* 313276371Semaste * The first byte is address byte length, followed by 314276371Semaste * the address value. If the length is 0, the address 315276371Semaste * size is the same as target pointer size. 316260684Skaiw */ 317276371Semaste case DW_OP_GNU_encoded_addr: 318276371Semaste s = *p++; 319276371Semaste if (s == 0) 320276371Semaste s = pointer_size; 321276371Semaste operand1 = dbg->decode(&p, s); 322260684Skaiw break; 323260684Skaiw 324276371Semaste /* 325276371Semaste * Operand1: DIE offset (size depending on DWARF version) 326276371Semaste * DWARF2: pointer size 327276371Semaste * DWARF{3,4}: offset size 328276371Semaste * 329276371Semaste * Operand2: SLEB128 330276371Semaste */ 331276371Semaste case DW_OP_GNU_implicit_pointer: 332276371Semaste if (version == 2) 333276371Semaste operand1 = dbg->decode(&p, pointer_size); 334276371Semaste else 335276371Semaste operand1 = dbg->decode(&p, offset_size); 336276371Semaste operand2 = _dwarf_decode_sleb128(&p); 337276371Semaste break; 338276371Semaste 339276371Semaste /* 340276371Semaste * Operand1: DIE offset (ULEB128) 341276371Semaste * Operand2: pointer to a block. The block's first byte 342276371Semaste * is its size. 343276371Semaste */ 344276371Semaste case DW_OP_GNU_const_type: 345276371Semaste operand1 = _dwarf_decode_uleb128(&p); 346276371Semaste operand2 = (Dwarf_Unsigned) (uintptr_t) p; 347276371Semaste s = *p++; 348276371Semaste p += s; 349276371Semaste break; 350276371Semaste 351260684Skaiw /* All other operations cause an error. */ 352260684Skaiw default: 353260684Skaiw count = -1; 354276371Semaste goto done; 355260684Skaiw } 356260684Skaiw 357260684Skaiw if (lbuf != NULL) { 358260684Skaiw lbuf->ld_s[count].lr_number = operand1; 359260684Skaiw lbuf->ld_s[count].lr_number2 = operand2; 360260684Skaiw } 361260684Skaiw 362260684Skaiw count++; 363260684Skaiw } 364260684Skaiw 365276371Semastedone: 366260684Skaiw return (count); 367260684Skaiw} 368260684Skaiw 369260684Skaiwint 370260684Skaiw_dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end, 371260684Skaiw Dwarf_Small atom, Dwarf_Unsigned operand1, Dwarf_Unsigned operand2, 372260684Skaiw int *length, Dwarf_Error *error) 373260684Skaiw{ 374260684Skaiw uint8_t buf[64]; 375260684Skaiw uint8_t *p, *pe; 376260684Skaiw uint64_t offset; 377260684Skaiw int len; 378260684Skaiw 379260684Skaiw if (out != NULL && end != NULL) { 380260684Skaiw p = out; 381260684Skaiw pe = end; 382260684Skaiw } else { 383260684Skaiw p = out = buf; 384260684Skaiw pe = &buf[sizeof(buf)]; 385260684Skaiw } 386260684Skaiw 387260684Skaiw switch (atom) { 388260684Skaiw /* Operations with no operands. */ 389260684Skaiw case DW_OP_deref: 390260684Skaiw case DW_OP_reg0: 391260684Skaiw case DW_OP_reg1: 392260684Skaiw case DW_OP_reg2: 393260684Skaiw case DW_OP_reg3: 394260684Skaiw case DW_OP_reg4: 395260684Skaiw case DW_OP_reg5: 396260684Skaiw case DW_OP_reg6: 397260684Skaiw case DW_OP_reg7: 398260684Skaiw case DW_OP_reg8: 399260684Skaiw case DW_OP_reg9: 400260684Skaiw case DW_OP_reg10: 401260684Skaiw case DW_OP_reg11: 402260684Skaiw case DW_OP_reg12: 403260684Skaiw case DW_OP_reg13: 404260684Skaiw case DW_OP_reg14: 405260684Skaiw case DW_OP_reg15: 406260684Skaiw case DW_OP_reg16: 407260684Skaiw case DW_OP_reg17: 408260684Skaiw case DW_OP_reg18: 409260684Skaiw case DW_OP_reg19: 410260684Skaiw case DW_OP_reg20: 411260684Skaiw case DW_OP_reg21: 412260684Skaiw case DW_OP_reg22: 413260684Skaiw case DW_OP_reg23: 414260684Skaiw case DW_OP_reg24: 415260684Skaiw case DW_OP_reg25: 416260684Skaiw case DW_OP_reg26: 417260684Skaiw case DW_OP_reg27: 418260684Skaiw case DW_OP_reg28: 419260684Skaiw case DW_OP_reg29: 420260684Skaiw case DW_OP_reg30: 421260684Skaiw case DW_OP_reg31: 422260684Skaiw 423260684Skaiw case DW_OP_lit0: 424260684Skaiw case DW_OP_lit1: 425260684Skaiw case DW_OP_lit2: 426260684Skaiw case DW_OP_lit3: 427260684Skaiw case DW_OP_lit4: 428260684Skaiw case DW_OP_lit5: 429260684Skaiw case DW_OP_lit6: 430260684Skaiw case DW_OP_lit7: 431260684Skaiw case DW_OP_lit8: 432260684Skaiw case DW_OP_lit9: 433260684Skaiw case DW_OP_lit10: 434260684Skaiw case DW_OP_lit11: 435260684Skaiw case DW_OP_lit12: 436260684Skaiw case DW_OP_lit13: 437260684Skaiw case DW_OP_lit14: 438260684Skaiw case DW_OP_lit15: 439260684Skaiw case DW_OP_lit16: 440260684Skaiw case DW_OP_lit17: 441260684Skaiw case DW_OP_lit18: 442260684Skaiw case DW_OP_lit19: 443260684Skaiw case DW_OP_lit20: 444260684Skaiw case DW_OP_lit21: 445260684Skaiw case DW_OP_lit22: 446260684Skaiw case DW_OP_lit23: 447260684Skaiw case DW_OP_lit24: 448260684Skaiw case DW_OP_lit25: 449260684Skaiw case DW_OP_lit26: 450260684Skaiw case DW_OP_lit27: 451260684Skaiw case DW_OP_lit28: 452260684Skaiw case DW_OP_lit29: 453260684Skaiw case DW_OP_lit30: 454260684Skaiw case DW_OP_lit31: 455260684Skaiw 456260684Skaiw case DW_OP_dup: 457260684Skaiw case DW_OP_drop: 458260684Skaiw 459260684Skaiw case DW_OP_over: 460260684Skaiw 461260684Skaiw case DW_OP_swap: 462260684Skaiw case DW_OP_rot: 463260684Skaiw case DW_OP_xderef: 464260684Skaiw 465260684Skaiw case DW_OP_abs: 466260684Skaiw case DW_OP_and: 467260684Skaiw case DW_OP_div: 468260684Skaiw case DW_OP_minus: 469260684Skaiw case DW_OP_mod: 470260684Skaiw case DW_OP_mul: 471260684Skaiw case DW_OP_neg: 472260684Skaiw case DW_OP_not: 473260684Skaiw case DW_OP_or: 474260684Skaiw case DW_OP_plus: 475260684Skaiw 476260684Skaiw case DW_OP_shl: 477260684Skaiw case DW_OP_shr: 478260684Skaiw case DW_OP_shra: 479260684Skaiw case DW_OP_xor: 480260684Skaiw 481260684Skaiw case DW_OP_eq: 482260684Skaiw case DW_OP_ge: 483260684Skaiw case DW_OP_gt: 484260684Skaiw case DW_OP_le: 485260684Skaiw case DW_OP_lt: 486260684Skaiw case DW_OP_ne: 487260684Skaiw 488260684Skaiw case DW_OP_nop: 489260684Skaiw case DW_OP_GNU_push_tls_address: 490260684Skaiw *p++ = atom; 491260684Skaiw break; 492260684Skaiw 493260684Skaiw /* Operations with 1-byte operands. */ 494260684Skaiw case DW_OP_const1u: 495260684Skaiw case DW_OP_const1s: 496260684Skaiw case DW_OP_pick: 497260684Skaiw case DW_OP_deref_size: 498260684Skaiw case DW_OP_xderef_size: 499260684Skaiw *p++ = atom; 500260684Skaiw *p++ = (uint8_t) operand1; 501260684Skaiw break; 502260684Skaiw 503260684Skaiw /* Operations with 2-byte operands. */ 504260684Skaiw case DW_OP_const2u: 505260684Skaiw case DW_OP_const2s: 506260684Skaiw case DW_OP_bra: 507260684Skaiw case DW_OP_skip: 508260684Skaiw *p++ = atom; 509260684Skaiw offset = 0; 510260684Skaiw dbg->write(p, &offset, operand1, 2); 511260684Skaiw p += 2; 512260684Skaiw break; 513260684Skaiw 514260684Skaiw /* Operations with 4-byte operands. */ 515260684Skaiw case DW_OP_const4u: 516260684Skaiw case DW_OP_const4s: 517260684Skaiw *p++ = atom; 518260684Skaiw offset = 0; 519260684Skaiw dbg->write(p, &offset, operand1, 4); 520260684Skaiw p += 4; 521260684Skaiw break; 522260684Skaiw 523260684Skaiw /* Operations with 8-byte operands. */ 524260684Skaiw case DW_OP_const8u: 525260684Skaiw case DW_OP_const8s: 526260684Skaiw *p++ = atom; 527260684Skaiw offset = 0; 528260684Skaiw dbg->write(p, &offset, operand1, 8); 529260684Skaiw p += 8; 530260684Skaiw break; 531260684Skaiw 532260684Skaiw /* Operations with an unsigned LEB128 operand. */ 533260684Skaiw case DW_OP_constu: 534260684Skaiw case DW_OP_plus_uconst: 535260684Skaiw case DW_OP_regx: 536260684Skaiw case DW_OP_piece: 537260684Skaiw *p++ = atom; 538260684Skaiw len = _dwarf_write_uleb128(p, pe, operand1); 539260684Skaiw assert(len > 0); 540260684Skaiw p += len; 541260684Skaiw break; 542260684Skaiw 543260684Skaiw /* Operations with a signed LEB128 operand. */ 544260684Skaiw case DW_OP_consts: 545260684Skaiw case DW_OP_breg0: 546260684Skaiw case DW_OP_breg1: 547260684Skaiw case DW_OP_breg2: 548260684Skaiw case DW_OP_breg3: 549260684Skaiw case DW_OP_breg4: 550260684Skaiw case DW_OP_breg5: 551260684Skaiw case DW_OP_breg6: 552260684Skaiw case DW_OP_breg7: 553260684Skaiw case DW_OP_breg8: 554260684Skaiw case DW_OP_breg9: 555260684Skaiw case DW_OP_breg10: 556260684Skaiw case DW_OP_breg11: 557260684Skaiw case DW_OP_breg12: 558260684Skaiw case DW_OP_breg13: 559260684Skaiw case DW_OP_breg14: 560260684Skaiw case DW_OP_breg15: 561260684Skaiw case DW_OP_breg16: 562260684Skaiw case DW_OP_breg17: 563260684Skaiw case DW_OP_breg18: 564260684Skaiw case DW_OP_breg19: 565260684Skaiw case DW_OP_breg20: 566260684Skaiw case DW_OP_breg21: 567260684Skaiw case DW_OP_breg22: 568260684Skaiw case DW_OP_breg23: 569260684Skaiw case DW_OP_breg24: 570260684Skaiw case DW_OP_breg25: 571260684Skaiw case DW_OP_breg26: 572260684Skaiw case DW_OP_breg27: 573260684Skaiw case DW_OP_breg28: 574260684Skaiw case DW_OP_breg29: 575260684Skaiw case DW_OP_breg30: 576260684Skaiw case DW_OP_breg31: 577260684Skaiw case DW_OP_fbreg: 578260684Skaiw *p++ = atom; 579260684Skaiw len = _dwarf_write_sleb128(p, pe, operand1); 580260684Skaiw assert(len > 0); 581260684Skaiw p += len; 582260684Skaiw break; 583260684Skaiw 584260684Skaiw /* 585260684Skaiw * Operations with an unsigned LEB128 operand 586260684Skaiw * followed by a signed LEB128 operand. 587260684Skaiw */ 588260684Skaiw case DW_OP_bregx: 589260684Skaiw *p++ = atom; 590260684Skaiw len = _dwarf_write_uleb128(p, pe, operand1); 591260684Skaiw assert(len > 0); 592260684Skaiw p += len; 593260684Skaiw len = _dwarf_write_sleb128(p, pe, operand2); 594260684Skaiw assert(len > 0); 595260684Skaiw p += len; 596260684Skaiw break; 597260684Skaiw 598260684Skaiw /* Target address size operand. */ 599260684Skaiw case DW_OP_addr: 600260684Skaiw *p++ = atom; 601260684Skaiw offset = 0; 602260684Skaiw dbg->write(p, &offset, operand1, dbg->dbg_pointer_size); 603260684Skaiw p += dbg->dbg_pointer_size; 604260684Skaiw break; 605260684Skaiw 606260684Skaiw /* All other operations cause an error. */ 607260684Skaiw default: 608260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); 609260684Skaiw return (DW_DLE_LOC_EXPR_BAD); 610260684Skaiw } 611260684Skaiw 612260684Skaiw if (length) 613260684Skaiw *length = p - out; 614260684Skaiw 615260684Skaiw return (DW_DLE_NONE); 616260684Skaiw} 617260684Skaiw 618260684Skaiwint 619260684Skaiw_dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, 620276371Semaste uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, 621276371Semaste uint8_t version, Dwarf_Error *error) 622260684Skaiw{ 623260684Skaiw int num; 624260684Skaiw 625260684Skaiw assert(llbuf != NULL); 626260684Skaiw assert(in != NULL); 627260684Skaiw assert(in_len > 0); 628260684Skaiw 629260684Skaiw /* Compute the number of locations. */ 630276371Semaste if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, offset_size, 631276371Semaste version, in, in_len)) < 0) { 632260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); 633260684Skaiw return (DW_DLE_LOC_EXPR_BAD); 634260684Skaiw } 635260684Skaiw 636260684Skaiw llbuf->ld_cents = num; 637260684Skaiw if (num <= 0) 638260684Skaiw return (DW_DLE_NONE); 639260684Skaiw 640260684Skaiw if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) { 641260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 642260684Skaiw return (DW_DLE_MEMORY); 643260684Skaiw } 644260684Skaiw 645276371Semaste (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, offset_size, 646276371Semaste version, in, in_len); 647260684Skaiw 648260684Skaiw return (DW_DLE_NONE); 649260684Skaiw} 650260684Skaiw 651260684Skaiwint 652260684Skaiw_dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, 653276371Semaste uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, 654276371Semaste uint8_t version, Dwarf_Error *error) 655260684Skaiw{ 656260684Skaiw Dwarf_Locdesc *llbuf; 657260684Skaiw int ret; 658260684Skaiw 659260684Skaiw if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) { 660260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 661260684Skaiw return (DW_DLE_MEMORY); 662260684Skaiw } 663260684Skaiw llbuf->ld_lopc = 0; 664260684Skaiw llbuf->ld_hipc = ~0ULL; 665260684Skaiw llbuf->ld_s = NULL; 666260684Skaiw 667260684Skaiw ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, 668276371Semaste offset_size, version, error); 669260684Skaiw if (ret != DW_DLE_NONE) { 670260684Skaiw free(llbuf); 671260684Skaiw return (ret); 672260684Skaiw } 673260684Skaiw 674260684Skaiw *ret_llbuf = llbuf; 675260684Skaiw 676260684Skaiw return (ret); 677260684Skaiw} 678260684Skaiw 679260684Skaiwint 680260684Skaiw_dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error) 681260684Skaiw{ 682260684Skaiw Dwarf_Debug dbg; 683260684Skaiw Dwarf_CU cu; 684260684Skaiw int ret; 685260684Skaiw 686260684Skaiw assert(at->at_ld == NULL); 687260684Skaiw assert(at->u[1].u8p != NULL); 688260684Skaiw assert(at->u[0].u64 > 0); 689260684Skaiw 690260684Skaiw cu = die->die_cu; 691260684Skaiw assert(cu != NULL); 692260684Skaiw 693260684Skaiw dbg = cu->cu_dbg; 694260684Skaiw assert(dbg != NULL); 695260684Skaiw 696260684Skaiw ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p, 697276371Semaste at->u[0].u64, cu->cu_pointer_size, cu->cu_length_size == 4 ? 4 : 8, 698276371Semaste cu->cu_version, error); 699260684Skaiw 700260684Skaiw return (ret); 701260684Skaiw} 702