Beispiel #1
0
static void
find_section_base(const char *exe, Elf *e, const char *section)
{
	Dwarf_Addr off;
	Elf_Scn *scn;
	GElf_Ehdr eh;
	GElf_Shdr sh;
	size_t shstrndx;
	int elferr;
	const char *name;

	if (gelf_getehdr(e, &eh) != &eh) {
		warnx("gelf_getehdr failed: %s", elf_errmsg(-1));
		return;
	}

	if (!elf_getshstrndx(e, &shstrndx)) {
		warnx("elf_getshstrndx failed: %s", elf_errmsg(-1));
		return;
	}

	(void) elf_errno();
	off = 0;
	scn = NULL;
	while ((scn = elf_nextscn(e, scn)) != NULL) {
		if (gelf_getshdr(scn, &sh) == NULL) {
			warnx("gelf_getshdr failed: %s", elf_errmsg(-1));
			continue;
		}
		if ((name = elf_strptr(e, shstrndx, sh.sh_name)) == NULL)
			goto next;
		if (!strcmp(section, name)) {
			if (eh.e_type == ET_EXEC || eh.e_type == ET_DYN) {
				/*
				 * For executables, section base is the virtual
				 * address of the specified section.
				 */
				section_base = sh.sh_addr;
			} else if (eh.e_type == ET_REL) {
				/*
				 * For relocatables, section base is the
				 * relative offset of the specified section
				 * to the start of the first section.
				 */
				section_base = off;
			} else
				warnx("unknown e_type %u", eh.e_type);
			return;
		}
	next:
		off += sh.sh_size;
	}
	elferr = elf_errno();
	if (elferr != 0)
		warnx("elf_nextscn failed: %s", elf_errmsg(elferr));

	errx(EXIT_FAILURE, "%s: cannot find section %s", exe, section);
}
Beispiel #2
0
void
ld_dynamic_load_dso_dynamic(struct ld *ld, struct ld_input *li, Elf *e,
    Elf_Scn *scn, size_t strndx)
{
	GElf_Shdr shdr;
	GElf_Dyn dyn;
	Elf_Data *d;
	int elferr, i, len;
	const char *name;

	if (strndx == SHN_UNDEF)
		return;

	if (gelf_getshdr(scn, &shdr) != &shdr) {
		ld_warn(ld, "%s: gelf_getshdr failed: %s", li->li_name,
		    elf_errmsg(-1));
		return;
	}

	(void) elf_errno();
	if ((d = elf_getdata(scn, NULL)) == NULL) {
		elferr = elf_errno();
		if (elferr != 0)
			ld_warn(ld, "%s: elf_getdata failed: %s", li->li_name,
			    elf_errmsg(elferr));
		return;
	}

	len = d->d_size / shdr.sh_entsize;
	for (i = 0; i < len; i++) {
		if (gelf_getdyn(d, i, &dyn) != &dyn) {
			ld_warn(ld, "%s: gelf_getdyn failed: %s", li->li_name,
			    elf_errmsg(-1));
			continue;
		}
		switch (dyn.d_tag) {
		case DT_SONAME:
			name = elf_strptr(e, strndx, dyn.d_un.d_ptr);
			if (name != NULL &&
			    (li->li_soname = strdup(name)) == NULL)
				ld_fatal_std(ld, "strdup");
			break;
		case DT_NEEDED:
			name = elf_strptr(e, strndx, dyn.d_un.d_ptr);
			if (name != NULL)
				ld_path_search_dso_needed(ld, li->li_file,
				    name);
			break;
		default:
			break;
		}
	}
}
Beispiel #3
0
void
elferr()
{
fprintf(stderr, "%s: %s\n", prog, elf_errmsg(elf_errno()));

exit(1);
}
void
tcBadElf_tpElf(void)
{
	int err;
	Elf *e;
	TS_PHDR *ph;
	char badelf[sizeof(badelftemplate)];

	TP_CHECK_INITIALIZATION();

	tet_infoline("assertion: " TS_ICNAME "() on a malformed ELF file "
	    "fails with ELF_E_HEADER.");

	(void) memcpy(badelf, badelftemplate, sizeof(badelf));
	badelf[EI_VERSION] = EV_CURRENT;
	badelf[EI_CLASS]   = TS_ELFCLASS;

	TS_OPEN_MEMORY(e, badelf);

	if ((ph = TS_ICFUNC(e)) != NULL ||
	    (err = elf_errno()) != ELF_E_HEADER) {
		tet_printf("fail: error=%d ph=%p.", err, (void *) ph);
		tet_result(TET_FAIL);
	} else
		tet_result(TET_PASS);

	(void) elf_end(e);
}
static inline int
canonicalize (Dwfl_Error error)
{
  unsigned int value;

  switch (error)
    {
    default:
      value = error;
      if ((value &~ 0xffff) != 0)
	break;
      assert (value < nmsgidx);
      break;
    case DWFL_E_ERRNO:
      value = DWFL_E (ERRNO, errno);
      break;
    case DWFL_E_LIBELF:
      value = DWFL_E (LIBELF, elf_errno ());
      break;
    case DWFL_E_LIBDW:
      value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ());
      break;
#if 0
    DWFL_E_LIBEBL:
      value = DWFL_E (LIBEBL, ebl_errno ());
      break;
#endif
    }

  return value;
}
/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD.
   When we return success, FILE->elf and FILE->bias are set up.  */
