dwarf_init.c revision 179187
1/*- 2 * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/lib/libdwarf/dwarf_init.c 179187 2008-05-22 02:14:23Z jb $ 27 */ 28 29#include <stdlib.h> 30#include <string.h> 31#include "_libdwarf.h" 32 33static const char *debug_snames[DWARF_DEBUG_SNAMES] = { 34 ".debug_abbrev", 35 ".debug_aranges", 36 ".debug_frame", 37 ".debug_info", 38 ".debug_line", 39 ".debug_pubnames", 40 ".eh_frame", 41 ".debug_macinfo", 42 ".debug_str", 43 ".debug_loc", 44 ".debug_pubtypes", 45 ".debug_ranges", 46 ".debug_static_func", 47 ".debug_static_vars", 48 ".debug_types", 49 ".debug_weaknames", 50 ".symtab", 51 ".strtab" 52}; 53 54static uint64_t (*dwarf_read) (Elf_Data **, uint64_t *, int); 55static void (*dwarf_write) (Elf_Data **, uint64_t *, uint64_t, int); 56 57static uint64_t 58dwarf_read_lsb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read) 59{ 60 uint64_t ret = 0; 61 62 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; 63 64 switch (bytes_to_read) { 65 case 8: 66 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; 67 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; 68 case 4: 69 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; 70 case 2: 71 ret |= ((uint64_t) src[1]) << 8; 72 case 1: 73 ret |= src[0]; 74 break; 75 default: 76 return 0; 77 break; 78 } 79 80 *offsetp += bytes_to_read; 81 82 return ret; 83} 84 85static uint64_t 86dwarf_read_msb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read) 87{ 88 uint64_t ret = 0; 89 90 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; 91 92 switch (bytes_to_read) { 93 case 1: 94 ret = src[0]; 95 break; 96 case 2: 97 ret = src[1] | ((uint64_t) src[0]) << 8; 98 break; 99 case 4: 100 ret = src[3] | ((uint64_t) src[2]) << 8; 101 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; 102 break; 103 case 8: 104 ret = src[7] | ((uint64_t) src[6]) << 8; 105 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; 106 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; 107 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; 108 break; 109 default: 110 return 0; 111 break; 112 } 113 114 *offsetp += bytes_to_read; 115 116 return ret; 117} 118 119static void 120dwarf_write_lsb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write) 121{ 122 uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp; 123 124 switch (bytes_to_write) { 125 case 8: 126 dst[7] = (value >> 56) & 0xff; 127 dst[6] = (value >> 48) & 0xff; 128 dst[5] = (value >> 40) & 0xff; 129 dst[4] = (value >> 32) & 0xff; 130 case 4: 131 dst[3] = (value >> 24) & 0xff; 132 dst[2] = (value >> 16) & 0xff; 133 case 2: 134 dst[1] = (value >> 8) & 0xff; 135 case 1: 136 dst[0] = value & 0xff; 137 break; 138 default: 139 return; 140 break; 141 } 142 143 *offsetp += bytes_to_write; 144} 145 146static void 147dwarf_write_msb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write) 148{ 149 uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp; 150 151 switch (bytes_to_write) { 152 case 8: 153 dst[7] = value & 0xff; 154 dst[6] = (value >> 8) & 0xff; 155 dst[5] = (value >> 16) & 0xff; 156 dst[4] = (value >> 24) & 0xff; 157 value >>= 32; 158 case 4: 159 dst[3] = value & 0xff; 160 dst[2] = (value >> 8) & 0xff; 161 value >>= 16; 162 case 2: 163 dst[1] = value & 0xff; 164 value >>= 8; 165 case 1: 166 dst[0] = value & 0xff; 167 break; 168 default: 169 return; 170 break; 171 } 172 173 *offsetp += bytes_to_write; 174} 175 176static int64_t 177dwarf_read_sleb128(Elf_Data **dp, uint64_t *offsetp) 178{ 179 int64_t ret = 0; 180 uint8_t b; 181 int shift = 0; 182 183 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; 184 185 do { 186 b = *src++; 187 188 ret |= ((b & 0x7f) << shift); 189 190 (*offsetp)++; 191 192 shift += 7; 193 } while ((b & 0x80) != 0); 194 195 if (shift < 32 && (b & 0x40) != 0) 196 ret |= (-1 << shift); 197 198 return ret; 199} 200 201static uint64_t 202dwarf_read_uleb128(Elf_Data **dp, uint64_t *offsetp) 203{ 204 uint64_t ret = 0; 205 uint8_t b; 206 int shift = 0; 207 208 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; 209 210 do { 211 b = *src++; 212 213 ret |= ((b & 0x7f) << shift); 214 215 (*offsetp)++; 216 217 shift += 7; 218 } while ((b & 0x80) != 0); 219 220 return ret; 221} 222 223static const char * 224dwarf_read_string(Elf_Data **dp, uint64_t *offsetp) 225{ 226 char *ret; 227 228 char *src = (char *) (*dp)->d_buf + *offsetp; 229 230 ret = src; 231 232 while (*src != '\0' && *offsetp < (*dp)->d_size) { 233 src++; 234 (*offsetp)++; 235 } 236 237 if (*src == '\0' && *offsetp < (*dp)->d_size) 238 (*offsetp)++; 239 240 return ret; 241} 242 243static uint8_t * 244dwarf_read_block(Elf_Data **dp, uint64_t *offsetp, uint64_t length) 245{ 246 uint8_t *ret; 247 248 uint8_t *src = (char *) (*dp)->d_buf + *offsetp; 249 250 ret = src; 251 252 (*offsetp) += length; 253 254 return ret; 255} 256 257static int 258dwarf_apply_relocations(Dwarf_Debug dbg, Elf_Data *reld, int secindx) 259{ 260 Elf_Data *d; 261 GElf_Rela rela; 262 int indx = 0; 263 int ret = DWARF_E_NONE; 264 uint64_t offset; 265 266 /* Point to the data to be relocated: */ 267 d = dbg->dbg_s[secindx].s_data; 268 269 /* Enter a loop to process each relocation addend: */ 270 while (gelf_getrela(reld, indx++, &rela) != NULL) { 271 GElf_Sym sym; 272 Elf64_Xword symindx = ELF64_R_SYM(rela.r_info); 273 274 if (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, symindx, &sym) == NULL) { 275 printf("Couldn't find symbol index %lu for relocation\n",(u_long) symindx); 276 continue; 277 } 278 279 offset = rela.r_offset; 280 281 dwarf_write(&d, &offset, rela.r_addend, dbg->dbg_offsize); 282 } 283 284 return ret; 285} 286 287static int 288dwarf_relocate(Dwarf_Debug dbg, Dwarf_Error *error) 289{ 290 Elf_Scn *scn = NULL; 291 GElf_Shdr shdr; 292 int i; 293 int ret = DWARF_E_NONE; 294 295 /* Look for sections which relocate the debug sections. */ 296 while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) { 297 if (gelf_getshdr(scn, &shdr) == NULL) { 298 DWARF_SET_ELF_ERROR(error, elf_errno()); 299 return DWARF_E_ELF; 300 } 301 302 if (shdr.sh_type != SHT_RELA || shdr.sh_size == 0) 303 continue; 304 305 for (i = 0; i < DWARF_DEBUG_SNAMES; i++) { 306 if (dbg->dbg_s[i].s_shnum == shdr.sh_info && 307 dbg->dbg_s[DWARF_symtab].s_shnum == shdr.sh_link) { 308 Elf_Data *rd; 309 310 /* Get the relocation data. */ 311 if ((rd = elf_getdata(scn, NULL)) == NULL) { 312 DWARF_SET_ELF_ERROR(error, elf_errno()); 313 return DWARF_E_ELF; 314 } 315 316 /* Apply the relocations. */ 317 dwarf_apply_relocations(dbg, rd, i); 318 break; 319 } 320 } 321 } 322 323 return ret; 324} 325 326static int 327dwarf_init_attr(Dwarf_Debug dbg, Elf_Data **dp, uint64_t *offsetp, 328 Dwarf_CU cu, Dwarf_Die die, Dwarf_Attribute at, uint64_t form, 329 Dwarf_Error *error) 330{ 331 int ret = DWARF_E_NONE; 332 struct _Dwarf_AttrValue avref; 333 334 memset(&avref, 0, sizeof(avref)); 335 avref.av_attrib = at->at_attrib; 336 avref.av_form = at->at_form; 337 338 switch (form) { 339 case DW_FORM_addr: 340 avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size); 341 break; 342 case DW_FORM_block: 343 avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp); 344 avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); 345 break; 346 case DW_FORM_block1: 347 avref.u[0].u64 = dwarf_read(dp, offsetp, 1); 348 avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); 349 break; 350 case DW_FORM_block2: 351 avref.u[0].u64 = dwarf_read(dp, offsetp, 2); 352 avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); 353 break; 354 case DW_FORM_block4: 355 avref.u[0].u64 = dwarf_read(dp, offsetp, 4); 356 avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); 357 break; 358 case DW_FORM_data1: 359 case DW_FORM_flag: 360 case DW_FORM_ref1: 361 avref.u[0].u64 = dwarf_read(dp, offsetp, 1); 362 break; 363 case DW_FORM_data2: 364 case DW_FORM_ref2: 365 avref.u[0].u64 = dwarf_read(dp, offsetp, 2); 366 break; 367 case DW_FORM_data4: 368 case DW_FORM_ref4: 369 avref.u[0].u64 = dwarf_read(dp, offsetp, 4); 370 break; 371 case DW_FORM_data8: 372 case DW_FORM_ref8: 373 avref.u[0].u64 = dwarf_read(dp, offsetp, 8); 374 break; 375 case DW_FORM_indirect: 376 form = dwarf_read_uleb128(dp, offsetp); 377 return dwarf_init_attr(dbg, dp, offsetp, cu, die, at, form, error); 378 case DW_FORM_ref_addr: 379 if (cu->cu_version == 2) 380 avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size); 381 else if (cu->cu_version == 3) 382 avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize); 383 break; 384 case DW_FORM_ref_udata: 385 case DW_FORM_udata: 386 avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp); 387 break; 388 case DW_FORM_sdata: 389 avref.u[0].s64 = dwarf_read_sleb128(dp, offsetp); 390 break; 391 case DW_FORM_string: 392 avref.u[0].s = dwarf_read_string(dp, offsetp); 393 break; 394 case DW_FORM_strp: 395 avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize); 396 avref.u[1].s = elf_strptr(dbg->dbg_elf, 397 dbg->dbg_s[DWARF_debug_str].s_shnum, avref.u[0].u64); 398 break; 399 default: 400 DWARF_SET_ERROR(error, DWARF_E_NOT_IMPLEMENTED); 401 ret = DWARF_E_NOT_IMPLEMENTED; 402 break; 403 } 404 405 if (ret == DWARF_E_NONE) 406 ret = dwarf_attrval_add(die, &avref, NULL, error); 407 408 return ret; 409} 410 411static int 412dwarf_init_abbrev(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Error *error) 413{ 414 Dwarf_Abbrev a; 415 Elf_Data *d; 416 int ret = DWARF_E_NONE; 417 uint64_t attr; 418 uint64_t entry; 419 uint64_t form; 420 uint64_t offset; 421 uint64_t tag; 422 u_int8_t children; 423 424 d = dbg->dbg_s[DWARF_debug_abbrev].s_data; 425 426 offset = cu->cu_abbrev_offset; 427 428 while (offset < d->d_size) { 429 430 entry = dwarf_read_uleb128(&d, &offset); 431 432 /* Check if this is the end of the data: */ 433 if (entry == 0) 434 break; 435 436 tag = dwarf_read_uleb128(&d, &offset); 437 438 children = dwarf_read(&d, &offset, 1); 439 440 if ((ret = dwarf_abbrev_add(cu, entry, tag, children, &a, error)) != DWARF_E_NONE) 441 break; 442 443 do { 444 attr = dwarf_read_uleb128(&d, &offset); 445 form = dwarf_read_uleb128(&d, &offset); 446 447 if (attr != 0) 448 if ((ret = dwarf_attr_add(a, attr, form, NULL, error)) != DWARF_E_NONE) 449 return ret; 450 } while (attr != 0); 451 } 452 453 return ret; 454} 455 456static int 457dwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error) 458{ 459 Dwarf_CU cu; 460 Elf_Data *d = NULL; 461 Elf_Scn *scn; 462 int i; 463 int level = 0; 464 int relocated = 0; 465 int ret = DWARF_E_NONE; 466 uint64_t length; 467 uint64_t next_offset; 468 uint64_t offset = 0; 469 470 scn = dbg->dbg_s[DWARF_debug_info].s_scn; 471 472 d = dbg->dbg_s[DWARF_debug_info].s_data; 473 474 while (offset < d->d_size) { 475 /* Allocate memory for the first compilation unit. */ 476 if ((cu = calloc(sizeof(struct _Dwarf_CU), 1)) == NULL) { 477 DWARF_SET_ERROR(error, DWARF_E_MEMORY); 478 return DWARF_E_MEMORY; 479 } 480 481 /* Save the offet to this compilation unit: */ 482 cu->cu_offset = offset; 483 484 length = dwarf_read(&d, &offset, 4); 485 if (length == 0xffffffff) { 486 length = dwarf_read(&d, &offset, 8); 487 dbg->dbg_offsize = 8; 488 } else 489 dbg->dbg_offsize = 4; 490 491 /* 492 * Check if there is enough ELF data for this CU. 493 * This assumes that libelf gives us the entire 494 * section in one Elf_Data object. 495 */ 496 if (length > d->d_size - offset) { 497 free(cu); 498 DWARF_SET_ERROR(error, DWARF_E_INVALID_CU); 499 return DWARF_E_INVALID_CU; 500 } 501 502 /* Relocate the DWARF sections if necessary: */ 503 if (!relocated) { 504 if ((ret = dwarf_relocate(dbg, error)) != DWARF_E_NONE) 505 return ret; 506 relocated = 1; 507 } 508 509 /* Compute the offset to the next compilation unit: */ 510 next_offset = offset + length; 511 512 /* Initialise the compilation unit. */ 513 cu->cu_length = length; 514 cu->cu_header_length = (dbg->dbg_offsize == 4) ? 4 : 12; 515 cu->cu_version = dwarf_read(&d, &offset, 2); 516 cu->cu_abbrev_offset = dwarf_read(&d, &offset, dbg->dbg_offsize); 517 cu->cu_pointer_size = dwarf_read(&d, &offset, 1); 518 cu->cu_next_offset = next_offset; 519 520 /* Initialise the list of abbrevs. */ 521 STAILQ_INIT(&cu->cu_abbrev); 522 523 /* Initialise the list of dies. */ 524 STAILQ_INIT(&cu->cu_die); 525 526 /* Initialise the hash table of dies. */ 527 for (i = 0; i < DWARF_DIE_HASH_SIZE; i++) 528 STAILQ_INIT(&cu->cu_die_hash[i]); 529 530 /* Add the compilation unit to the list. */ 531 STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); 532 533 if (cu->cu_version != 2 && cu->cu_version != 3) { 534 DWARF_SET_ERROR(error, DWARF_E_CU_VERSION); 535 ret = DWARF_E_CU_VERSION; 536 break; 537 } 538 539 /* Parse the .debug_abbrev info for this CU: */ 540 if ((ret = dwarf_init_abbrev(dbg, cu, error)) != DWARF_E_NONE) 541 break; 542 543 level = 0; 544 545 while (offset < next_offset && offset < d->d_size) { 546 Dwarf_Abbrev a; 547 Dwarf_Attribute at; 548 Dwarf_Die die; 549 uint64_t abnum; 550 uint64_t die_offset = offset;; 551 552 abnum = dwarf_read_uleb128(&d, &offset); 553 554 if (abnum == 0) { 555 level--; 556 continue; 557 } 558 559 if ((a = dwarf_abbrev_find(cu, abnum)) == NULL) { 560 DWARF_SET_ERROR(error, DWARF_E_MISSING_ABBREV); 561 return DWARF_E_MISSING_ABBREV; 562 } 563 564 if ((ret = dwarf_die_add(cu, level, die_offset, 565 abnum, a, &die, error)) != DWARF_E_NONE) 566 return ret; 567 568 STAILQ_FOREACH(at, &a->a_attrib, at_next) { 569 if ((ret = dwarf_init_attr(dbg, &d, &offset, 570 cu, die, at, at->at_form, error)) != DWARF_E_NONE) 571 return ret; 572 } 573 574 if (a->a_children == DW_CHILDREN_yes) 575 level++; 576 } 577 578 offset = next_offset; 579 } 580 581 return ret; 582} 583 584static int 585dwarf_elf_read(Dwarf_Debug dbg, Dwarf_Error *error) 586{ 587 GElf_Shdr shdr; 588 Elf_Scn *scn = NULL; 589 char *sname; 590 int i; 591 int ret = DWARF_E_NONE; 592 593 /* Get a copy of the ELF header. */ 594 if (gelf_getehdr(dbg->dbg_elf, &dbg->dbg_ehdr) == NULL) { 595 DWARF_SET_ELF_ERROR(error, elf_errno()); 596 return DWARF_E_ELF; 597 } 598 599 /* Check the ELF data format: */ 600 switch (dbg->dbg_ehdr.e_ident[EI_DATA]) { 601 case ELFDATA2MSB: 602 dwarf_read = dwarf_read_msb; 603 dwarf_write = dwarf_write_msb; 604 break; 605 606 case ELFDATA2LSB: 607 case ELFDATANONE: 608 default: 609 dwarf_read = dwarf_read_lsb; 610 dwarf_write = dwarf_write_lsb; 611 break; 612 } 613 614 /* Get the section index to the string table. */ 615 if (elf_getshstrndx(dbg->dbg_elf, &dbg->dbg_stnum) == 0) { 616 DWARF_SET_ELF_ERROR(error, elf_errno()); 617 return DWARF_E_ELF; 618 } 619 620 /* Look for the debug sections. */ 621 while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) { 622 /* Get a copy of the section header: */ 623 if (gelf_getshdr(scn, &shdr) == NULL) { 624 DWARF_SET_ELF_ERROR(error, elf_errno()); 625 return DWARF_E_ELF; 626 } 627 628 /* Get a pointer to the section name: */ 629 if ((sname = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, shdr.sh_name)) == NULL) { 630 DWARF_SET_ELF_ERROR(error, elf_errno()); 631 return DWARF_E_ELF; 632 } 633 634 /* 635 * Look up the section name to check if it's 636 * one we need for DWARF. 637 */ 638 for (i = 0; i < DWARF_DEBUG_SNAMES; i++) { 639 if (strcmp(sname, debug_snames[i]) == 0) { 640 dbg->dbg_s[i].s_sname = sname; 641 dbg->dbg_s[i].s_shnum = elf_ndxscn(scn); 642 dbg->dbg_s[i].s_scn = scn; 643 memcpy(&dbg->dbg_s[i].s_shdr, &shdr, sizeof(shdr)); 644 if ((dbg->dbg_s[i].s_data = elf_getdata(scn, NULL)) == NULL) { 645 DWARF_SET_ELF_ERROR(error, elf_errno()); 646 return DWARF_E_ELF; 647 } 648 break; 649 } 650 } 651 } 652 653 /* Check if any of the required sections are missing: */ 654 if (dbg->dbg_s[DWARF_debug_abbrev].s_scn == NULL || 655 dbg->dbg_s[DWARF_debug_info].s_scn == NULL) { 656 /* Missing debug information. */ 657 DWARF_SET_ERROR(error, DWARF_E_DEBUG_INFO); 658 return DWARF_E_DEBUG_INFO; 659 } 660 661 /* Initialise the compilation-units: */ 662 ret = dwarf_init_info(dbg, error); 663 664 return ret; 665} 666 667int 668dwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error) 669{ 670 Dwarf_Debug dbg; 671 int ret = DWARF_E_NONE; 672 673 if (error == NULL) 674 /* Can only return a generic error. */ 675 return DWARF_E_ERROR; 676 677 if (elf == NULL || ret_dbg == NULL) { 678 DWARF_SET_ERROR(error, DWARF_E_ARGUMENT); 679 ret = DWARF_E_ARGUMENT; 680 } else if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { 681 DWARF_SET_ERROR(error, DWARF_E_MEMORY); 682 ret = DWARF_E_MEMORY; 683 } else { 684 dbg->dbg_elf = elf; 685 dbg->dbg_elf_close = 0; 686 dbg->dbg_mode = mode; 687 688 STAILQ_INIT(&dbg->dbg_cu); 689 690 *ret_dbg = dbg; 691 692 /* Read the ELF sections. */ 693 ret = dwarf_elf_read(dbg, error); 694 } 695 696 return ret; 697} 698 699int 700dwarf_init(int fd, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error) 701{ 702 Dwarf_Error lerror; 703 Elf *elf; 704 Elf_Cmd c; 705 int ret; 706 707 if (error == NULL) 708 /* Can only return a generic error. */ 709 return DWARF_E_ERROR; 710 711 if (fd < 0 || ret_dbg == NULL) { 712 DWARF_SET_ERROR(error, DWARF_E_ARGUMENT); 713 return DWARF_E_ERROR; 714 } 715 716 /* Translate the DWARF mode to ELF mode. */ 717 switch (mode) { 718 default: 719 case DW_DLC_READ: 720 c = ELF_C_READ; 721 break; 722 } 723 724 if (elf_version(EV_CURRENT) == EV_NONE) { 725 DWARF_SET_ELF_ERROR(error, elf_errno()); 726 return DWARF_E_ERROR; 727 } 728 729 if ((elf = elf_begin(fd, c, NULL)) == NULL) { 730 DWARF_SET_ELF_ERROR(error, elf_errno()); 731 return DWARF_E_ERROR; 732 } 733 734 ret = dwarf_elf_init(elf, mode, ret_dbg, error); 735 736 if (*ret_dbg != NULL) 737 /* Remember to close the ELF file. */ 738 (*ret_dbg)->dbg_elf_close = 1; 739 740 if (ret != DWARF_E_NONE) { 741 if (*ret_dbg != NULL) { 742 dwarf_finish(ret_dbg, &lerror); 743 } else 744 elf_end(elf); 745 } 746 747 return ret; 748} 749