Exemple #1
0
char *
elf_strptr(Elf * elf, size_t ndx, size_t off)
{
	Elf_Scn *	s;
	Elf_Data *	d;
	char *		rc;

	if (elf == 0)
		return (0);
		
	extern const char *elf_macho_str_off(size_t off);
	
	if (elf->ed_kind == ELF_K_MACHO && (ndx == SHN_MACHO || ndx == SHN_MACHO_64))
		return (char *)elf_macho_str_off(off);

	if ((s = elf_getscn(elf, ndx)) == 0) {
		_elf_seterr(EREQ_STRSCN, 0);
		return (0);
	}
	READLOCKS(elf, s)
	if (elf->ed_class == ELFCLASS32) {
		Elf32_Shdr* sh = (Elf32_Shdr*)s->s_shdr;

		if ((sh == 0) || (sh->sh_type != SHT_STRTAB)) {
			_elf_seterr(EREQ_STRSCN, 0);
			READUNLOCKS(elf, s)
			return (0);
		}
static Dwarf *
scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Dwarf_Cmd cmd,
	     Elf_Scn *scngrp)
{
  /* SCNGRP is the section descriptor for a section group which might
     contain debug sections.  */
  Elf_Data *data = elf_getdata (scngrp, NULL);
  if (data == NULL)
    {
      /* We cannot read the section content.  Fail!  */
      free (result);
      return NULL;
    }

  /* The content of the section is a number of 32-bit words which
     represent section indices.  The first word is a flag word.  */
  Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
  size_t cnt;
  for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
    {
      Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
      if (scn == NULL)
	{
	  /* A section group refers to a non-existing section.  Should
	     never happen.  */
	  __libdw_seterrno (DWARF_E_INVALID_ELF);
	  free (result);
	  return NULL;
	}

      check_section (result, ehdr, scn, true);
    }

  return valid_p (result);
}
Exemple #3
0
static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
				    GElf_Shdr *shp, const char *name,
				    size_t *idx)
{
	Elf_Scn *sec = NULL;
	size_t cnt = 1;

	/* Elf is corrupted/truncated, avoid calling elf_strptr. */
	if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL))
		return NULL;

	while ((sec = elf_nextscn(elf, sec)) != NULL) {
		char *str;

		gelf_getshdr(sec, shp);
		str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
		if (!strcmp(name, str)) {
			if (idx)
				*idx = cnt;
			break;
		}
		++cnt;
	}

	return sec;
}
Exemple #4
0
int find_symbol(char *fn, struct lsym *lsym, unsigned long baseaddr)
{
	struct lsym *ls;
	int num = 0;
	for (ls = lsym; ls->name; ls++)
		num++;

	elf_version(EV_CURRENT);
	int fd = open(fn, O_RDONLY);
	if (fd < 0)
		return -1;

	long ret = -1;
	Elf *elf = elf_begin(fd, ELF_C_READ, NULL);
	if (elf == NULL)
		goto out;

	GElf_Ehdr header;
	if (!gelf_getehdr(elf, &header))
		goto out_elf;

	Elf_Scn *section = NULL;
	int found = 0;
	while (found < num && (section = elf_nextscn(elf, section)) != 0) {
		GElf_Shdr shdr, *sh;
		sh = gelf_getshdr(section, &shdr);

		if (sh->sh_type == SHT_SYMTAB || sh->sh_type == SHT_DYNSYM) {
			Elf_Data *data = elf_getdata(section, NULL);
			GElf_Sym *sym, symbol;
			int j;

			unsigned numsym = sh->sh_size / sh->sh_entsize;
			for (j = 0; j < numsym; j++) {
				sym = gelf_getsymshndx(data, NULL, j, &symbol, NULL);
				char *symname = elf_strptr(elf, shdr.sh_link, sym->st_name);
				for (ls = lsym; ls->name; ls++) {
					if (!strcmp(symname, ls->name)) {
						Elf_Scn *oscn = elf_getscn(elf, sym->st_shndx);
						GElf_Shdr oshdr, *osh;
						osh = gelf_getshdr(oscn, &oshdr);
						ls->addr = (sym->st_value - osh->sh_addr) + osh->sh_offset + baseaddr;
						found++;
						if (found == num)
							break;
					}
				}
			}
		}
	}
	if (found == num)
		ret = 0;

out_elf:
	elf_end(elf);

out:
	close(fd);
	return ret;
}
Exemple #5
0
int
elf_getphnum(Elf *elf, size_t *phnum)
{
	GElf_Ehdr	ehdr;
	Elf_Scn		*scn;
	GElf_Shdr	shdr0;

	if (gelf_getehdr(elf, &ehdr) == NULL)
		return (0);

	if (ehdr.e_phnum != PN_XNUM) {
		*phnum = ehdr.e_phnum;
		return (1);
	}

	if ((scn = elf_getscn(elf, 0)) == NULL ||
	    gelf_getshdr(scn, &shdr0) == NULL)
		return (0);

	if (shdr0.sh_info == 0)
		*phnum = ehdr.e_phnum;
	else
		*phnum = shdr0.sh_info;

	return (1);
}
Exemple #6
0
static void handle_dynamic_section(elf_info_s *elf, Elf_Scn *scn, GElf_Shdr shdr)
{
    Elf_Data *data;
    GElf_Addr replt_addr;
    size_t replt_count;

    /* get data of .dynamic */
    data = elf_getdata(scn, NULL);

    /* iterate through .dynamic */
    for (size_t i = 0; i < shdr.sh_size / shdr.sh_entsize; ++i) {
        GElf_Dyn dyn;

        // get entries i
        gelf_getdyn(data, i, &dyn);
        // if replt
        if (dyn.d_tag == DT_JMPREL)
            replt_addr = dyn.d_un.d_ptr;
        // if replt_size
        if (dyn.d_tag == DT_PLTRELSZ)
            replt_count = dyn.d_un.d_val;
    }
    LOG(INFO, "Section relplt at 0x%lx (%zu)", replt_addr, replt_count);
    for (size_t i = 1; i < elf->hdr.e_shnum; ++i) {
        Elf_Scn *scn;
        GElf_Shdr shdr;
        scn = elf_getscn(elf->elf, i);
        gelf_getshdr(scn, &shdr);
        if (shdr.sh_addr == replt_addr && shdr.sh_size == replt_count) {
            elf->replt = elf_getdata(scn, NULL);
            elf->replt_count = shdr.sh_size / shdr.sh_entsize;
            break;
        }
    }
}
Exemple #7
0
Elf_Scn *
get_scnbyname(Elf *elf, char *name, int *num)
{
	Elf32_Ehdr	* ehdr;
	Elf_Scn		* scn;
	Elf32_Shdr	* shdr;
	Elf_Data	* data;
	int		  cnt,
			  tmp;

	if (!num)
		num = &tmp;
	
	*num = 0;

	if ((ehdr = elf32_getehdr(elf))==NULL)
		return NULL;

	if (((scn = elf_getscn(elf, ehdr->e_shstrndx)) == NULL) ||
	    ((data = elf_getdata(scn, NULL)) == NULL))
		return NULL;

	for (cnt = 1, scn = NULL; (scn = elf_nextscn(elf, scn)); cnt++) {
		if ((shdr = elf32_getshdr(scn)) == NULL)
			return NULL;

		if (! strcmp(name, (char *)data->d_buf + shdr->sh_name)) {
			*num = cnt;
			return scn;
		}
	}
	return NULL;
}
Exemple #8
0
char*
elf_strptr(Elf *elf, size_t section, size_t offset) {
    Elf_Scn *scn;
    Elf_Data *sd;

    if (!elf) {
	return NULL;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    if (!(scn = elf_getscn(elf, section))) {
	return NULL;
    }
    if (scn->s_type != SHT_STRTAB) {
	seterr(ERROR_NOSTRTAB);
	return NULL;
    }
    if (offset >= 0 && offset < scn->s_size) {
	sd = NULL;
	while ((sd = elf_getdata(scn, sd))) {
	    if (sd->d_buf
	     && offset >= (size_t)sd->d_off
	     && offset < (size_t)sd->d_off + sd->d_size) {
		return (char*)sd->d_buf + (offset - sd->d_off);
	    }
	}
    }
    seterr(ERROR_BADSTROFF);
    return NULL;
}
Exemple #9
0
Elf_Scn *elf_utils_new_scn_with_name(Elf *e, const char *scn_name)
{
	Elf_Scn *scn;
	GElf_Shdr shdr;
	size_t shstrndx, index, namelen;
	Elf_Data *shstrdata;
	void *ptr;

	ELF_ASSERT(elf_getshdrstrndx(e, &shstrndx) == 0);

	ELF_ASSERT(scn = elf_getscn(e, shstrndx));
	ELF_ASSERT(shstrdata = elf_getdata(scn, NULL));

	namelen = strlen(scn_name) + 1;
	ELF_ASSERT(gelf_getshdr(scn, &shdr));
	if (!elf_utils_shift_contents(e, shdr.sh_offset + shdr.sh_size, namelen))
		goto failure;
	ASSERT(ptr = realloc(shstrdata->d_buf, shstrdata->d_size + namelen));
	index = shstrdata->d_size;
	strcpy(ptr+index, scn_name);
	shstrdata->d_buf = ptr;
	shstrdata->d_size += namelen;
	shdr.sh_size += namelen;
	ELF_ASSERT(gelf_update_shdr(scn, &shdr));

	ELF_ASSERT(scn = elf_newscn(e));
	ELF_ASSERT(gelf_getshdr(scn, &shdr));
	shdr.sh_name = index;
	ELF_ASSERT(gelf_update_shdr(scn, &shdr));
	
	return scn;
failure:
	return NULL;
}
bool
addr_in_section (Elf *elf, GElf_Word shndx, GElf_Addr addr)
{
  GElf_Shdr shdr;
  Elf_Scn *scn = elf_getscn (elf, shndx);
  gelf_getshdr (scn, &shdr);
  return addr >= shdr.sh_addr && addr < shdr.sh_addr + shdr.sh_size;
}
Exemple #11
0
static void
set_flag(char *ifile, ulong_t flval)
{
	Elf *elf;
	Elf_Scn *scn;
	Elf_Data *data;
	GElf_Shdr shdr;
	GElf_Dyn dyn;
	int fd, secidx, nent, i;

	(void) elf_version(EV_CURRENT);

	if ((fd = open(ifile, O_RDWR)) < 0)
		die("Can't open %s", ifile);

	if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL)
		elfdie("Can't start ELF for %s", ifile);

	if ((secidx = findelfsecidx(elf, ".dynamic")) == -1)
		die("Can't find .dynamic section in %s\n", ifile);

	if ((scn = elf_getscn(elf, secidx)) == NULL)
		elfdie("elf_getscn (%d)", secidx);

	if (gelf_getshdr(scn, &shdr) == NULL)
		elfdie("gelf_shdr");

	if ((data = elf_getdata(scn, NULL)) == NULL)
		elfdie("elf_getdata");

	nent = shdr.sh_size / shdr.sh_entsize;
	for (i = 0; i < nent; i++) {
		if (gelf_getdyn(data, i, &dyn) == NULL)
			elfdie("gelf_getdyn");

		if (dyn.d_tag == DT_FLAGS_1) {
			dyn.d_un.d_val |= (Elf64_Xword)flval;

			if (gelf_update_dyn(data, i, &dyn) == 0)
				elfdie("gelf_update_dyn");

			break;
		}
	}

	if (i == nent) {
		die("%s's .dynamic section doesn't have a DT_FLAGS_1 "
		    "field\n", ifile);
	}

	if (elf_update(elf, ELF_C_WRITE) == -1)
		elfdie("Couldn't update %s with changes", ifile);

	(void) elf_end(elf);
	(void) close(fd);
}
Exemple #12
0
Elf_Scn *xelf_getscn(Elf *e, size_t idx)
{
  Elf_Scn *scn = elf_getscn(e, idx);
  if (scn == NULL)
	{
	  eprintf("elf_getscn() failed: %s", elf_errmsg(-1));
	  exit(EXIT_FAILURE);
	}
  return scn;
}
static const char *
elf_section_name (Elf *elf, GElf_Word shndx)
{
  GElf_Ehdr ehdr;
  GElf_Shdr shdr;
  Elf_Scn *scn = elf_getscn (elf, shndx);
  gelf_getshdr (scn, &shdr);
  gelf_getehdr (elf, &ehdr);
  return elf_strptr (elf, ehdr.e_shstrndx, shdr.sh_name);
}
/*
	Load the ELF section with the specified index and set the
	pointer pointed to by section_data to the memory where it
	was loaded.
 */
