1 /* 2 Copyright (c) 2019, David Anderson 3 All rights reserved. 4 cc 5 Redistribution and use in source and binary forms, with 6 or without modification, are permitted provided that the 7 following conditions are met: 8 9 Redistributions of source code must retain the above 10 copyright notice, this list of conditions and the following 11 disclaimer. 12 13 Redistributions in binary form must reproduce the above 14 copyright notice, this list of conditions and the following 15 disclaimer in the documentation and/or other materials 16 provided with the distribution. 17 18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 19 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* This file reads the parts of an Elf 34 file appropriate to reading DWARF debugging data. 35 Overview: 36 _dwarf_elf_nlsetup() Does all elf setup. 37 calls _dwarf_elf_access_init() 38 calls _dwarf_elf_object_access_internals_init() 39 Creates internals record 'M', 40 dwarf_elf_object_access_internals_t 41 Sets flags/data in internals record 42 Loads elf object data needed later. 43 Sets methods struct to access elf object. 44 calls _dwarf_object_init_b() Creates Dwarf_Debug, independent 45 of any elf code. 46 Sets internals record into dbg. 47 ---------------------- 48 _dwarf_destruct_elf_nlaccess(). This frees 49 the elf internals record created in 50 _dwarf_elf_object_access_internals_init() 51 in case of errors during setup or when 52 dwarf_finish() is called. Works safely for 53 partially or fully set-up elf internals record. 54 55 Other than in _dwarf_elf_nlsetup() the elf code 56 knows nothing about Dwarf_Debug, and the rest of 57 libdwarf knows nothing about the content of the 58 object-type-specific (for Elf here) 59 internals record. 60 */ 61 62 #include "config.h" 63 #include <stdio.h> 64 #ifdef HAVE_MALLOC_H 65 /* Useful include for some Windows compilers. */ 66 #include <malloc.h> 67 #endif /* HAVE_MALLOC_H */ 68 #ifdef HAVE_STDLIB_H 69 #include <stdlib.h> 70 #endif /* HAVE_STDLIB_H */ 71 #include <string.h> 72 #include <stdlib.h> 73 #include <sys/types.h> /* open() */ 74 #include <sys/stat.h> /* open() */ 75 #include <fcntl.h> /* open() */ 76 #include <time.h> 77 #ifdef HAVE_UNISTD_H 78 #include <unistd.h> /* lseek read close */ 79 #elif defined(_WIN32) && defined(_MSC_VER) 80 #include <io.h> 81 #endif /* HAVE_UNISTD_H */ 82 83 /* Windows specific header files */ 84 #if defined(_WIN32) && defined(HAVE_STDAFX_H) 85 #include "stdafx.h" 86 #endif /* HAVE_STDAFX_H */ 87 88 #include "libdwarf.h" 89 #include "libdwarfdefs.h" 90 #include "dwarf_base_types.h" 91 #include "dwarf_opaque.h" 92 #include "dwarf_error.h" /* for _dwarf_error() declaration */ 93 #include "dwarf_reading.h" 94 #include "memcpy_swap.h" 95 #include "dwarf_object_read_common.h" 96 #include "dwarf_object_detector.h" 97 #include "dwarf_elfstructs.h" 98 #include "dwarf_elf_defines.h" 99 #include "dwarf_elf_rel_detector.h" 100 #include "dwarf_elfread.h" 101 102 103 #ifndef TYP 104 #define TYP(n,l) char n[l] 105 #endif /* TYPE */ 106 107 #ifdef WORDS_BIGENDIAN 108 #define READ_UNALIGNED_SAFE(dbg,dest, source, length) \ 109 do { \ 110 Dwarf_Unsigned _ltmp = 0; \ 111 dbg->de_copy_word( (((char *)(&_ltmp)) + \ 112 sizeof(_ltmp) - length),source, length); \ 113 dest = _ltmp; \ 114 } while (0) 115 116 #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \ 117 { \ 118 dbg->de_copy_word(dest, \ 119 ((char *)source) +srclength-len_out, \ 120 len_out) ; \ 121 } 122 #else /* LITTLE ENDIAN */ 123 #define READ_UNALIGNED_SAFE(dbg,dest, source, srclength) \ 124 do { \ 125 Dwarf_Unsigned _ltmp = 0; \ 126 dbg->de_copy_word( (char *)(&_ltmp), \ 127 source, srclength) ; \ 128 dest = _ltmp; \ 129 } while (0) 130 131 #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \ 132 { \ 133 dbg->de_copy_word( (dest) , \ 134 ((char *)source) , \ 135 len_out) ; \ 136 } 137 #endif /* *-ENDIAN */ 138 139 140 #ifdef WORDS_BIGENDIAN 141 #define ASNAR(func,t,s) \ 142 do { \ 143 unsigned tbyte = sizeof(t) - sizeof(s); \ 144 t = 0; \ 145 func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ 146 } while (0) 147 #else /* LITTLE ENDIAN */ 148 #define ASNAR(func,t,s) \ 149 do { \ 150 t = 0; \ 151 func(&t,&s[0],sizeof(s)); \ 152 } while (0) 153 #endif /* end LITTLE- BIG-ENDIAN */ 154 155 156 static int 157 _dwarf_elf_object_access_init( 158 int fd, 159 unsigned ftype, 160 unsigned endian, 161 unsigned offsetsize, 162 size_t filesize, 163 Dwarf_Unsigned access, 164 Dwarf_Obj_Access_Interface **binary_interface, 165 int *localerrnum); 166 167 168 static Dwarf_Endianness elf_get_nolibelf_byte_order (void *obj) 169 { 170 dwarf_elf_object_access_internals_t *elf = 171 (dwarf_elf_object_access_internals_t*)(obj); 172 return elf->f_endian; 173 } 174 175 176 static Dwarf_Small elf_get_nolibelf_length_size (void *obj) 177 { 178 dwarf_elf_object_access_internals_t *elf = 179 (dwarf_elf_object_access_internals_t*)(obj); 180 return elf->f_offsetsize/8; 181 } 182 183 184 static Dwarf_Small elf_get_nolibelf_pointer_size (void *obj) 185 { 186 dwarf_elf_object_access_internals_t *elf = 187 (dwarf_elf_object_access_internals_t*)(obj); 188 return elf->f_pointersize/8; 189 } 190 191 192 static Dwarf_Unsigned elf_get_nolibelf_section_count (void *obj) 193 { 194 dwarf_elf_object_access_internals_t *elf = 195 (dwarf_elf_object_access_internals_t*)(obj); 196 return elf->f_loc_shdr.g_count; 197 } 198 199 static int elf_get_nolibelf_section_info (void *obj, 200 Dwarf_Half section_index, 201 Dwarf_Obj_Access_Section *return_section, 202 UNUSEDARG int *error) 203 { 204 dwarf_elf_object_access_internals_t *elf = 205 (dwarf_elf_object_access_internals_t*)(obj); 206 207 208 if (section_index < elf->f_loc_shdr.g_count) { 209 struct generic_shdr *sp = 0; 210 211 sp = elf->f_shdr + section_index; 212 return_section->addr = sp->gh_addr; 213 return_section->type = sp->gh_type; 214 return_section->size = sp->gh_size; 215 return_section->name = sp->gh_namestring; 216 return_section->link = sp->gh_link; 217 return_section->info = sp->gh_info; 218 return_section->entrysize = sp->gh_entsize; 219 return DW_DLV_OK; 220 } 221 return DW_DLV_NO_ENTRY; 222 } 223 224 static int 225 elf_load_nolibelf_section (void *obj, Dwarf_Half section_index, 226 Dwarf_Small **return_data, int *error) 227 { 228 dwarf_elf_object_access_internals_t *elf = 229 (dwarf_elf_object_access_internals_t*)(obj); 230 231 if (0 < section_index && 232 section_index < elf->f_loc_shdr.g_count) { 233 int res = 0; 234 235 struct generic_shdr *sp = 236 elf->f_shdr + section_index; 237 if (sp->gh_content) { 238 *return_data = (Dwarf_Small *)sp->gh_content; 239 return DW_DLV_OK; 240 } 241 if (!sp->gh_size) { 242 return DW_DLV_NO_ENTRY; 243 } 244 if ((sp->gh_size + sp->gh_offset) > 245 elf->f_filesize) { 246 *error = DW_DLE_ELF_SECTION_ERROR; 247 return DW_DLV_ERROR; 248 } 249 250 sp->gh_content = malloc((size_t)sp->gh_size); 251 if(!sp->gh_content) { 252 *error = DW_DLE_ALLOC_FAIL; 253 return DW_DLV_ERROR; 254 } 255 res = RRMOA(elf->f_fd, 256 sp->gh_content, (off_t)sp->gh_offset, 257 (size_t)sp->gh_size, (off_t)elf->f_filesize, error); 258 if (res != DW_DLV_OK) { 259 free(sp->gh_content); 260 sp->gh_content = 0; 261 return res; 262 } 263 *return_data = (Dwarf_Small *)sp->gh_content; 264 return DW_DLV_OK; 265 } 266 return DW_DLV_NO_ENTRY; 267 } 268 269 static int 270 _dwarf_get_elf_flags_func_nl( 271 void* obj_in, 272 Dwarf_Half section_index, 273 Dwarf_Unsigned *flags_out, 274 Dwarf_Unsigned *addralign_out, 275 int *error) 276 { 277 dwarf_elf_object_access_internals_t *ep = 0; 278 struct generic_shdr *shp = 0; 279 280 ep = (dwarf_elf_object_access_internals_t *)obj_in; 281 if (section_index == 0) { 282 /* Nothing to do. Empty section */ 283 return DW_DLV_OK; 284 } 285 if (section_index >= ep->f_loc_shdr.g_count) { 286 *error = DW_DLE_SECTION_INDEX_BAD; 287 return DW_DLV_ERROR; 288 } 289 shp = ep->f_shdr + section_index; 290 *flags_out = shp->gh_flags; 291 *addralign_out = shp->gh_addralign; 292 return DW_DLV_OK; 293 } 294 295 296 #define MATCH_REL_SEC(i_,s_,r_) \ 297 if (i_ == s_.dss_index) { \ 298 *r_ = &s_; \ 299 return DW_DLV_OK; \ 300 } 301 302 static int 303 find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index, 304 struct Dwarf_Section_s **relocatablesec, int *error) 305 { 306 MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec); 307 MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec); 308 MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec); 309 MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec); 310 MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); 311 MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec); 312 MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec); 313 MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec); 314 MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec); 315 MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec); 316 MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec); 317 MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec); 318 MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec); 319 MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec); 320 MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec); 321 MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec); 322 MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec); 323 MATCH_REL_SEC(section_index,dbg->de_debug_rnglists,relocatablesec); 324 MATCH_REL_SEC(section_index,dbg->de_debug_loclists,relocatablesec); 325 MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); 326 MATCH_REL_SEC(section_index,dbg->de_debug_sup,relocatablesec); 327 MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets,relocatablesec); 328 MATCH_REL_SEC(section_index,dbg->de_debug_addr,relocatablesec); 329 /* dbg-> de_debug_tu_index,reloctablesec); */ 330 /* dbg-> de_debug_cu_index,reloctablesec); */ 331 /* dbg-> de_debug_gdbindex,reloctablesec); */ 332 /* dbg-> de_debug_str,syms); */ 333 /* de_elf_symtab,syms); */ 334 /* de_elf_strtab,syms); */ 335 *error = DW_DLE_RELOC_SECTION_MISMATCH; 336 return DW_DLV_ERROR; 337 } 338 339 340 /* Returns DW_DLV_OK if it works, else DW_DLV_ERROR. 341 The caller may decide to ignore the errors or report them. */ 342 static int 343 update_entry(Dwarf_Debug dbg, 344 dwarf_elf_object_access_internals_t*obj, 345 struct generic_rela *rela, 346 Dwarf_Small *target_section, 347 Dwarf_Unsigned target_section_size, 348 int *error) 349 { 350 unsigned int type = 0; 351 unsigned int sym_idx = 0; 352 Dwarf_Unsigned offset = 0; 353 Dwarf_Signed addend = 0; 354 Dwarf_Unsigned reloc_size = 0; 355 Dwarf_Half machine = obj->f_machine; 356 struct generic_symentry *symp = 0; 357 int is_rela = rela->gr_is_rela; 358 359 offset = rela->gr_offset; 360 addend = rela->gr_addend; 361 type = (unsigned int)rela->gr_type; 362 sym_idx = (unsigned int)rela->gr_sym; 363 if (sym_idx >= obj->f_loc_symtab.g_count) { 364 *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD; 365 return DW_DLV_ERROR; 366 } 367 symp = obj->f_symtab + sym_idx; 368 if (offset >= target_section_size) { 369 /* If offset really big, any add will overflow. 370 So lets stop early if offset is corrupt. */ 371 *error = DW_DLE_RELOC_INVALID; 372 return DW_DLV_ERROR; 373 } 374 375 /* Determine relocation size */ 376 if (_dwarf_is_32bit_abs_reloc(type, machine)) { 377 reloc_size = 4; 378 } else if (_dwarf_is_64bit_abs_reloc(type, machine)) { 379 reloc_size = 8; 380 } else { 381 *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; 382 return DW_DLV_ERROR; 383 } 384 if ( (offset + reloc_size) < offset) { 385 /* Another check for overflow. */ 386 *error = DW_DLE_RELOC_INVALID; 387 return DW_DLV_ERROR; 388 } 389 if ( (offset + reloc_size) > target_section_size) { 390 *error = DW_DLE_RELOC_INVALID; 391 return DW_DLV_ERROR; 392 } 393 /* Assuming we do not need to do a READ_UNALIGNED here 394 at target_section + offset and add its value to 395 outval. Some ABIs say no read (for example MIPS), 396 but if some do then which ones? */ 397 { /* .rel. (addend is 0), or .rela. */ 398 Dwarf_Small *targ = target_section+offset; 399 Dwarf_Unsigned presentval = 0; 400 Dwarf_Unsigned outval = 0; 401 /* See also: READ_UNALIGNED_SAFE in 402 dwarf_elf_access.c */ 403 404 if (!is_rela) { 405 READ_UNALIGNED_SAFE(dbg,presentval, 406 targ,reloc_size); 407 } 408 /* There is no addend in .rel. 409 Normally presentval is correct 410 and st_value will be zero. 411 But a few compilers have 412 presentval zero and st_value set. */ 413 outval = presentval + symp->gs_value + addend; 414 WRITE_UNALIGNED_LOCAL(dbg,targ, 415 &outval,sizeof(outval),reloc_size); 416 } 417 return DW_DLV_OK; 418 } 419 420 421 422 /* Somewhat arbitrarily, we attempt to apply all the 423 relocations we can 424 and still notify the caller of at least one error if we found 425 any errors. */ 426 427 static int 428 apply_rela_entries( 429 Dwarf_Debug dbg, 430 /* Section_index of the relocation section, .rela entries */ 431 Dwarf_Half r_section_index, 432 dwarf_elf_object_access_internals_t*obj, 433 /* relocatablesec is the .debug_info(etc) in Dwarf_Debug */ 434 struct Dwarf_Section_s * relocatablesec, 435 int *error) 436 { 437 int return_res = DW_DLV_OK; 438 struct generic_shdr * rels_shp = 0; 439 Dwarf_Unsigned relcount; 440 Dwarf_Unsigned i = 0; 441 442 if (r_section_index >= obj->f_loc_shdr.g_count) { 443 *error = DW_DLE_SECTION_INDEX_BAD; 444 return DW_DLV_ERROR; 445 } 446 rels_shp = obj->f_shdr + r_section_index; 447 relcount = rels_shp->gh_relcount; 448 if (!relcount) { 449 /* Nothing to do. */ 450 return DW_DLV_OK; 451 } 452 if (!rels_shp->gh_rels) { 453 /* something wrong. */ 454 *error = DW_DLE_RELOCS_ERROR; 455 return DW_DLV_ERROR; 456 } 457 for (i = 0; i < relcount; i++) { 458 int res = update_entry(dbg,obj, 459 rels_shp->gh_rels+i, 460 relocatablesec->dss_data, 461 relocatablesec->dss_size, 462 error); 463 if (res != DW_DLV_OK) { 464 /* We try to keep going, not stop. */ 465 return_res = res; 466 } 467 } 468 return return_res; 469 } 470 471 /* Find the section data in dbg and find all the relevant 472 sections. Then do relocations. 473 474 section_index is the index of a .debug_info (for example) 475 so we have to find the section(s) with relocations 476 targeting section_index. 477 Normally there is exactly one such, though. 478 */ 479 static int 480 elf_relocations_nolibelf(void* obj_in, 481 Dwarf_Half section_index, 482 Dwarf_Debug dbg, 483 int* error) 484 { 485 int res = DW_DLV_ERROR; 486 dwarf_elf_object_access_internals_t*obj = 0; 487 struct Dwarf_Section_s * relocatablesec = 0; 488 unsigned section_with_reloc_records = 0; 489 490 if (section_index == 0) { 491 return DW_DLV_NO_ENTRY; 492 } 493 obj = (dwarf_elf_object_access_internals_t*)obj_in; 494 495 /* The section to relocate must already be loaded into memory. 496 This just turns section_index into a pointer 497 to a de_debug_info or other section record in 498 Dwarf_Debug. */ 499 res = find_section_to_relocate(dbg, section_index, 500 &relocatablesec, error); 501 if (res != DW_DLV_OK) { 502 return res; 503 } 504 /* Now we know the Dwarf_Section_s section 505 we need to relocate. 506 So lets find the rela section(s) targeting this. 507 */ 508 509 /* Sun and possibly others do not always set 510 sh_link in .debug_* sections. 511 So we cannot do full consistency checks. 512 FIXME: This approach assumes there is only one 513 relocation section applying to section section_index! */ 514 section_with_reloc_records = relocatablesec->dss_reloc_index; 515 if (!section_with_reloc_records) { 516 /* Something is wrong. */ 517 *error = DW_DLE_RELOC_SECTION_MISSING_INDEX; 518 return DW_DLV_ERROR; 519 } 520 /* The relocations, if they exist, have been loaded. */ 521 /* The symtab was already loaded. */ 522 if (!obj->f_symtab || !obj->f_symtab_sect_strings) { 523 *error = DW_DLE_DEBUG_SYMTAB_ERR; 524 return DW_DLV_ERROR; 525 } 526 if (obj->f_symtab_sect_index != relocatablesec->dss_reloc_link) { 527 /* Something is wrong. */ 528 *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX; 529 return DW_DLV_ERROR; 530 } 531 /* We have all the data we need in memory. */ 532 /* Now we apply the relocs in section_with_reloc_records to the 533 target, relocablesec */ 534 res = apply_rela_entries(dbg,section_with_reloc_records, 535 obj, relocatablesec,error); 536 return res; 537 } 538 539 void 540 _dwarf_destruct_elf_nlaccess( 541 struct Dwarf_Obj_Access_Interface_s *aip) 542 { 543 dwarf_elf_object_access_internals_t *ep = 0; 544 struct generic_shdr *shp = 0; 545 Dwarf_Unsigned shcount = 0; 546 Dwarf_Unsigned i = 0; 547 548 ep = (dwarf_elf_object_access_internals_t *)aip->object; 549 free(ep->f_ehdr); 550 shp = ep->f_shdr; 551 shcount = ep->f_loc_shdr.g_count; 552 for(i = 0; i < shcount; ++i,++shp) { 553 free(shp->gh_rels); 554 shp->gh_rels = 0; 555 free(shp->gh_content); 556 shp->gh_content = 0; 557 free(shp->gh_sht_group_array); 558 shp->gh_sht_group_array = 0; 559 shp->gh_sht_group_array_count = 0; 560 } 561 free(ep->f_shdr); 562 ep->f_loc_shdr.g_count = 0; 563 free(ep->f_phdr); 564 free(ep->f_elf_shstrings_data); 565 free(ep->f_dynamic); 566 free(ep->f_symtab_sect_strings); 567 free(ep->f_dynsym_sect_strings); 568 free(ep->f_symtab); 569 free(ep->f_dynsym); 570 571 /* if TRUE close f_fd on destruct.*/ 572 if (ep->f_destruct_close_fd) { 573 close(ep->f_fd); 574 } 575 ep->f_ident[0] = 'X'; 576 free(ep->f_path); 577 free(ep); 578 free(aip); 579 } 580 581 582 int 583 _dwarf_elf_nlsetup(int fd, 584 char *true_path, 585 unsigned ftype, 586 unsigned endian, 587 unsigned offsetsize, 588 size_t filesize, 589 Dwarf_Unsigned access, 590 unsigned groupnumber, 591 Dwarf_Handler errhand, 592 Dwarf_Ptr errarg, 593 Dwarf_Debug *dbg,Dwarf_Error *error) 594 { 595 Dwarf_Obj_Access_Interface *binary_interface = 0; 596 dwarf_elf_object_access_internals_t *intfc = 0; 597 int res = DW_DLV_OK; 598 int localerrnum = 0; 599 600 res = _dwarf_elf_object_access_init( 601 fd, 602 ftype,endian,offsetsize,filesize,access, 603 &binary_interface, 604 &localerrnum); 605 if (res != DW_DLV_OK) { 606 if (res == DW_DLV_NO_ENTRY) { 607 return res; 608 } 609 _dwarf_error(NULL, error, localerrnum); 610 return DW_DLV_ERROR; 611 } 612 /* allocates and initializes Dwarf_Debug, 613 generic code */ 614 res = dwarf_object_init_b(binary_interface, errhand, errarg, 615 groupnumber, dbg, error); 616 if (res != DW_DLV_OK){ 617 _dwarf_destruct_elf_nlaccess(binary_interface); 618 return res; 619 } 620 intfc = binary_interface->object; 621 intfc->f_path = strdup(true_path); 622 return res; 623 } 624 625 /* dwarf_elf_access method table for use with non-libelf. 626 See also the methods table in dwarf_elf_access.c for libelf. 627 */ 628 static Dwarf_Obj_Access_Methods const elf_nlmethods = { 629 elf_get_nolibelf_section_info, 630 elf_get_nolibelf_byte_order, 631 elf_get_nolibelf_length_size, 632 elf_get_nolibelf_pointer_size, 633 elf_get_nolibelf_section_count, 634 elf_load_nolibelf_section, 635 elf_relocations_nolibelf 636 }; 637 638 /* On any error this frees internals argument. */ 639 static int 640 _dwarf_elf_object_access_internals_init( 641 dwarf_elf_object_access_internals_t * internals, 642 int fd, 643 unsigned ftype, 644 unsigned endian, 645 unsigned offsetsize, 646 size_t filesize, 647 UNUSEDARG Dwarf_Unsigned access, 648 int *errcode) 649 { 650 dwarf_elf_object_access_internals_t * intfc = internals; 651 Dwarf_Unsigned i = 0; 652 struct Dwarf_Obj_Access_Interface_s *localdoas; 653 int res = 0; 654 655 /* Must malloc as _dwarf_destruct_elf_access() 656 forces that due to other uses. */ 657 localdoas = (struct Dwarf_Obj_Access_Interface_s *) 658 malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); 659 if (!localdoas) { 660 free(internals); 661 *errcode = DW_DLE_ALLOC_FAIL; 662 return DW_DLV_ERROR; 663 } 664 memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); 665 /* E is used with libelf. F with this elf reader. */ 666 intfc->f_ident[0] = 'F'; 667 intfc->f_ident[1] = '1'; 668 intfc->f_fd = fd; 669 intfc->f_is_64bit = ((offsetsize==64)?TRUE:FALSE); 670 intfc->f_offsetsize = offsetsize; 671 intfc->f_pointersize = offsetsize; 672 intfc->f_filesize = filesize; 673 intfc->f_ftype = ftype; 674 intfc->f_destruct_close_fd = FALSE; 675 676 #ifdef WORDS_BIGENDIAN 677 if (endian == DW_ENDIAN_LITTLE ) { 678 intfc->f_copy_word = _dwarf_memcpy_swap_bytes; 679 intfc->f_endian = DW_OBJECT_LSB; 680 } else { 681 intfc->f_copy_word = _dwarf_memcpy_noswap_bytes; 682 intfc->f_endian = DW_OBJECT_MSB; 683 } 684 #else /* LITTLE ENDIAN */ 685 if (endian == DW_ENDIAN_LITTLE ) { 686 intfc->f_copy_word = _dwarf_memcpy_noswap_bytes; 687 intfc->f_endian = DW_OBJECT_LSB; 688 } else { 689 intfc->f_copy_word = _dwarf_memcpy_swap_bytes; 690 intfc->f_endian = DW_OBJECT_MSB; 691 } 692 #endif /* LITTLE- BIG-ENDIAN */ 693 _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func_nl; 694 /* The following sets f_machine. */ 695 res = _dwarf_load_elf_header(intfc,errcode); 696 if (res != DW_DLV_OK) { 697 localdoas->object = intfc; 698 localdoas->methods = 0; 699 _dwarf_destruct_elf_nlaccess(localdoas); 700 localdoas = 0; 701 return res; 702 } 703 /* Not loading progheaders */ 704 res = _dwarf_load_elf_sectheaders(intfc,errcode); 705 if (res != DW_DLV_OK) { 706 localdoas->object = intfc; 707 localdoas->methods = 0; 708 _dwarf_destruct_elf_nlaccess(localdoas); 709 localdoas = 0; 710 return res; 711 } 712 /* We are not looking at symbol strings for now. */ 713 res = _dwarf_load_elf_symstr(intfc,errcode); 714 if (res == DW_DLV_ERROR) { 715 localdoas->object = intfc; 716 localdoas->methods = 0; 717 _dwarf_destruct_elf_nlaccess(localdoas); 718 localdoas = 0; 719 return res; 720 } 721 res = _dwarf_load_elf_symtab_symbols(intfc,errcode); 722 if (res == DW_DLV_ERROR) { 723 localdoas->object = intfc; 724 localdoas->methods = 0; 725 _dwarf_destruct_elf_nlaccess(localdoas); 726 localdoas = 0; 727 return res; 728 } 729 for ( i = 1; i < intfc->f_loc_shdr.g_count; ++i) { 730 struct generic_shdr *shp = 0; 731 Dwarf_Unsigned section_type = 0; 732 enum RelocRela localrel = RelocIsRela; 733 734 shp = intfc->f_shdr +i; 735 section_type = shp->gh_type; 736 if (section_type == SHT_REL || 737 (!strncmp(".rel.",shp->gh_namestring,5))) { 738 localrel = RelocIsRel; 739 } else if (section_type == SHT_RELA || 740 (!strncmp(".rela.",shp->gh_namestring,6))) { 741 localrel = RelocIsRela; 742 } else { 743 continue; 744 } 745 /* ASSERT: local rel is either RelocIsRel or 746 RelocIsRela. Never any other value. */ 747 /* Possibly we should check if the target section 748 is one we care about before loading rela 749 FIXME */ 750 res = _dwarf_load_elf_relx(intfc,i,localrel,errcode); 751 if (res == DW_DLV_ERROR) { 752 localdoas->object = intfc; 753 localdoas->methods = 0; 754 _dwarf_destruct_elf_nlaccess(localdoas); 755 localdoas = 0; 756 return res; 757 } 758 } 759 free(localdoas); 760 localdoas = 0; 761 return DW_DLV_OK; 762 } 763 764 765 static int 766 _dwarf_elf_object_access_init( 767 int fd, 768 unsigned ftype, 769 unsigned endian, 770 unsigned offsetsize, 771 size_t filesize, 772 Dwarf_Unsigned access, 773 Dwarf_Obj_Access_Interface **binary_interface, 774 int *localerrnum) 775 { 776 777 int res = 0; 778 dwarf_elf_object_access_internals_t *internals = 0; 779 Dwarf_Obj_Access_Interface *intfc = 0; 780 781 internals = malloc(sizeof(dwarf_elf_object_access_internals_t)); 782 if (!internals) { 783 *localerrnum = DW_DLE_ALLOC_FAIL; 784 /* Impossible case, we hope. Give up. */ 785 return DW_DLV_ERROR; 786 } 787 memset(internals,0,sizeof(*internals)); 788 res = _dwarf_elf_object_access_internals_init(internals, 789 fd, 790 ftype, endian, offsetsize, filesize, 791 access, 792 localerrnum); 793 if (res != DW_DLV_OK){ 794 return res; 795 } 796 797 intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); 798 if (!intfc) { 799 /* Impossible case, we hope. Give up. */ 800 free(internals); 801 *localerrnum = DW_DLE_ALLOC_FAIL; 802 return DW_DLV_ERROR; 803 } 804 /* Initialize the interface struct */ 805 intfc->object = internals; 806 intfc->methods = &elf_nlmethods; 807 *binary_interface = intfc; 808 return DW_DLV_OK; 809 } 810