Пример #1
0
/*
 * 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 */
}
Пример #2
0
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);
}
Пример #3
0
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;
	}
}
Пример #4
0
/*
 * 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);
}
Пример #5
0
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);
}
Пример #6
0
/*
 * 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);
}
Пример #7
0
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);
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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);
}
Пример #11
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);
}