/* * Process member files of an archive. This function provides * a loop through an archive equivalent the processing of * each_file for individual object files. */ static void print_ar_files(int fd, Elf * elf_file, char *filename) { Elf_Arhdr *p_ar; Elf *arf; Elf_Cmd cmd; Elf_Kind file_type; cmd = ELF_C_READ; archive_name = filename; while ((arf = elf_begin(fd, cmd, elf_file)) != 0) { p_ar = elf_getarhdr(arf); if (p_ar == NULL) { (void) fprintf(stderr, "%s: %s: %s\n", prog_name, filename, elf_errmsg(-1)); return; } if (p_ar->ar_name[0] == '/') { cmd = elf_next(arf); (void) elf_end(arf); continue; } if (!h_flag & !P_flag) { if (p_flag) (void) printf("\n\n%s[%s]:\n", filename, p_ar->ar_name); else { if (A_flag != 0) (void) printf("\n\n%s%s[%s]:\n", A_header, filename, p_ar->ar_name); else (void) printf("\n\n%s[%s]:\n", filename, p_ar->ar_name); } } file_type = elf_kind(arf); if (file_type == ELF_K_ELF) { process(arf, p_ar->ar_name); } else { (void) fprintf(stderr, gettext( "%s: %s: invalid file type\n"), prog_name, p_ar->ar_name); cmd = elf_next(arf); (void) elf_end(arf); errflag++; continue; } cmd = elf_next(arf); (void) elf_end(arf); } /* end while */ }
static int read_archive(int fd, Elf *elf, char *file, char *label, read_cb_f *func, void *arg, int require_ctf) { Elf *melf; Elf_Cmd cmd = ELF_C_READ; Elf_Arhdr *arh; int secnum = 1, found = 0; while ((melf = elf_begin(fd, cmd, elf)) != NULL) { int rc = 0; if ((arh = elf_getarhdr(melf)) == NULL) { elfterminate(file, "Can't get archive header for " "member %d", secnum); } /* skip special sections - their names begin with "/" */ if (*arh->ar_name != '/') { size_t memlen = strlen(file) + 1 + strlen(arh->ar_name) + 1 + 1; char *memname = xmalloc(memlen); snprintf(memname, memlen, "%s(%s)", file, arh->ar_name); switch (elf_kind(melf)) { case ELF_K_AR: rc = read_archive(fd, melf, memname, label, func, arg, require_ctf); break; case ELF_K_ELF: rc = read_file(melf, memname, label, func, arg, require_ctf); break; default: terminate("%s: Unknown elf kind %d\n", memname, elf_kind(melf)); } free(memname); } cmd = elf_next(melf); (void) elf_end(melf); secnum++; if (rc < 0) return (rc); else found += rc; } return (found); }
static void process_elf(Elf *elf, char *file, int fd, int member) { Elf_Cmd cmd; Elf *_elf; switch (elf_kind(elf)) { case ELF_K_ELF: /* * This is an ELF file, now attempt to find it's * .comment section and to display it. */ print_symtab(elf, file); break; case ELF_K_AR: /* * Archives contain multiple ELF files, which can each * in turn be examined with libelf. * * The below loop will iterate over each member of the * archive and recursively call process_elf(). */ cmd = ELF_C_READ; while ((_elf = elf_begin(fd, cmd, elf)) != NULL) { Elf_Arhdr *arhdr; char buffer[1024]; arhdr = elf_getarhdr(_elf); /* * Build up file names based off of * 'archivename(membername)'. */ (void) snprintf(buffer, 1024, "%s(%s)", file, arhdr->ar_name); /* * Recursively process the ELF members. */ process_elf(_elf, buffer, fd, 1); cmd = elf_next(_elf); (void) elf_end(_elf); } break; default: if (!member) (void) fprintf(stderr, "%s: unexpected elf_kind(): 0x%x\n", file, elf_kind(elf)); return; } }
/* * Given an elf object,ar(1) filename, and based on the output style * and radix format the various sections and their length will be printed * or the size of the text, data, bss sections will be printed out. */ static int handle_elf(char const *name) { GElf_Ehdr elfhdr; GElf_Shdr shdr; Elf *elf, *elf1; Elf_Arhdr *arhdr; Elf_Scn *scn; Elf_Cmd elf_cmd; int exit_code, fd; if (name == NULL) return (RETURN_NOINPUT); if ((fd = open(name, O_RDONLY, 0)) < 0) return (RETURN_NOINPUT); elf_cmd = ELF_C_READ; elf1 = elf_begin(fd, elf_cmd, NULL); while ((elf = elf_begin(fd, elf_cmd, elf1)) != NULL) { arhdr = elf_getarhdr(elf); if (elf_kind(elf) == ELF_K_NONE && arhdr == NULL) { (void) elf_end(elf); (void) elf_end(elf1); (void) close(fd); return (RETURN_DATAERR); } if (elf_kind(elf) != ELF_K_ELF || (gelf_getehdr(elf, &elfhdr) == NULL)) { elf_cmd = elf_next(elf); (void) elf_end(elf); warnx("%s: File format not recognized", arhdr->ar_name); continue; } /* Core dumps are handled seperately */ if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { exit_code = handle_core(name, elf, &elfhdr); (void) elf_end(elf); (void) elf_end(elf1); (void) close(fd); return (exit_code); } else { scn = NULL; if (style == STYLE_BERKELEY) { berkeley_header(); while ((scn = elf_nextscn(elf, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != NULL) berkeley_calc(&shdr); } } else { sysv_header(name, arhdr); scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != NULL) sysv_calc(elf, &elfhdr, &shdr); } } if (style == STYLE_BERKELEY) { if (arhdr != NULL) { berkeley_footer(name, arhdr->ar_name, "ex"); } else { berkeley_footer(name, NULL, "ex"); } } else { sysv_footer(); } } elf_cmd = elf_next(elf); (void) elf_end(elf); } (void) elf_end(elf1); (void) close(fd); return (RETURN_OK); }
int each_file(char *cur_file, Cmd_Info *cmd_info) { Elf *elf = 0; Elf_Cmd cmd; Elf *arf = 0; Elf_Arhdr *mem_header; char *cur_filenm = NULL; int code = 0; int error = 0, err = 0; int ar_file = 0; int fdartmp; int fd; int oflag; if (cmd_info->flags & MIGHT_CHG) oflag = O_RDWR; else oflag = O_RDONLY; if ((fd = open(cur_file, oflag)) == -1) { error_message(OPEN_ERROR, SYSTEM_ERROR, strerror(errno), prog, cur_file); return (FAILURE); } /* * Note, elf_begin requires ELF_C_READ even if MIGHT_CHK is in effect. * libelf does not allow elf_begin() with ELF_C_RDWR when processing * archive file members. Because we are limited to ELF_C_READ use, any * ELF data modification must be provided by updating a copy of * the data, rather than updating the original file data. */ cmd = ELF_C_READ; if ((arf = elf_begin(fd, cmd, (Elf *)0)) == 0) { error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog); (void) elf_end(arf); (void) close(fd); /* done processing this file */ return (FAILURE); } if ((elf_kind(arf) == ELF_K_AR)) { ar_file = 1; if (CHK_OPT(cmd_info, MIGHT_CHG)) { artmpfile = tempnam(TMPDIR, "mcs2"); if ((fdartmp = open(artmpfile, O_WRONLY | O_APPEND | O_CREAT, (mode_t)0666)) == NULL) { error_message(OPEN_TEMP_ERROR, SYSTEM_ERROR, strerror(errno), prog, artmpfile); (void) elf_end(arf); (void) close(fd); exit(FAILURE); } /* write magic string to artmpfile */ if ((write(fdartmp, ARMAG, SARMAG)) != SARMAG) { error_message(WRITE_ERROR, SYSTEM_ERROR, strerror(errno), prog, artmpfile, cur_file); mcs_exit(FAILURE); } } } else { ar_file = 0; cur_filenm = cur_file; } /* * Holds temporary file; * if archive, holds the current member file if it has an ehdr, * and there were no errors in * processing the object file. */ elftmpfile = tempnam(TMPDIR, "mcs1"); while ((elf = elf_begin(fd, cmd, arf)) != 0) { if (ar_file) /* get header info */ { size_t len; if ((mem_header = elf_getarhdr(elf)) == NULL) { error_message(GETARHDR_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog, cur_file, elf_getbase(elf)); (void) elf_end(elf); (void) elf_end(arf); (void) close(fd); (void) unlink(artmpfile); return (FAILURE); } if (cur_filenm != NULL) free(cur_filenm); len = (strlen(cur_file) + 3 + strlen(mem_header->ar_name)); if ((cur_filenm = malloc(len)) == NULL) { error_message(MALLOC_ERROR, PLAIN_ERROR, (char *)0, prog); mcs_exit(FAILURE); } (void) snprintf(cur_filenm, len, "%s[%s]", cur_file, mem_header->ar_name); } if (elf_kind(elf) == ELF_K_ELF) { if ((code = process_file(elf, cur_filenm, cmd_info)) == FAILURE) { if (!ar_file) { (void) elf_end(arf); (void) elf_end(elf); (void) close(fd); return (FAILURE); } else { copy_non_elf_to_temp_ar( fd, elf, fdartmp, mem_header, cur_file, cmd_info); error++; } } else if (ar_file && CHK_OPT(cmd_info, MIGHT_CHG)) { if (code == DONT_BUILD) copy_non_elf_to_temp_ar( fd, elf, fdartmp, mem_header, cur_file, cmd_info); else copy_elf_file_to_temp_ar_file( fdartmp, mem_header, cur_file); } } else { /* * decide what to do with non-ELF file */ if (!ar_file) { error_message(FILE_TYPE_ERROR, PLAIN_ERROR, (char *)0, prog, cur_filenm); (void) close(fd); return (FAILURE); } else { if (CHK_OPT(cmd_info, MIGHT_CHG)) copy_non_elf_to_temp_ar( fd, elf, fdartmp, mem_header, cur_file, cmd_info); } } cmd = elf_next(elf); (void) elf_end(elf); } err = elf_errno(); if (err != 0) { error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(err), prog); error_message(NOT_MANIPULATED_ERROR, PLAIN_ERROR, (char *)0, prog, cur_file); return (FAILURE); } (void) elf_end(arf); if (ar_file && CHK_OPT(cmd_info, MIGHT_CHG)) { (void) close(fdartmp); /* done writing to ar_temp_file */ /* copy ar_temp_file to FILE */ copy_file(fd, cur_file, artmpfile); } else if (code != DONT_BUILD && CHK_OPT(cmd_info, MIGHT_CHG)) copy_file(fd, cur_file, elftmpfile); (void) close(fd); /* done processing this file */ return (error); }
/* * Extract every object in the given archive directly without going through * the symbol table. * * entry: * name - Name of archive * fd - Open file descriptor for archive * adp - Archive descriptor * ofl - output descriptor * found - Address of variable to set to TRUE if any objects are extracted * rej - Rejection descriptor to pass to ld_process_ifl(). * * exit: * Returns FALSE on fatal error. On success, *found will be TRUE * if any object was extracted, rej will be set if any object * was rejected, and TRUE is returned. */ static Boolean ar_extract_all(const char *name, int fd, Ar_desc *adp, Ofl_desc *ofl, Boolean *found, Rej_desc *rej) { Elf_Cmd cmd = ELF_C_READ; Elf *arelf; const char *arname, *arpath; size_t off, next_off; DBG_CALL(Dbg_file_ar(ofl->ofl_lml, name, FALSE)); while ((arelf = elf_begin(fd, cmd, adp->ad_elf)) != NULL) { /* * Call elf_next() so that the next call to elf_begin() will * fetch the archive member following this one. We do this now * because it simplifies the logic below, and because the * support libraries called below can set our handle to NULL. */ cmd = elf_next(arelf); /* Get member filename */ if ((arname = ar_member_name(name, arelf, ofl)) == NULL) return (FALSE); /* * Skip the symbol table, string table, or any other special * archive member. These all start with a '/' character. */ if (*arname == '/') { (void) elf_end(arelf); continue; } /* Obtain archive member offset within the file */ off = _elf_getarhdrbase(arelf); /* * ld_sup_open() will reset the current iteration point for * the archive to point at this member rather than the next * one for the benefit of the support libraries. Since * this loop relies on the current position not changing * underneath it, we save and restore the current * position around the support library call. */ next_off = _elf_getnextoff(adp->ad_elf); /* Construct the member's full pathname */ if ((arpath = ar_member_path(name, arname)) == NULL) return (S_ERROR); /* * Determine whether the support libraries wish to process * this open. See comments in ld_process_open(). */ ld_sup_open(ofl, &arpath, &arname, &fd, (FLG_IF_EXTRACT | FLG_IF_NEEDED), &arelf, adp->ad_elf, off, elf_kind(arelf)); (void) elf_rand(adp->ad_elf, next_off); if (arelf == NULL) continue; DBG_CALL(Dbg_syms_ar_force(ofl->ofl_lml, name, arname)); switch (ar_input(fd, adp, ofl, arelf, arpath, rej)) { case S_ERROR: return (FALSE); case 0: continue; } *found = TRUE; } /* * As this archive was extracted by -z allextract, the ar_aux table * and elf descriptor can be freed. Set ad_elf to NULL to mark the * archive is completely processed. */ (void) elf_end(adp->ad_elf); adp->ad_elf = NULL; return (TRUE); }
int main( int argc, char *argv[]) { int fd, cmd; size_t i; char shname[1024]; Elf *arf, *elf; GElf_Ehdr ehdr; Elf_Scn *scn; GElf_Shdr shdr; Elf_Data *data; if(elf_version(EV_CURRENT) == EV_NONE) error(EXIT_FAILURE, 0, "Library out of date."); if(argc != 2) error(EXIT_FAILURE, 0, "Usage: %s <filename>", argv[0]); if((fd = open(argv[1], O_RDONLY)) == -1) error(EXIT_FAILURE, 0, "Failed open file."); cmd = ELF_C_READ; if((arf = elf_begin(fd, cmd, (Elf *)0)) == NULL) error(EXIT_FAILURE, 0, "Failed open elf: %s", elf_errmsg ( -1)); while((elf = elf_begin(fd, cmd, arf)) != NULL) { if(gelf_getehdr(elf,&ehdr) != NULL) { scn = NULL; while((scn = elf_nextscn(elf, scn)) != NULL) { gelf_getshdr(scn, &shdr); strcpy(shname, elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)); printf("%s\n", shname); /* if( !strcmp(shname, ".bss") || !strcmp(shname, ".tbss") ) continue; */ if(shdr.sh_type == SHT_NOBITS) continue; data = NULL; while((data = elf_getdata(scn, data)) != NULL) { printf( "Type:\t\t%d\nSize:\t\t%lu\n" "Off:\t\t%lu\nAlign:\t\t%lu\nVersion:\t%u\n", data->d_type, data->d_size, data->d_off, data->d_align, data->d_version ); for(i = 0; i < (int)data->d_size; i++) { printf("%2x ", (uint8_t)((char *)(data->d_buf))[i]); if((i+1)%16 == 0) printf("\n"); } } printf("\n\n"); } } cmd = elf_next(elf); elf_end(elf); } elf_end(arf); close(fd); }
Func_DWARF *SET_fill_func_dwarf(char *name, uint32_t *func_addr, int len, uint32_t off) { int fd; Elf_Cmd cmd; Elf *arf; /* Used for an archive */ Elf *elf; int ret; if (elf_version(EV_CURRENT) == EV_NONE) { fprintf(stderr, "SET dwarf: libelf.a is out of date\n"); return NULL; } fd = open(name, O_RDONLY); if (fd == -1) { fprintf(stderr, "SET dwarf: Cannot open %s\n", name); return NULL; } /* Function DWARF table */ func_dwarf = (Func_DWARF *) malloc(sizeof(Func_DWARF) * len); if (func_dwarf == NULL) { fprintf(stderr, "SET dwarf: No memory space to allocate DWARF table!\n"); close(fd); return NULL; } memset(func_dwarf, 0, sizeof(Func_DWARF) * len); local_func_addr = func_addr; local_func_len = len; local_offset = off; cmd = ELF_C_READ; arf = elf_begin(fd, cmd, NULL); while ((elf = elf_begin(fd, cmd, arf)) != NULL) { Elf32_Ehdr *eh32; eh32 = elf32_getehdr(elf); if (eh32 == NULL) { fprintf(stderr, "SET dwarf: %s is not a 32-bit ELF file\n", name); goto fail; } else { ret = process_one_file(elf); if (ret != 0) goto fail; } cmd = elf_next(elf); elf_end(elf); } elf_end(arf); close(fd); return func_dwarf; fail: elf_end(elf); elf_end(arf); free(func_dwarf); close(fd); return NULL; }
int ar_diff(int fd1, int fd2, char *sections, int verbose) { int i=0, retval = ED_SUCCESS; Elf *arf[2]; Elf *elf[2]; Elf_Cmd cmd[2]; if ((arf[0] = elf_begin(fd1,ELF_C_READ,NULL))==NULL) { if (verbose) fprintf(stderr, "elfdiff: Error reading AR information from first input file.\n"); return ED_ELFFAIL; } if ((arf[1] = elf_begin(fd2,ELF_C_READ,NULL))==NULL) { if (verbose) fprintf(stderr, "elfdiff: Error reading AR information from second input file.\n"); elf_end(elf[0]); return ED_ELFFAIL; } if (arf[0]->e_numsyms != arf[1]->e_numsyms) { retval = ED_HDRFAIL; } else { //////////////////////////////////////////////////////// //FIXME: this section should correlate the items by name //////////////////////////////////////////////////////// cmd[0] = cmd[1] = ELF_C_READ; while (((elf[0] = elf_begin(fd1, cmd[0], arf[0])) != 0) && !retval) { if (elf32_getehdr(elf[0]) != 0) { while ((elf[1] = elf_begin(fd2, cmd[1], arf[1])) != 0) { if (elf32_getehdr(elf[1]) != 0) { if (strcmp(elf[0]->e_arhdrp->ar_name, elf[1]->e_arhdrp->ar_name) != 0) { if (verbose>1) fprintf(stderr, "elfdiff: Internal object order does not match. ('%s' != '%s')\n", elf[0]->e_arhdrp->ar_name, elf[1]->e_arhdrp->ar_name); retval = ED_HDRFAIL; } else { retval = ohdr_diff(elf, verbose); if (!retval && sections) retval=shdr_diff(elf, sections, verbose); if (retval) { if (verbose>1) fprintf(stderr, "elfdiff: Internal object '%s' - FAIL\n", elf[0]->e_arhdrp->ar_name); } else { if (verbose>1) fprintf(stdout, "elfdiff: Internal object '%s'- PASS\n", elf[0]->e_arhdrp->ar_name); } } cmd[1]=elf_next(elf[1]); elf_end(elf[1]); break; } cmd[1]=elf_next(elf[1]); elf_end(elf[1]); } } cmd[0]=elf_next(elf[0]); elf_end(elf[0]); } } for (i=0;i<2;i++) { elf_end(arf[i]); } if (verbose) { if (retval) { fprintf(stderr, "elfdiff: Files do not match\n"); } else { printf("elfdiff: Files match.\n"); } } return retval; }
static int archive(const char *file, int fd, Elf *elf, uint_t flags, const char *wname, int wfd, uchar_t osabi) { Elf_Cmd cmd = ELF_C_READ; Elf_Arhdr *arhdr; Elf *_elf = NULL; size_t ptr; Elf_Arsym *arsym = NULL; /* * Determine if the archive symbol table itself is required. */ if ((flags & FLG_SHOW_SYMBOLS) && match(MATCH_F_NAME, MSG_ORIG(MSG_ELF_ARSYM), 0, 0)) { /* * Get the archive symbol table. */ if (((arsym = elf_getarsym(elf, &ptr)) == 0) && elf_errno()) { /* * The arsym could be 0 even though there was no error. * Print the error message only when there was * real error from elf_getarsym(). */ failure(file, MSG_ORIG(MSG_ELF_GETARSYM)); return (0); } } /* * Print the archive symbol table only when the archive symbol * table exists and it was requested to print. */ if (arsym) { size_t cnt; char index[MAXNDXSIZE]; size_t offset = 0, _offset = 0; const char *fmt_arsym1, *fmt_arsym2; /* * Print out all the symbol entries. The format width used * corresponds to whether the archive symbol table is 32 * or 64-bit. We see them via Elf_Arhdr as size_t values * in either case with no information loss (see the comments * in libelf/getarsym.c) so this is done simply to improve * the user presentation. */ if (_elf_getarsymwordsize(elf) == 8) { dbg_print(0, MSG_INTL(MSG_ARCHIVE_SYMTAB_64)); dbg_print(0, MSG_INTL(MSG_ARCHIVE_FIELDS_64)); fmt_arsym1 = MSG_ORIG(MSG_FMT_ARSYM1_64); fmt_arsym2 = MSG_ORIG(MSG_FMT_ARSYM2_64); } else { dbg_print(0, MSG_INTL(MSG_ARCHIVE_SYMTAB_32)); dbg_print(0, MSG_INTL(MSG_ARCHIVE_FIELDS_32)); fmt_arsym1 = MSG_ORIG(MSG_FMT_ARSYM1_32); fmt_arsym2 = MSG_ORIG(MSG_FMT_ARSYM2_32); } for (cnt = 0; cnt < ptr; cnt++, arsym++) { /* * For each object obtain an elf descriptor so that we * can establish the members name. Note, we have had * archives where the archive header has not been * obtainable so be lenient with errors. */ if ((offset == 0) || ((arsym->as_off != 0) && (arsym->as_off != _offset))) { if (_elf) (void) elf_end(_elf); if (elf_rand(elf, arsym->as_off) != arsym->as_off) { failure(file, MSG_ORIG(MSG_ELF_RAND)); arhdr = NULL; } else if ((_elf = elf_begin(fd, ELF_C_READ, elf)) == 0) { failure(file, MSG_ORIG(MSG_ELF_BEGIN)); arhdr = NULL; } else if ((arhdr = elf_getarhdr(_elf)) == 0) { failure(file, MSG_ORIG(MSG_ELF_GETARHDR)); arhdr = NULL; } _offset = arsym->as_off; if (offset == 0) offset = _offset; } (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(cnt)); if (arsym->as_off) dbg_print(0, fmt_arsym1, index, EC_XWORD(arsym->as_off), arhdr ? arhdr->ar_name : MSG_INTL(MSG_STR_UNKNOWN), (arsym->as_name ? demangle(arsym->as_name, flags) : MSG_INTL(MSG_STR_NULL))); else dbg_print(0, fmt_arsym2, index, EC_XWORD(arsym->as_off)); } if (_elf) (void) elf_end(_elf); /* * If we only need the archive symbol table return. */ if ((flags & FLG_SHOW_SYMBOLS) && match(MATCH_F_STRICT | MATCH_F_NAME, MSG_ORIG(MSG_ELF_ARSYM), -1, -1)) return (0); /* * Reset elf descriptor in preparation for processing each * member. */ if (offset) (void) elf_rand(elf, offset); } /* * Process each object within the archive. */ while ((_elf = elf_begin(fd, cmd, elf)) != NULL) { char name[MAXPATHLEN]; if ((arhdr = elf_getarhdr(_elf)) == NULL) { failure(file, MSG_ORIG(MSG_ELF_GETARHDR)); return (0); } if (*arhdr->ar_name != '/') { (void) snprintf(name, MAXPATHLEN, MSG_ORIG(MSG_FMT_ARNAME), file, arhdr->ar_name); dbg_print(0, MSG_ORIG(MSG_FMT_NLSTR), name); switch (elf_kind(_elf)) { case ELF_K_AR: if (archive(name, fd, _elf, flags, wname, wfd, osabi) == 1) return (1); break; case ELF_K_ELF: if (decide(name, fd, _elf, flags, wname, wfd, osabi) == 1) return (1); break; default: (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADFILE), name); break; } } cmd = elf_next(_elf); (void) elf_end(_elf); } return (0); }
int main( int argc, char *argv[]) { int fd, cmd; size_t i, n; char *p; Elf *arf, *elf; GElf_Ehdr ehdr; Elf_Scn *scn; GElf_Shdr shdr; Elf_Data *data; GElf_Dyn dyn; if(elf_version(EV_CURRENT) == EV_NONE) error(EXIT_FAILURE, 0, "Library out of date."); if(argc != 2) error(EXIT_FAILURE, 0, "Usage: %s <filename>", argv[0]); if((fd = open(argv[1], O_RDONLY)) == -1) error(EXIT_FAILURE, 0, "Failed open file."); cmd = ELF_C_READ; if((arf = elf_begin(fd, cmd, (Elf *)0)) == NULL) error(EXIT_FAILURE, 0, "Failed open elf: %s", elf_errmsg ( -1)); while((elf = elf_begin(fd, cmd, arf)) != NULL) { if(gelf_getehdr(elf,&ehdr) != NULL) { scn = NULL; while((scn = elf_nextscn(elf, scn)) != NULL) { gelf_getshdr(scn, &shdr); if(shdr.sh_type != SHT_DYNAMIC) continue; printf("Section name: %s\n", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)); data = NULL; while((data = elf_getdata(scn, data)) != NULL) { if(data != NULL) for( i=0; gelf_getdyn(data, i, &dyn) != NULL; i++) { if(dyn.d_tag == DT_RPATH) printf("DT_RPATH found\n"); if(dyn.d_tag == DT_RUNPATH) printf("DT_RUNPATH found\n"); } } } } cmd = elf_next(elf); elf_end(elf); } elf_end(arf); close(fd); }