429
430 tgt = safe_malloc(sizeof (dis_tgt_t));
431
432 if ((tgt->dt_fd = open(file, O_RDONLY)) < 0) {
433 warn("%s: failed opening file, reason: %s", file,
434 strerror(errno));
435 free(tgt);
436 return (NULL);
437 }
438
439 if ((tgt->dt_elf_root =
440 elf_begin(tgt->dt_fd, ELF_C_READ, NULL)) == NULL) {
441 warn("%s: invalid or corrupt ELF file", file);
442 dis_tgt_destroy(tgt);
443 return (NULL);
444 }
445
446 current = tgt;
447 cmd = ELF_C_READ;
448 while ((elf = elf_begin(tgt->dt_fd, cmd, tgt->dt_elf_root)) != NULL) {
449
450 if (elf_kind(tgt->dt_elf_root) == ELF_K_AR &&
451 (arhdr = elf_getarhdr(elf)) == NULL) {
452 warn("%s: malformed archive", file);
453 dis_tgt_destroy(tgt);
454 return (NULL);
455 }
456
457 /*
458 * Make sure that this Elf file is sane
459 */
460 if (gelf_getehdr(elf, &ehdr) == NULL) {
461 if (arhdr != NULL) {
462 /*
463 * For archives, we drive on in the face of bad
464 * members. The "/" and "//" members are
465 * special, and should be silently ignored.
466 */
467 if (strcmp(arhdr->ar_name, "/") != 0 &&
468 strcmp(arhdr->ar_name, "//") != 0)
484 * off the master target. We can later iterate over these
485 * targets using dis_tgt_next().
486 */
487 if (current->dt_elf != NULL) {
488 dis_tgt_t *next = safe_malloc(sizeof (dis_tgt_t));
489 next->dt_elf_root = tgt->dt_elf_root;
490 next->dt_fd = -1;
491 current->dt_next = next;
492 current = next;
493 }
494 current->dt_elf = elf;
495 current->dt_arhdr = arhdr;
496
497 if (elf_getshdrstrndx(elf, ¤t->dt_shstrndx) == -1) {
498 warn("%s: failed to get section string table for "
499 "file", file);
500 dis_tgt_destroy(tgt);
501 return (NULL);
502 }
503
504 current->dt_shnmap = safe_malloc(sizeof (dis_shnmap_t) *
505 ehdr.e_shnum);
506 current->dt_shncount = ehdr.e_shnum;
507
508 idx = 0;
509 dis_tgt_section_iter(current, tgt_scn_init, &idx);
510 current->dt_filename = file;
511
512 create_addrmap(current);
513 if (current->dt_symidx != 0)
514 construct_symtab(current);
515
516 cmd = elf_next(elf);
517 }
518
519 /*
520 * Final sanity check. If we had an archive with no members, then bail
521 * out with a nice message.
522 */
523 if (tgt->dt_elf == NULL) {
524 warn("%s: empty archive\n", file);
525 dis_tgt_destroy(tgt);
526 return (NULL);
|
429
430 tgt = safe_malloc(sizeof (dis_tgt_t));
431
432 if ((tgt->dt_fd = open(file, O_RDONLY)) < 0) {
433 warn("%s: failed opening file, reason: %s", file,
434 strerror(errno));
435 free(tgt);
436 return (NULL);
437 }
438
439 if ((tgt->dt_elf_root =
440 elf_begin(tgt->dt_fd, ELF_C_READ, NULL)) == NULL) {
441 warn("%s: invalid or corrupt ELF file", file);
442 dis_tgt_destroy(tgt);
443 return (NULL);
444 }
445
446 current = tgt;
447 cmd = ELF_C_READ;
448 while ((elf = elf_begin(tgt->dt_fd, cmd, tgt->dt_elf_root)) != NULL) {
449 size_t shnum = 0;
450
451 if (elf_kind(tgt->dt_elf_root) == ELF_K_AR &&
452 (arhdr = elf_getarhdr(elf)) == NULL) {
453 warn("%s: malformed archive", file);
454 dis_tgt_destroy(tgt);
455 return (NULL);
456 }
457
458 /*
459 * Make sure that this Elf file is sane
460 */
461 if (gelf_getehdr(elf, &ehdr) == NULL) {
462 if (arhdr != NULL) {
463 /*
464 * For archives, we drive on in the face of bad
465 * members. The "/" and "//" members are
466 * special, and should be silently ignored.
467 */
468 if (strcmp(arhdr->ar_name, "/") != 0 &&
469 strcmp(arhdr->ar_name, "//") != 0)
485 * off the master target. We can later iterate over these
486 * targets using dis_tgt_next().
487 */
488 if (current->dt_elf != NULL) {
489 dis_tgt_t *next = safe_malloc(sizeof (dis_tgt_t));
490 next->dt_elf_root = tgt->dt_elf_root;
491 next->dt_fd = -1;
492 current->dt_next = next;
493 current = next;
494 }
495 current->dt_elf = elf;
496 current->dt_arhdr = arhdr;
497
498 if (elf_getshdrstrndx(elf, ¤t->dt_shstrndx) == -1) {
499 warn("%s: failed to get section string table for "
500 "file", file);
501 dis_tgt_destroy(tgt);
502 return (NULL);
503 }
504
505 if (elf_getshdrnum(elf, &shnum) == -1) {
506 warn("%s: failed to get number of sections in file",
507 file);
508 dis_tgt_destroy(tgt);
509 return (NULL);
510 }
511
512 current->dt_shnmap = safe_malloc(sizeof (dis_shnmap_t) *
513 shnum);
514 current->dt_shncount = shnum;
515
516 idx = 0;
517 dis_tgt_section_iter(current, tgt_scn_init, &idx);
518 current->dt_filename = file;
519
520 create_addrmap(current);
521 if (current->dt_symidx != 0)
522 construct_symtab(current);
523
524 cmd = elf_next(elf);
525 }
526
527 /*
528 * Final sanity check. If we had an archive with no members, then bail
529 * out with a nice message.
530 */
531 if (tgt->dt_elf == NULL) {
532 warn("%s: empty archive\n", file);
533 dis_tgt_destroy(tgt);
534 return (NULL);
|