int
_dwarf_load_section(Dwarf_Debug dbg,
		    Dwarf_Half section_index,
		    Dwarf_Small ** section_data,
		    Dwarf_Error * error)
{
    if (section_index == 0) {
	return DW_DLV_NO_ENTRY;
    }

    /* check to see if the section is already loaded */
    if (*section_data != NULL) {
	return DW_DLV_OK;
    }

    {
#ifdef __SGI_FAST_LIBELF
        enum elf_sgi_error_type sres;

        sres = elf_sgi_section(dbg->de_elf,
		               section_index,
			       (void**) section_data);
        if (sres != ELF_SGI_ERROR_OK) {
	    DWARF_DBG_ERROR(dbg, _dwarf_error_code_from_elf_sgi_error_code(sres),
			    DW_DLV_ERROR);
        }
#else
        Elf_Scn* scn;
        Elf_Data* data;

        scn = elf_getscn(dbg->de_elf, section_index);
        if (scn == NULL) {
	    _dwarf_error(dbg, error, DW_DLE_MDE);
	    return DW_DLV_ERROR;
        }

	/* 
	    When using libelf as a producer, section data may be stored
	    in multiple buffers. In libdwarf however, we only use libelf
	    as a consumer (there is a dwarf producer API, but it doesn't
	    use libelf). Because of this, this single call to elf_getdata
	    will retrieve the entire section in a single contiguous buffer.
	 */
        data = elf_getdata(scn, NULL);
        if (data == NULL) {
	    _dwarf_error(dbg, error, DW_DLE_MDE);
	    return DW_DLV_ERROR;
        }

        *section_data = data->d_buf;
#endif /* !defined(__SGI_FAST_LIBELF) */
    }

    return DW_DLV_OK;
}
Exemple #15
0
unsigned long
_libelf_checksum(Elf *e, int elfclass)
{
	size_t shn;
	Elf_Scn *scn;
	Elf_Data *d;
	unsigned long checksum;
	GElf_Ehdr eh;
	GElf_Shdr shdr;

	if (e == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0L);
	}

	if (e->e_class != elfclass) {
		LIBELF_SET_ERROR(CLASS, 0);
		return (0L);
	}

	if (gelf_getehdr(e, &eh) == NULL)
		return (0);

	/*
	 * Iterate over all sections in the ELF file, computing the
	 * checksum along the way.
	 *
	 * The first section is always SHN_UNDEF and can be skipped.
	 * Non-allocatable sections are skipped, as are sections that
	 * could be affected by utilities such as strip(1).
	 */

	checksum = 0;
	for (shn = 1; shn < e->e_u.e_elf.e_nscn; shn++) {
		if ((scn = elf_getscn(e, shn)) == NULL)
			return (0);
		if (gelf_getshdr(scn, &shdr) == NULL)
			return (0);
		if ((shdr.sh_flags & SHF_ALLOC) == 0 ||
		    shdr.sh_type == SHT_DYNAMIC ||
		    shdr.sh_type == SHT_DYNSYM)
			continue;

		d = NULL;
		while ((d = elf_rawdata(scn, d)) != NULL)
			checksum = _libelf_sum(checksum,
			    (unsigned char *) d->d_buf, d->d_size);
	}

	/*
	 * Return a 16-bit checksum compatible with Solaris.
	 */
	return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL));
}
/*
 * Load template of the function described by the given symbol.
 */
