dwarf_init.c revision 252430
1179187Sjb/*- 2179187Sjb * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3179187Sjb * All rights reserved. 4179187Sjb * 5179187Sjb * Redistribution and use in source and binary forms, with or without 6179187Sjb * modification, are permitted provided that the following conditions 7179187Sjb * are met: 8179187Sjb * 1. Redistributions of source code must retain the above copyright 9179187Sjb * notice, this list of conditions and the following disclaimer. 10179187Sjb * 2. Redistributions in binary form must reproduce the above copyright 11179187Sjb * notice, this list of conditions and the following disclaimer in the 12179187Sjb * documentation and/or other materials provided with the distribution. 13179187Sjb * 14179187Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15179187Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16179187Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17179187Sjb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18179187Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19179187Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20179187Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21179187Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22179187Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23179187Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24179187Sjb * SUCH DAMAGE. 25179187Sjb * 26179187Sjb * $FreeBSD: head/lib/libdwarf/dwarf_init.c 252430 2013-06-30 21:06:47Z kaiw $ 27179187Sjb */ 28179187Sjb 29179187Sjb#include <stdlib.h> 30179187Sjb#include <string.h> 31179187Sjb#include "_libdwarf.h" 32179187Sjb 33179187Sjbstatic const char *debug_snames[DWARF_DEBUG_SNAMES] = { 34179187Sjb ".debug_abbrev", 35179187Sjb ".debug_aranges", 36179187Sjb ".debug_frame", 37179187Sjb ".debug_info", 38179187Sjb ".debug_line", 39179187Sjb ".debug_pubnames", 40179187Sjb ".eh_frame", 41179187Sjb ".debug_macinfo", 42179187Sjb ".debug_str", 43179187Sjb ".debug_loc", 44179187Sjb ".debug_pubtypes", 45179187Sjb ".debug_ranges", 46179187Sjb ".debug_static_func", 47179187Sjb ".debug_static_vars", 48179187Sjb ".debug_types", 49179187Sjb ".debug_weaknames", 50179187Sjb ".symtab", 51179187Sjb ".strtab" 52179187Sjb}; 53179187Sjb 54179187Sjbstatic uint64_t (*dwarf_read) (Elf_Data **, uint64_t *, int); 55179187Sjbstatic void (*dwarf_write) (Elf_Data **, uint64_t *, uint64_t, int); 56179187Sjb 57179187Sjbstatic uint64_t 58179187Sjbdwarf_read_lsb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read) 59179187Sjb{ 60179187Sjb uint64_t ret = 0; 61179187Sjb 62179187Sjb uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; 63179187Sjb 64179187Sjb switch (bytes_to_read) { 65179187Sjb case 8: 66179187Sjb ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; 67179187Sjb ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; 68179187Sjb case 4: 69179187Sjb ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; 70179187Sjb case 2: 71179187Sjb ret |= ((uint64_t) src[1]) << 8; 72179187Sjb case 1: 73179187Sjb ret |= src[0]; 74179187Sjb break; 75179187Sjb default: 76179187Sjb return 0; 77179187Sjb break; 78179187Sjb } 79179187Sjb 80179187Sjb *offsetp += bytes_to_read; 81179187Sjb 82179187Sjb return ret; 83179187Sjb} 84179187Sjb 85179187Sjbstatic uint64_t 86179187Sjbdwarf_read_msb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read) 87179187Sjb{ 88179187Sjb uint64_t ret = 0; 89179187Sjb 90179187Sjb uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; 91179187Sjb 92179187Sjb switch (bytes_to_read) { 93179187Sjb case 1: 94179187Sjb ret = src[0]; 95179187Sjb break; 96179187Sjb case 2: 97179187Sjb ret = src[1] | ((uint64_t) src[0]) << 8; 98179187Sjb break; 99179187Sjb case 4: 100179187Sjb ret = src[3] | ((uint64_t) src[2]) << 8; 101179187Sjb ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; 102179187Sjb break; 103179187Sjb case 8: 104179187Sjb ret = src[7] | ((uint64_t) src[6]) << 8; 105179187Sjb ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; 106179187Sjb ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; 107179187Sjb ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; 108179187Sjb break; 109179187Sjb default: 110179187Sjb return 0; 111179187Sjb break; 112179187Sjb } 113179187Sjb 114179187Sjb *offsetp += bytes_to_read; 115179187Sjb 116179187Sjb return ret; 117179187Sjb} 118179187Sjb 119179187Sjbstatic void 120179187Sjbdwarf_write_lsb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write) 121179187Sjb{ 122179187Sjb uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp; 123179187Sjb 124179187Sjb switch (bytes_to_write) { 125179187Sjb case 8: 126179187Sjb dst[7] = (value >> 56) & 0xff; 127179187Sjb dst[6] = (value >> 48) & 0xff; 128179187Sjb dst[5] = (value >> 40) & 0xff; 129179187Sjb dst[4] = (value >> 32) & 0xff; 130179187Sjb case 4: 131179187Sjb dst[3] = (value >> 24) & 0xff; 132179187Sjb dst[2] = (value >> 16) & 0xff; 133179187Sjb case 2: 134179187Sjb dst[1] = (value >> 8) & 0xff; 135179187Sjb case 1: 136179187Sjb dst[0] = value & 0xff; 137179187Sjb break; 138179187Sjb default: 139179187Sjb return; 140179187Sjb break; 141179187Sjb } 142179187Sjb 143179187Sjb *offsetp += bytes_to_write; 144179187Sjb} 145179187Sjb 146179187Sjbstatic void 147179187Sjbdwarf_write_msb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write) 148179187Sjb{ 149179187Sjb uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp; 150179187Sjb 151179187Sjb switch (bytes_to_write) { 152179187Sjb case 8: 153179187Sjb dst[7] = value & 0xff; 154179187Sjb dst[6] = (value >> 8) & 0xff; 155179187Sjb dst[5] = (value >> 16) & 0xff; 156179187Sjb dst[4] = (value >> 24) & 0xff; 157179187Sjb value >>= 32; 158179187Sjb case 4: 159179187Sjb dst[3] = value & 0xff; 160179187Sjb dst[2] = (value >> 8) & 0xff; 161179187Sjb value >>= 16; 162179187Sjb case 2: 163179187Sjb dst[1] = value & 0xff; 164179187Sjb value >>= 8; 165179187Sjb case 1: 166179187Sjb dst[0] = value & 0xff; 167179187Sjb break; 168179187Sjb default: 169179187Sjb return; 170179187Sjb break; 171179187Sjb } 172179187Sjb 173179187Sjb *offsetp += bytes_to_write; 174179187Sjb} 175179187Sjb 176179187Sjbstatic int64_t 177179187Sjbdwarf_read_sleb128(Elf_Data **dp, uint64_t *offsetp) 178179187Sjb{ 179179187Sjb int64_t ret = 0; 180179187Sjb uint8_t b; 181179187Sjb int shift = 0; 182179187Sjb 183179187Sjb uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; 184179187Sjb 185179187Sjb do { 186179187Sjb b = *src++; 187179187Sjb 188179187Sjb ret |= ((b & 0x7f) << shift); 189179187Sjb 190179187Sjb (*offsetp)++; 191179187Sjb 192179187Sjb shift += 7; 193179187Sjb } while ((b & 0x80) != 0); 194179187Sjb 195252430Skaiw if (shift < 64 && (b & 0x40) != 0) 196179187Sjb ret |= (-1 << shift); 197179187Sjb 198179187Sjb return ret; 199179187Sjb} 200179187Sjb 201179187Sjbstatic uint64_t 202179187Sjbdwarf_read_uleb128(Elf_Data **dp, uint64_t *offsetp) 203179187Sjb{ 204179187Sjb uint64_t ret = 0; 205179187Sjb uint8_t b; 206179187Sjb int shift = 0; 207179187Sjb 208179187Sjb uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; 209179187Sjb 210179187Sjb do { 211179187Sjb b = *src++; 212179187Sjb 213179187Sjb ret |= ((b & 0x7f) << shift); 214179187Sjb 215179187Sjb (*offsetp)++; 216179187Sjb 217179187Sjb shift += 7; 218179187Sjb } while ((b & 0x80) != 0); 219179187Sjb 220179187Sjb return ret; 221179187Sjb} 222179187Sjb 223179187Sjbstatic const char * 224179187Sjbdwarf_read_string(Elf_Data **dp, uint64_t *offsetp) 225179187Sjb{ 226179187Sjb char *ret; 227179187Sjb 228179187Sjb char *src = (char *) (*dp)->d_buf + *offsetp; 229179187Sjb 230179187Sjb ret = src; 231179187Sjb 232179187Sjb while (*src != '\0' && *offsetp < (*dp)->d_size) { 233179187Sjb src++; 234179187Sjb (*offsetp)++; 235179187Sjb } 236179187Sjb 237179187Sjb if (*src == '\0' && *offsetp < (*dp)->d_size) 238179187Sjb (*offsetp)++; 239179187Sjb 240179187Sjb return ret; 241179187Sjb} 242179187Sjb 243179187Sjbstatic uint8_t * 244179187Sjbdwarf_read_block(Elf_Data **dp, uint64_t *offsetp, uint64_t length) 245179187Sjb{ 246179187Sjb uint8_t *ret; 247179187Sjb 248179187Sjb uint8_t *src = (char *) (*dp)->d_buf + *offsetp; 249179187Sjb 250179187Sjb ret = src; 251179187Sjb 252179187Sjb (*offsetp) += length; 253179187Sjb 254179187Sjb return ret; 255179187Sjb} 256179187Sjb 257179187Sjbstatic int 258179187Sjbdwarf_apply_relocations(Dwarf_Debug dbg, Elf_Data *reld, int secindx) 259179187Sjb{ 260179187Sjb Elf_Data *d; 261179187Sjb GElf_Rela rela; 262179187Sjb int indx = 0; 263179187Sjb int ret = DWARF_E_NONE; 264179187Sjb uint64_t offset; 265179187Sjb 266179187Sjb /* Point to the data to be relocated: */ 267179187Sjb d = dbg->dbg_s[secindx].s_data; 268179187Sjb 269179187Sjb /* Enter a loop to process each relocation addend: */ 270179187Sjb while (gelf_getrela(reld, indx++, &rela) != NULL) { 271179187Sjb GElf_Sym sym; 272179187Sjb Elf64_Xword symindx = ELF64_R_SYM(rela.r_info); 273179187Sjb 274179187Sjb if (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, symindx, &sym) == NULL) { 275179187Sjb printf("Couldn't find symbol index %lu for relocation\n",(u_long) symindx); 276179187Sjb continue; 277179187Sjb } 278179187Sjb 279179187Sjb offset = rela.r_offset; 280179187Sjb 281179187Sjb dwarf_write(&d, &offset, rela.r_addend, dbg->dbg_offsize); 282179187Sjb } 283179187Sjb 284179187Sjb return ret; 285179187Sjb} 286179187Sjb 287179187Sjbstatic int 288179187Sjbdwarf_relocate(Dwarf_Debug dbg, Dwarf_Error *error) 289179187Sjb{ 290179187Sjb Elf_Scn *scn = NULL; 291179187Sjb GElf_Shdr shdr; 292179187Sjb int i; 293179187Sjb int ret = DWARF_E_NONE; 294179187Sjb 295179187Sjb /* Look for sections which relocate the debug sections. */ 296179187Sjb while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) { 297179187Sjb if (gelf_getshdr(scn, &shdr) == NULL) { 298179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 299179187Sjb return DWARF_E_ELF; 300179187Sjb } 301179187Sjb 302179187Sjb if (shdr.sh_type != SHT_RELA || shdr.sh_size == 0) 303179187Sjb continue; 304179187Sjb 305179187Sjb for (i = 0; i < DWARF_DEBUG_SNAMES; i++) { 306179187Sjb if (dbg->dbg_s[i].s_shnum == shdr.sh_info && 307179187Sjb dbg->dbg_s[DWARF_symtab].s_shnum == shdr.sh_link) { 308179187Sjb Elf_Data *rd; 309179187Sjb 310179187Sjb /* Get the relocation data. */ 311179187Sjb if ((rd = elf_getdata(scn, NULL)) == NULL) { 312179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 313179187Sjb return DWARF_E_ELF; 314179187Sjb } 315179187Sjb 316179187Sjb /* Apply the relocations. */ 317179187Sjb dwarf_apply_relocations(dbg, rd, i); 318179187Sjb break; 319179187Sjb } 320179187Sjb } 321179187Sjb } 322179187Sjb 323179187Sjb return ret; 324179187Sjb} 325179187Sjb 326179187Sjbstatic int 327179187Sjbdwarf_init_attr(Dwarf_Debug dbg, Elf_Data **dp, uint64_t *offsetp, 328179187Sjb Dwarf_CU cu, Dwarf_Die die, Dwarf_Attribute at, uint64_t form, 329179187Sjb Dwarf_Error *error) 330179187Sjb{ 331179187Sjb int ret = DWARF_E_NONE; 332179187Sjb struct _Dwarf_AttrValue avref; 333179187Sjb 334179187Sjb memset(&avref, 0, sizeof(avref)); 335179187Sjb avref.av_attrib = at->at_attrib; 336179187Sjb avref.av_form = at->at_form; 337179187Sjb 338179187Sjb switch (form) { 339179187Sjb case DW_FORM_addr: 340179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size); 341179187Sjb break; 342179187Sjb case DW_FORM_block: 343179187Sjb avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp); 344179187Sjb avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); 345179187Sjb break; 346179187Sjb case DW_FORM_block1: 347179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, 1); 348179187Sjb avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); 349179187Sjb break; 350179187Sjb case DW_FORM_block2: 351179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, 2); 352179187Sjb avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); 353179187Sjb break; 354179187Sjb case DW_FORM_block4: 355179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, 4); 356179187Sjb avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); 357179187Sjb break; 358179187Sjb case DW_FORM_data1: 359179187Sjb case DW_FORM_flag: 360179187Sjb case DW_FORM_ref1: 361179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, 1); 362179187Sjb break; 363179187Sjb case DW_FORM_data2: 364179187Sjb case DW_FORM_ref2: 365179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, 2); 366179187Sjb break; 367179187Sjb case DW_FORM_data4: 368179187Sjb case DW_FORM_ref4: 369179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, 4); 370179187Sjb break; 371179187Sjb case DW_FORM_data8: 372179187Sjb case DW_FORM_ref8: 373179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, 8); 374179187Sjb break; 375179187Sjb case DW_FORM_indirect: 376179187Sjb form = dwarf_read_uleb128(dp, offsetp); 377179187Sjb return dwarf_init_attr(dbg, dp, offsetp, cu, die, at, form, error); 378179187Sjb case DW_FORM_ref_addr: 379179187Sjb if (cu->cu_version == 2) 380179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size); 381179187Sjb else if (cu->cu_version == 3) 382179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize); 383179187Sjb break; 384179187Sjb case DW_FORM_ref_udata: 385179187Sjb case DW_FORM_udata: 386179187Sjb avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp); 387179187Sjb break; 388179187Sjb case DW_FORM_sdata: 389179187Sjb avref.u[0].s64 = dwarf_read_sleb128(dp, offsetp); 390179187Sjb break; 391179187Sjb case DW_FORM_string: 392179187Sjb avref.u[0].s = dwarf_read_string(dp, offsetp); 393179187Sjb break; 394179187Sjb case DW_FORM_strp: 395179187Sjb avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize); 396179187Sjb avref.u[1].s = elf_strptr(dbg->dbg_elf, 397179187Sjb dbg->dbg_s[DWARF_debug_str].s_shnum, avref.u[0].u64); 398179187Sjb break; 399239872Sdim case DW_FORM_flag_present: 400239872Sdim /* This form has no value encoded in the DIE. */ 401239872Sdim avref.u[0].u64 = 1; 402239872Sdim break; 403179187Sjb default: 404179187Sjb DWARF_SET_ERROR(error, DWARF_E_NOT_IMPLEMENTED); 405179187Sjb ret = DWARF_E_NOT_IMPLEMENTED; 406179187Sjb break; 407179187Sjb } 408179187Sjb 409179187Sjb if (ret == DWARF_E_NONE) 410179187Sjb ret = dwarf_attrval_add(die, &avref, NULL, error); 411179187Sjb 412179187Sjb return ret; 413179187Sjb} 414179187Sjb 415179187Sjbstatic int 416179187Sjbdwarf_init_abbrev(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Error *error) 417179187Sjb{ 418179187Sjb Dwarf_Abbrev a; 419179187Sjb Elf_Data *d; 420179187Sjb int ret = DWARF_E_NONE; 421179187Sjb uint64_t attr; 422179187Sjb uint64_t entry; 423179187Sjb uint64_t form; 424179187Sjb uint64_t offset; 425179187Sjb uint64_t tag; 426179187Sjb u_int8_t children; 427179187Sjb 428179187Sjb d = dbg->dbg_s[DWARF_debug_abbrev].s_data; 429179187Sjb 430179187Sjb offset = cu->cu_abbrev_offset; 431179187Sjb 432179187Sjb while (offset < d->d_size) { 433179187Sjb 434179187Sjb entry = dwarf_read_uleb128(&d, &offset); 435179187Sjb 436179187Sjb /* Check if this is the end of the data: */ 437179187Sjb if (entry == 0) 438179187Sjb break; 439179187Sjb 440179187Sjb tag = dwarf_read_uleb128(&d, &offset); 441179187Sjb 442179187Sjb children = dwarf_read(&d, &offset, 1); 443179187Sjb 444179187Sjb if ((ret = dwarf_abbrev_add(cu, entry, tag, children, &a, error)) != DWARF_E_NONE) 445179187Sjb break; 446179187Sjb 447179187Sjb do { 448179187Sjb attr = dwarf_read_uleb128(&d, &offset); 449179187Sjb form = dwarf_read_uleb128(&d, &offset); 450179187Sjb 451179187Sjb if (attr != 0) 452179187Sjb if ((ret = dwarf_attr_add(a, attr, form, NULL, error)) != DWARF_E_NONE) 453179187Sjb return ret; 454179187Sjb } while (attr != 0); 455179187Sjb } 456179187Sjb 457179187Sjb return ret; 458179187Sjb} 459179187Sjb 460179187Sjbstatic int 461179187Sjbdwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error) 462179187Sjb{ 463179187Sjb Dwarf_CU cu; 464179187Sjb Elf_Data *d = NULL; 465179187Sjb Elf_Scn *scn; 466179187Sjb int i; 467179187Sjb int level = 0; 468179187Sjb int relocated = 0; 469179187Sjb int ret = DWARF_E_NONE; 470179187Sjb uint64_t length; 471179187Sjb uint64_t next_offset; 472179187Sjb uint64_t offset = 0; 473179187Sjb 474179187Sjb scn = dbg->dbg_s[DWARF_debug_info].s_scn; 475179187Sjb 476179187Sjb d = dbg->dbg_s[DWARF_debug_info].s_data; 477179187Sjb 478179187Sjb while (offset < d->d_size) { 479179187Sjb /* Allocate memory for the first compilation unit. */ 480179187Sjb if ((cu = calloc(sizeof(struct _Dwarf_CU), 1)) == NULL) { 481179187Sjb DWARF_SET_ERROR(error, DWARF_E_MEMORY); 482179187Sjb return DWARF_E_MEMORY; 483179187Sjb } 484179187Sjb 485179187Sjb /* Save the offet to this compilation unit: */ 486179187Sjb cu->cu_offset = offset; 487179187Sjb 488179187Sjb length = dwarf_read(&d, &offset, 4); 489179187Sjb if (length == 0xffffffff) { 490179187Sjb length = dwarf_read(&d, &offset, 8); 491179187Sjb dbg->dbg_offsize = 8; 492179187Sjb } else 493179187Sjb dbg->dbg_offsize = 4; 494179187Sjb 495179187Sjb /* 496179187Sjb * Check if there is enough ELF data for this CU. 497179187Sjb * This assumes that libelf gives us the entire 498179187Sjb * section in one Elf_Data object. 499179187Sjb */ 500179187Sjb if (length > d->d_size - offset) { 501179187Sjb free(cu); 502179187Sjb DWARF_SET_ERROR(error, DWARF_E_INVALID_CU); 503179187Sjb return DWARF_E_INVALID_CU; 504179187Sjb } 505179187Sjb 506179187Sjb /* Relocate the DWARF sections if necessary: */ 507179187Sjb if (!relocated) { 508179187Sjb if ((ret = dwarf_relocate(dbg, error)) != DWARF_E_NONE) 509179187Sjb return ret; 510179187Sjb relocated = 1; 511179187Sjb } 512179187Sjb 513179187Sjb /* Compute the offset to the next compilation unit: */ 514179187Sjb next_offset = offset + length; 515179187Sjb 516179187Sjb /* Initialise the compilation unit. */ 517179187Sjb cu->cu_length = length; 518179187Sjb cu->cu_header_length = (dbg->dbg_offsize == 4) ? 4 : 12; 519179187Sjb cu->cu_version = dwarf_read(&d, &offset, 2); 520179187Sjb cu->cu_abbrev_offset = dwarf_read(&d, &offset, dbg->dbg_offsize); 521179187Sjb cu->cu_pointer_size = dwarf_read(&d, &offset, 1); 522179187Sjb cu->cu_next_offset = next_offset; 523179187Sjb 524179187Sjb /* Initialise the list of abbrevs. */ 525179187Sjb STAILQ_INIT(&cu->cu_abbrev); 526179187Sjb 527179187Sjb /* Initialise the list of dies. */ 528179187Sjb STAILQ_INIT(&cu->cu_die); 529179187Sjb 530179187Sjb /* Initialise the hash table of dies. */ 531179187Sjb for (i = 0; i < DWARF_DIE_HASH_SIZE; i++) 532179187Sjb STAILQ_INIT(&cu->cu_die_hash[i]); 533179187Sjb 534179187Sjb /* Add the compilation unit to the list. */ 535179187Sjb STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); 536179187Sjb 537179187Sjb if (cu->cu_version != 2 && cu->cu_version != 3) { 538179187Sjb DWARF_SET_ERROR(error, DWARF_E_CU_VERSION); 539179187Sjb ret = DWARF_E_CU_VERSION; 540179187Sjb break; 541179187Sjb } 542179187Sjb 543179187Sjb /* Parse the .debug_abbrev info for this CU: */ 544179187Sjb if ((ret = dwarf_init_abbrev(dbg, cu, error)) != DWARF_E_NONE) 545179187Sjb break; 546179187Sjb 547179187Sjb level = 0; 548179187Sjb 549179187Sjb while (offset < next_offset && offset < d->d_size) { 550179187Sjb Dwarf_Abbrev a; 551179187Sjb Dwarf_Attribute at; 552179187Sjb Dwarf_Die die; 553179187Sjb uint64_t abnum; 554241844Seadler uint64_t die_offset = offset; 555179187Sjb 556179187Sjb abnum = dwarf_read_uleb128(&d, &offset); 557179187Sjb 558179187Sjb if (abnum == 0) { 559179187Sjb level--; 560179187Sjb continue; 561179187Sjb } 562179187Sjb 563179187Sjb if ((a = dwarf_abbrev_find(cu, abnum)) == NULL) { 564179187Sjb DWARF_SET_ERROR(error, DWARF_E_MISSING_ABBREV); 565179187Sjb return DWARF_E_MISSING_ABBREV; 566179187Sjb } 567179187Sjb 568179187Sjb if ((ret = dwarf_die_add(cu, level, die_offset, 569179187Sjb abnum, a, &die, error)) != DWARF_E_NONE) 570179187Sjb return ret; 571179187Sjb 572179187Sjb STAILQ_FOREACH(at, &a->a_attrib, at_next) { 573179187Sjb if ((ret = dwarf_init_attr(dbg, &d, &offset, 574179187Sjb cu, die, at, at->at_form, error)) != DWARF_E_NONE) 575179187Sjb return ret; 576179187Sjb } 577179187Sjb 578179187Sjb if (a->a_children == DW_CHILDREN_yes) 579179187Sjb level++; 580179187Sjb } 581179187Sjb 582179187Sjb offset = next_offset; 583179187Sjb } 584179187Sjb 585221569Sobrien /* Build the function table. */ 586221569Sobrien dwarf_build_function_table(dbg); 587221569Sobrien 588179187Sjb return ret; 589179187Sjb} 590179187Sjb 591179187Sjbstatic int 592179187Sjbdwarf_elf_read(Dwarf_Debug dbg, Dwarf_Error *error) 593179187Sjb{ 594179187Sjb GElf_Shdr shdr; 595179187Sjb Elf_Scn *scn = NULL; 596179187Sjb char *sname; 597179187Sjb int i; 598179187Sjb int ret = DWARF_E_NONE; 599179187Sjb 600179187Sjb /* Get a copy of the ELF header. */ 601179187Sjb if (gelf_getehdr(dbg->dbg_elf, &dbg->dbg_ehdr) == NULL) { 602179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 603179187Sjb return DWARF_E_ELF; 604179187Sjb } 605179187Sjb 606179187Sjb /* Check the ELF data format: */ 607179187Sjb switch (dbg->dbg_ehdr.e_ident[EI_DATA]) { 608179187Sjb case ELFDATA2MSB: 609179187Sjb dwarf_read = dwarf_read_msb; 610179187Sjb dwarf_write = dwarf_write_msb; 611179187Sjb break; 612179187Sjb 613179187Sjb case ELFDATA2LSB: 614179187Sjb case ELFDATANONE: 615179187Sjb default: 616179187Sjb dwarf_read = dwarf_read_lsb; 617179187Sjb dwarf_write = dwarf_write_lsb; 618179187Sjb break; 619179187Sjb } 620179187Sjb 621179187Sjb /* Get the section index to the string table. */ 622179187Sjb if (elf_getshstrndx(dbg->dbg_elf, &dbg->dbg_stnum) == 0) { 623179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 624179187Sjb return DWARF_E_ELF; 625179187Sjb } 626179187Sjb 627179187Sjb /* Look for the debug sections. */ 628179187Sjb while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) { 629179187Sjb /* Get a copy of the section header: */ 630179187Sjb if (gelf_getshdr(scn, &shdr) == NULL) { 631179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 632179187Sjb return DWARF_E_ELF; 633179187Sjb } 634179187Sjb 635179187Sjb /* Get a pointer to the section name: */ 636179187Sjb if ((sname = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, shdr.sh_name)) == NULL) { 637179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 638179187Sjb return DWARF_E_ELF; 639179187Sjb } 640179187Sjb 641179187Sjb /* 642179187Sjb * Look up the section name to check if it's 643179187Sjb * one we need for DWARF. 644179187Sjb */ 645179187Sjb for (i = 0; i < DWARF_DEBUG_SNAMES; i++) { 646179187Sjb if (strcmp(sname, debug_snames[i]) == 0) { 647179187Sjb dbg->dbg_s[i].s_sname = sname; 648179187Sjb dbg->dbg_s[i].s_shnum = elf_ndxscn(scn); 649179187Sjb dbg->dbg_s[i].s_scn = scn; 650179187Sjb memcpy(&dbg->dbg_s[i].s_shdr, &shdr, sizeof(shdr)); 651179187Sjb if ((dbg->dbg_s[i].s_data = elf_getdata(scn, NULL)) == NULL) { 652179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 653179187Sjb return DWARF_E_ELF; 654179187Sjb } 655179187Sjb break; 656179187Sjb } 657179187Sjb } 658179187Sjb } 659179187Sjb 660179187Sjb /* Check if any of the required sections are missing: */ 661179187Sjb if (dbg->dbg_s[DWARF_debug_abbrev].s_scn == NULL || 662179187Sjb dbg->dbg_s[DWARF_debug_info].s_scn == NULL) { 663179187Sjb /* Missing debug information. */ 664179187Sjb DWARF_SET_ERROR(error, DWARF_E_DEBUG_INFO); 665179187Sjb return DWARF_E_DEBUG_INFO; 666179187Sjb } 667179187Sjb 668179187Sjb /* Initialise the compilation-units: */ 669179187Sjb ret = dwarf_init_info(dbg, error); 670179187Sjb 671179187Sjb return ret; 672179187Sjb} 673179187Sjb 674179187Sjbint 675179187Sjbdwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error) 676179187Sjb{ 677179187Sjb Dwarf_Debug dbg; 678179187Sjb int ret = DWARF_E_NONE; 679179187Sjb 680179187Sjb if (error == NULL) 681179187Sjb /* Can only return a generic error. */ 682179187Sjb return DWARF_E_ERROR; 683179187Sjb 684179187Sjb if (elf == NULL || ret_dbg == NULL) { 685179187Sjb DWARF_SET_ERROR(error, DWARF_E_ARGUMENT); 686179187Sjb ret = DWARF_E_ARGUMENT; 687179187Sjb } else if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { 688179187Sjb DWARF_SET_ERROR(error, DWARF_E_MEMORY); 689179187Sjb ret = DWARF_E_MEMORY; 690179187Sjb } else { 691179187Sjb dbg->dbg_elf = elf; 692179187Sjb dbg->dbg_elf_close = 0; 693179187Sjb dbg->dbg_mode = mode; 694179187Sjb 695179187Sjb STAILQ_INIT(&dbg->dbg_cu); 696221569Sobrien STAILQ_INIT(&dbg->dbg_func); 697179187Sjb 698179187Sjb *ret_dbg = dbg; 699179187Sjb 700179187Sjb /* Read the ELF sections. */ 701179187Sjb ret = dwarf_elf_read(dbg, error); 702179187Sjb } 703179187Sjb 704179187Sjb return ret; 705179187Sjb} 706179187Sjb 707179187Sjbint 708179187Sjbdwarf_init(int fd, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error) 709179187Sjb{ 710179187Sjb Dwarf_Error lerror; 711179187Sjb Elf *elf; 712179187Sjb Elf_Cmd c; 713179187Sjb int ret; 714179187Sjb 715179187Sjb if (error == NULL) 716179187Sjb /* Can only return a generic error. */ 717179187Sjb return DWARF_E_ERROR; 718179187Sjb 719179187Sjb if (fd < 0 || ret_dbg == NULL) { 720179187Sjb DWARF_SET_ERROR(error, DWARF_E_ARGUMENT); 721179187Sjb return DWARF_E_ERROR; 722179187Sjb } 723179187Sjb 724179187Sjb /* Translate the DWARF mode to ELF mode. */ 725179187Sjb switch (mode) { 726179187Sjb default: 727179187Sjb case DW_DLC_READ: 728179187Sjb c = ELF_C_READ; 729179187Sjb break; 730179187Sjb } 731179187Sjb 732179187Sjb if (elf_version(EV_CURRENT) == EV_NONE) { 733179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 734179187Sjb return DWARF_E_ERROR; 735179187Sjb } 736179187Sjb 737179187Sjb if ((elf = elf_begin(fd, c, NULL)) == NULL) { 738179187Sjb DWARF_SET_ELF_ERROR(error, elf_errno()); 739179187Sjb return DWARF_E_ERROR; 740179187Sjb } 741179187Sjb 742179187Sjb ret = dwarf_elf_init(elf, mode, ret_dbg, error); 743179187Sjb 744179187Sjb if (*ret_dbg != NULL) 745179187Sjb /* Remember to close the ELF file. */ 746179187Sjb (*ret_dbg)->dbg_elf_close = 1; 747179187Sjb 748179187Sjb if (ret != DWARF_E_NONE) { 749179187Sjb if (*ret_dbg != NULL) { 750179187Sjb dwarf_finish(ret_dbg, &lerror); 751179187Sjb } else 752179187Sjb elf_end(elf); 753179187Sjb } 754179187Sjb 755179187Sjb return ret; 756179187Sjb} 757