static inline Dwfl_Error
open_elf (Dwfl_Module *mod, struct dwfl_file *file)
{
  if (file->elf == NULL)
    {
      /* If there was a pre-primed file name left that the callback left
	 behind, try to open that file name.  */
      if (file->fd < 0 && file->name != NULL)
	file->fd = TEMP_FAILURE_RETRY (open64 (file->name, O_RDONLY));

      if (file->fd < 0)
	return CBFAIL;

      file->elf = elf_begin (file->fd, ELF_C_READ_MMAP_PRIVATE, NULL);
    }

  if (unlikely (elf_kind (file->elf) != ELF_K_ELF))
    {
      close (file->fd);
      file->fd = -1;
      return DWFL_E_BADELF;
    }

  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
  if (ehdr == NULL)
    {
    elf_error:
      close (file->fd);
      file->fd = -1;
      return DWFL_E (LIBELF, elf_errno ());
    }

  /* The addresses in an ET_EXEC file are absolute.  The lowest p_vaddr of
     the main file can differ from that of the debug file due to prelink.
     But that doesn't not change addresses that symbols, debuginfo, or
     sh_addr of any program sections refer to.  */
  file->bias = 0;
  if (mod->e_type != ET_EXEC)
    for (uint_fast16_t i = 0; i < ehdr->e_phnum; ++i)
      {
	GElf_Phdr ph_mem;
	GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem);
	if (ph == NULL)
	  goto elf_error;
	if (ph->p_type == PT_LOAD)
	  {
	    file->bias = ((mod->low_addr & -ph->p_align)
			  - (ph->p_vaddr & -ph->p_align));
	    break;
	  }
      }

  mod->e_type = ehdr->e_type;

  /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN.  */
  if (mod->e_type == ET_EXEC && file->bias != 0)
    mod->e_type = ET_DYN;

  return DWFL_E_NOERROR;
}
Beispiel #7
0
static void check_libelf_version()
{
    if (elf_version(EV_CURRENT) == EV_NONE) {
        fprintf(stderr, "elf initialization failed: %s\n",
                elf_errmsg(elf_errno()));
        exit(1);
    }
}
void
tcElf_tpCorruptEhdr(void)
{
	int err, fd, result;
	char *fn;
	Elf *e;
	TS_PHDR *ph;

	TP_CHECK_INITIALIZATION();

	tet_infoline("assertion: " TS_ICNAME "(E) with corrupt phdr values "
	    "the header returns E_HEADER.");

	fn = "ehdr.msb" __XSTRING(TS_PHDRSZ);
	TS_OPEN_FILE(e, fn, ELF_C_READ, fd);

	result = TET_PASS;

	if ((ph = TS_ICFUNC(e)) != NULL ||
	    (err = (elf_errno() != ELF_E_HEADER))) {
		tet_printf("fail: \"%s\" (ph %p, error %d)", fn, (void *) ph,
		    err);
		result = TET_FAIL;
	}
	(void) elf_end(e);
	(void) close(fd);

	if (result != TET_PASS) {
		tet_result(result);
		return;
	}

	fn = "ehdr.lsb" __XSTRING(TS_PHDRSZ);
	TS_OPEN_FILE(e, fn, ELF_C_READ, fd);

	if ((ph = TS_ICFUNC(e)) != NULL ||
	    (err = (elf_errno() != ELF_E_HEADER))) {
		tet_printf("fail: \"%s\" (ph %p, error %d)", fn, (void *) ph,
		    err);
		result = TET_FAIL;
	}
	(void) elf_end(e);
	(void) close(fd);

	tet_result(result);
}
Beispiel #9
0
/*
 * Wrapper on msg_fatal() that issues an error that results from
 * a call to libelf.
 *
 * entry:
 *	file - Name of ELF object
 *	libelf_rtn_name - Name of routine that was called
 *
 * exit:
 *	An error has been issued that shows the routine called
 *	and the libelf error string for it from elf_errmsg().
 *	This routine does not return to the caller.
 */