static struct code_template* function_template_load32(Elf* e, Elf32_Sym* func32)
{
    Elf_Scn* scn = elf_getscn(e, func32->st_shndx);
    assert(scn);
    
    Elf32_Shdr* shdr32 = elf32_getshdr(scn);
    assert(shdr32);
    
    return ct_load(e, scn, func32->st_value, func32->st_size,
        shdr32->sh_addralign);
}
static struct code_template* function_template_load64(Elf* e, Elf64_Sym* func64)
{
    Elf_Scn* scn = elf_getscn(e, func64->st_shndx);
    assert(scn);
    
    Elf64_Shdr* shdr64 = elf64_getshdr(scn);
    assert(shdr64);
    
    return ct_load(e, scn, func64->st_value, func64->st_size,
        shdr64->sh_addralign);
}
Exemple #18
0
Elf_Scn *
elf_nextscn(Elf *e, Elf_Scn *s)
{
        if (e == NULL || (e->e_kind != ELF_K_ELF) ||
            (s && s->s_elf != e)) {
                LIBELF_SET_ERROR(ARGUMENT, 0);
                return (NULL);
        }

        return (s == NULL ? elf_getscn(e, (size_t) 1) :
            STAILQ_NEXT(s, s_next));
}
Exemple #19
0
static int init_scns()
{
	Elf* e = g.e;
	size_t shstrndx = g.shstrndx;
	size_t shdrnum = g.shdrnum;

	int i = 0;
	GElf_Shdr shdr;
	Elf_Scn** buf   = (Elf_Scn**)malloc(shdrnum * sizeof(Elf_Scn*));
	GElf_Shdr* buf2 = (GElf_Shdr*)malloc(shdrnum * sizeof(GElf_Shdr));

	if (buf == NULL) {
		errx (EXIT_FAILURE , "malloc failed");
		return -1;
	}
	Elf_Scn *scn = NULL;
	while ((scn = elf_nextscn(e, scn)) != NULL && i < shdrnum) {
		if (gelf_getshdr (scn , & shdr ) != & shdr) {
			errx ( EXIT_FAILURE , " getshdr ()  failed : %s.",
			       elf_errmsg ( -1));
			free(buf);
			return -1;
		}
		buf[i]  = scn;
		buf2[i] = shdr;
		i++;
	}

	if (i < shdrnum) {
	  /* the .shstrtab section*/
	  /* size_t shstrndx; */
	  /* if (elf_getshdrstrndx (e, &shstrndx) != 0) */
	  /*   errx (EXIT_FAILURE, " getshdrstrndx ()  failed : %s.", */
	  /* 	  elf_errmsg (-1)); */
	  if ((scn = elf_getscn (e, shstrndx)) == NULL )
	    errx ( EXIT_FAILURE , " getscn ()  failed : %s.",
		   elf_errmsg ( -1));
	  if (gelf_getshdr(scn , &shdr) != & shdr )
	    errx ( EXIT_FAILURE , " getshdr ( shstrndx )  failed : %s.",
		   elf_errmsg ( -1));
	  buf[i] = scn;
	  buf2[i] = shdr;
	}

	// printf("[D] No. of sections:%d\n", i-1);
	
	g.scns  = buf;
	g.shdrs = buf2;
	
	return 0;
}
Exemple #20
0
static int
is_function(Elf *elf, GElf_Sym *sym)
{
	Elf_Scn		*scn;
	GElf_Shdr	shdr;

	/*
	 * With dynamic linking, it is possible that certain undefined
	 * symbols exist in the objects. The actual definition will be
	 * found elsewhere, so we'll just skip it for this object.
	 */
	if (sym->st_shndx == SHN_UNDEF)
		return (0);

	if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) {
		if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
			return (1);

		if (GELF_ST_BIND(sym->st_info) == STB_WEAK)
			return (1);

		if (gflag && GELF_ST_BIND(sym->st_info) == STB_LOCAL)
			return (1);
	}

	/*
	 * It's not a function; determine if it's in an executable section.
	 */
	if (GELF_ST_TYPE(sym->st_info) != STT_NOTYPE)
		return (0);

	/*
	 * If it isn't global, and it isn't weak, and it isn't
	 * a 'local with the gflag set', then get out.
	 */
	if (GELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
			GELF_ST_BIND(sym->st_info) != STB_WEAK &&
			!(gflag && GELF_ST_BIND(sym->st_info) == STB_LOCAL))
		return (0);

	if (sym->st_shndx >= SHN_LORESERVE)
		return (0);

	scn = elf_getscn(elf, sym->st_shndx);
	(void) gelf_getshdr(scn, &shdr);

	if (!(shdr.sh_flags & SHF_EXECINSTR))
		return (0);

	return (1);
}
Exemple #21
0
static void handle_dynsym_section(elf_info_s *elf, Elf_Scn *scn, GElf_Shdr shdr)
{
    Elf_Data *data;
    /* get .dynsym data and size */
    elf->dynsym = elf_getdata(scn, NULL);
    elf->dynsym_count = shdr.sh_size / shdr.sh_entsize;

    /* retrieve the header table index link which point to .dynstr */
    scn = elf_getscn(elf->elf, shdr.sh_link);
    gelf_getshdr(scn, &shdr);
    /* get the data of .dynstr */
    data = elf_getdata(scn, NULL);
    elf->dynstr = data->d_buf;
}
Exemple #22
0
Elf_Scn* getSection(Elf *elf,const char *name)
{
	Elf64_Ehdr *ehdr = elf64_getehdr(elf);
	if(!ehdr) return NULL;

	Elf_Data *data = elf_getdata(elf_getscn(elf,ehdr->e_shstrndx),NULL);
	if(!data) return NULL;

	for(Elf_Scn *scn = NULL;(scn = elf_nextscn(elf,scn));) {
		Elf64_Shdr *shdr = elf64_getshdr(scn);
		if(shdr && !strcmp(name,(const char*)data->d_buf + shdr->sh_name)) return scn;
	}
	return NULL;
}
Exemple #23
0
/* if this function encounters an error it never returns */
static void exec_getsection(
    Elf *elf, size_t index,
    Elf32_Shdr **shdr,
    Elf_Data **data,
    int line
)
#define exec_getsection(a,b,c,d) \
    exec_getsection(a,b,c,d,__LINE__)
{
    Elf_Scn *section;
    char *location;

    location = NULL;
    section = elf_getscn( elf, index );
    if ( section )
    {
        if ( shdr )
        {
            *shdr = elf32_getshdr(section);
            if ( *shdr == NULL )
            {
                location = "elf32_getshdr";
            }
        }
        if ( location == NULL && data )
        {
            *data = elf_getdata(section, NULL);
            if ( *data == NULL )
            {
                location = "elf_getdata";
            }
            else if ( (*data)->d_buf == NULL )
            {
                location = "d_buf";
            }
        }
        if ( location == NULL )
        {
            return;
        }
    }
    else
    {
        location = "elf_getscn";
    }
    fprintf( stderr, "exec_getsection: %s@%d - %s\n", location, line,
             elf_errmsg( -1 ) );
    exit( 1 );
}
Dwfl_Error
internal_function
__libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx,
			  Elf32_Word shndx, GElf_Addr *value)
{
  assert (mod->e_type == ET_REL);

  Elf_Scn *refscn = elf_getscn (elf, shndx);
  GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem);
  if (refshdr == NULL)
    return DWFL_E_LIBELF;

  if (refshdr->sh_addr == 0 && (refshdr->sh_flags & SHF_ALLOC))
    {
      /* This is a loaded section.  Find its actual
	 address and update the section header.  */

      if (*shstrndx == SHN_UNDEF
	  && unlikely (elf_getshdrstrndx (elf, shstrndx) < 0))
	return DWFL_E_LIBELF;

      const char *name = elf_strptr (elf, *shstrndx, refshdr->sh_name);
      if (unlikely (name == NULL))
	return DWFL_E_LIBELF;

      if ((*mod->dwfl->callbacks->section_address) (MODCB_ARGS (mod),
						    name, shndx, refshdr,
						    &refshdr->sh_addr))
	return CBFAIL;

      if (refshdr->sh_addr == (Dwarf_Addr) -1l)
	/* The callback indicated this section wasn't really loaded but we
	   don't really care.  */
	refshdr->sh_addr = 0;	/* Make no adjustment below.  */

      /* Update the in-core file's section header to show the final
	 load address (or unloadedness).  This serves as a cache,
	 so we won't get here again for the same section.  */
      if (likely (refshdr->sh_addr != 0)
	  && unlikely (! gelf_update_shdr (refscn, refshdr)))
	return DWFL_E_LIBELF;
    }

  if (refshdr->sh_flags & SHF_ALLOC)
    /* Apply the adjustment.  */
    *value += dwfl_adjusted_address (mod, refshdr->sh_addr);

  return DWFL_E_NOERROR;
}
Exemple #25
0
/*
 * Return TRUE(1) if the given section is ".bss" for "-p" option.
 * Return FALSE(0) if not ".bss" section.
 */