static void
msg_elf(const char *libelf_rtn_name)
{
	const char *errstr = elf_errmsg(elf_errno());

	msg_fatal("%s: %s failed: %s\n", file,
	    libelf_rtn_name, errstr ? errstr : "<unknown>");
}
Beispiel #10
0
void
tcElf_tpElfWrongSize(void)
{
	int error, fd, result;
	Elf *e;
	char *fn;
	TS_PHDR *ph;

	TP_CHECK_INITIALIZATION();

	tet_infoline("assertion: a call to " TS_ICNAME "() and a mismatched "
	    "ELF class fails with ELF_E_CLASS.");

	result = TET_PASS;

	fn = "phdr.msb" __XSTRING(TS_OTHERSIZE);
	TS_OPEN_FILE(e,fn,ELF_C_READ,fd);

	if ((ph = TS_ICFUNC(e)) != NULL ||
	    (error = elf_errno()) != ELF_E_CLASS) {
		tet_printf("fail: \"%s\" opened (error %d).", fn, error);
		result = TET_FAIL;
	}

	(void) elf_end(e);
	(void) close(fd);

	if (result != TET_PASS) {
		tet_result(result);
		return;
	}

	fn = "phdr.lsb" __XSTRING(TS_OTHERSIZE);
	TS_OPEN_FILE(e,fn,ELF_C_READ,fd);
	if ((ph = TS_ICFUNC(e)) != NULL ||
	    (error = elf_errno()) != ELF_E_CLASS) {
		tet_printf("fail: \"%s\" opened (error %d).", fn, error);
		result = TET_FAIL;
	}

	(void) elf_end(e);
	(void) close(fd);

	tet_result(result);
}
void print_elf_errno(int line_number)
{
	int err;

	if ((err = elf_errno()) != 0) {
		fprintf(stderr, "%s (line %i): %s\n", PROGRAM_NAME, line_number, elf_errmsg(err));
		exit(3);
	}
}
Beispiel #12
0
/*
 * Create an archive descriptor.  By maintaining a list of archives any
 * duplicate occurrences of the same archive specified by the user enable us to
 * pick off where the last processing finished.
 */
Ar_desc *
ld_ar_setup(const char *name, Elf *elf, Ofl_desc *ofl)
{
	Ar_desc *	adp;
	size_t		number;
	Elf_Arsym *	start;

	/*
	 * Unless, -z allextract is specified, get the archive symbol table
	 * if one exists, and ignore the file with a warning message otherwise.
	 */
	if (ofl->ofl_flags1 & FLG_OF1_ALLEXRT) {
		start = NULL;
	} else  if ((start = elf_getarsym(elf, &number)) == NULL) {
		if (elf_errno())
			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETARSYM),
			    name);
		else
			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ELF_ARSYM),
			    name);
		return (0);
	}

	/*
	 * As this is a new archive reference establish a new descriptor.
	 */
	if ((adp = libld_malloc(sizeof (Ar_desc))) == NULL)
		return ((Ar_desc *)S_ERROR);
	adp->ad_name = name;
	adp->ad_elf = elf;
	adp->ad_start = start;
	if (start) {
		adp->ad_aux = libld_calloc(sizeof (Ar_aux), number);
		if (adp->ad_aux == NULL)
			return ((Ar_desc *)S_ERROR);
	} else {
		adp->ad_aux = NULL;
	}

	/*
	 * Retain any command line options that are applicable to archive
	 * extraction in case we have to rescan this archive later.
	 */
	adp->ad_flags = ofl->ofl_flags1 & MSK_OF1_ARCHIVE;

	ofl->ofl_arscnt++;

	/*
	 * Add this new descriptor to the list of archives.
	 */
	if (aplist_append(&ofl->ofl_ars, adp, AL_CNT_OFL_LIBS) == NULL)
		return ((Ar_desc *)S_ERROR);
	else
		return (adp);
}
Beispiel #13
0
void
tcNull_tpGet(void)
{
	TP_CHECK_INITIALIZATION();

	tet_infoline("assertion: " TS_ICNAME "(NULL) fails with "
	    "ELF_E_ARGUMENT.");

	if (TS_ICFUNC(NULL) != NULL ||
	    elf_errno() != ELF_E_ARGUMENT)
		tet_result(TET_FAIL);
	else
		tet_result(TET_PASS);
}
Beispiel #14
0
void
tcData_tpElf(void)
{
	Elf *e;

	TP_CHECK_INITIALIZATION();

	tet_infoline("assertion: " TS_ICNAME "(E) for non-ELF (E) fails with "
	    "ELF_E_ARGUMENT.");

	TS_OPEN_MEMORY(e, data);

	if (TS_ICFUNC(e) != NULL ||
	    elf_errno() != ELF_E_ARGUMENT)
		tet_result(TET_FAIL);
	else
		tet_result(TET_PASS);

	(void) elf_end(e);
}
Beispiel #15
0
static int read_phdr(struct elf32_info *info, FILE *in)
{
	int i;

	if (info->file_ehdr.e_phnum > MAX_PHDRS) {
		printc_err("elf32: too many program headers: %d\n",
			info->file_ehdr.e_phnum);
		return -1;
	}

	for (i = 0; i < info->file_ehdr.e_phnum; i++) {
		GElf_Phdr *phdr = &info->file_phdrs[i];
		if (gelf_getphdr(info->elf, i, phdr) != phdr) {
			printc_err("elf32: can't read phdr %d: %s\n",
				i, elf_errmsg(elf_errno()));
		}
	}

	return 0;
}
Beispiel #16
0
/* Given Elf header, Elf_Scn, and Elf32_Shdr 
 * print out the symbol table 
 */
static _Bool print_symbols(Elf *elf, Elf_Scn *scn, GElf_Shdr *shdr)
{
	Elf_Data *data;
	char *name;
	char *stringName;
	data = 0;
	int number = 0;
	if ((data = elf_getdata(scn, data)) == 0 || data->d_size == 0)
	{
		/* error or no data */
		fprintf(stderr, "Section had no data!\n");
			exit(-1);
	}
	/*now print the symbols*/
	unsigned count = symtab_shdr.sh_size / symtab_shdr.sh_entsize;
	//fprintf(stderr, "Total symbols count: %u\n", count);
	/* now loop through the symbol table and print it*/
	for (unsigned i = 0; i < count; ++i)
	{
		//fprintf(stderr, "Index is %u\n", i);
		GElf_Sym esym;
		GElf_Sym *ret = gelf_getsym(data, i, &esym);
		if (ret == 0) { fprintf(stderr, "Error!\n"); return FALSE; }
		if ((esym.st_value == 0) ||
			(GELF_ST_BIND(esym.st_info)== STB_WEAK) ||
			(GELF_ST_BIND(esym.st_info)== STB_NUM)) 
				continue;
		//fprintf(stderr, "Symbol has strtab offset %zu\n", (size_t)esym.st_name);
		name = elf_strptr(elf, shdr->sh_link, (size_t)esym.st_name);
		if(!name)
		{
			fprintf(stderr,"%s\n",elf_errmsg(elf_errno()));
			exit(-1);
		}
		printf("%d: %s\n", number++, name);
	}
	return TRUE;
}
Beispiel #17
0
Datei: die.c Projekt: 0mp/freebsd
void
elfdie(char *format, ...)
{
	va_list ap;
#ifndef illumos
	const char *progname = getprogname();
#endif

	(void) fprintf(stderr, "%s: ", progname);

	va_start(ap, format);
	/* LINTED - variable format specifier */
	(void) vfprintf(stderr, format, ap);
	va_end(ap);

	if (format[strlen(format) - 1] != '\n')
		(void) fprintf(stderr, ": %s\n", elf_errmsg(elf_errno()));

#ifndef illumos
	exit(0);
#else
	exit(1);
#endif
}
int
main (void)
{
  size_t cnt;
  int result = EXIT_SUCCESS;

  /* Clear the error state.  */
  (void) elf_errno ();

  /* Check all the messages of libelf.  */
  for (cnt = 1; cnt < ELF_E_NUM; ++cnt)
    {
      const char *str = elf_errmsg (libelf_msgs[cnt].id);

      if (strcmp (str, libelf_msgs[cnt].expected) != 0)
	{
	  printf ("libelf msg %zu: expected \"%s\", got \"%s\"\n",
		  cnt, libelf_msgs[cnt].expected, str);
	  result = EXIT_FAILURE;
	}
    }

  return result;
}