static int
is_bss_section(unsigned int shndx, Elf * elf_file, unsigned int shstrndx)
{
	Elf_Scn *scn		= elf_getscn(elf_file, shndx);
	char	*sym_name;

	if (scn != NULL) {
		GElf_Shdr shdr;
		(void) gelf_getshdr(scn, &shdr);
		sym_name = elf_strptr(elf_file, shstrndx, shdr.sh_name);
		if (strcmp(BSS_SECN, sym_name) == 0)
			return (1);
	}
	return (0);
}
Exemple #26
0
/*
 * Get section descriptor for the associated string table
 * and verify that the type of the section pointed to is
 * indeed of type STRTAB.  Returns a valid section descriptor
 * or NULL on error.
 */
static Elf_Scn *
get_scnfd(Elf * e_file, int shstrtab, int SCN_TYPE)
{
	Elf_Scn	*fd_scn;
	GElf_Shdr shdr;

	if ((fd_scn = elf_getscn(e_file, shstrtab)) == NULL) {
		return (NULL);
	}

	(void) gelf_getshdr(fd_scn, &shdr);
	if (shdr.sh_type != SCN_TYPE) {
		return (NULL);
	}
	return (fd_scn);
}
Exemple #27
0
void elf_utils_free_scn_contents(Elf *e, int scndx)
{
	Elf_Scn *scn;
	Elf_Data *data;

	ELF_ASSERT(scn = elf_getscn(e, scndx));

	data = NULL;
	while ((data = elf_getdata(scn, data)) != NULL) {
		free(data->d_buf);
		data->d_buf = NULL;
	}
		
failure:
	return;
}
Dwfl_Error
internal_function
__libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
{
  assert (mod->e_type == ET_REL);

  GElf_Ehdr ehdr_mem;
  const GElf_Ehdr *ehdr = gelf_getehdr (debugfile, &ehdr_mem);
  if (ehdr == NULL)
    return DWFL_E_LIBELF;

  size_t d_shstrndx;
  if (elf_getshdrstrndx (debugfile, &d_shstrndx) < 0)
    return DWFL_E_LIBELF;

  RELOC_SYMTAB_CACHE (reloc_symtab);

  /* Look at each section in the debuginfo file, and process the
     relocation sections for debugging sections.  */
  Dwfl_Error result = DWFL_E_NOERROR;
  Elf_Scn *scn = NULL;
  while (result == DWFL_E_NOERROR
	 && (scn = elf_nextscn (debugfile, scn)) != NULL)
    {
      GElf_Shdr shdr_mem;
      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);

      if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
	  && shdr->sh_size != 0)
	{
	  /* It's a relocation section.  */

	  Elf_Scn *tscn = elf_getscn (debugfile, shdr->sh_info);
	  if (unlikely (tscn == NULL))
	    result = DWFL_E_LIBELF;
	  else
	    result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
				       &reloc_symtab, scn, shdr, tscn,
				       debug, !debug);
	}
    }

  return result;
}
Exemple #29
0
int elf_utils_duplicate_scn_contents(Elf *e, int scndx)
{
	Elf_Scn *scn;
	Elf_Data *data;
	void *new_data;

	ELF_ASSERT(scn = elf_getscn(e, scndx));

	data = NULL;
	while ((data = elf_getdata(scn, data)) != NULL) {
		ASSERT(new_data = malloc(data->d_size));
		memcpy(new_data, data->d_buf, data->d_size);
		data->d_buf = new_data;
	}
		
	return 1;
failure:
	return 0;
}
Exemple #30
0
bool ElfWriter::addSectionData(int section_index, void *data, uint64_t size) {
  Elf_Scn *scn = elf_getscn(m_elf, section_index);
  if (!scn) {
    logError("Unable to retrieve section number");
    return false;
  }
  Elf_Data *elfData = elf_newdata(scn);
  if (!elfData) {
    logError("Unable to add section data");
    return false;
  }
  elfData->d_buf = data;
  elfData->d_type = ELF_T_BYTE;
  elfData->d_size = size;
  elfData->d_off = 0;
  elfData->d_align = 1;
  elfData->d_version = EV_CURRENT;
  return true;
}