Beispiel #1
0
GElf_Phdr *
gelf_getphdr(Elf *e, int index, GElf_Phdr *d)
{
	int ec;
	Elf32_Ehdr *eh32;
	Elf64_Ehdr *eh64;
	Elf32_Phdr *ep32;
	Elf64_Phdr *ep64;

	if (d == NULL || e == NULL ||
	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
	    (e->e_kind != ELF_K_ELF) || index < 0) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {
		if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL ||
		    ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL))
			return (NULL);

		if (index >= eh32->e_phnum) {
			LIBELF_SET_ERROR(ARGUMENT, 0);
			return (NULL);
		}

		ep32 += index;

		d->p_type   = ep32->p_type;
		d->p_offset = ep32->p_offset;
		d->p_vaddr  = (Elf64_Addr) ep32->p_vaddr;
		d->p_paddr  = (Elf64_Addr) ep32->p_paddr;
		d->p_filesz = (Elf64_Xword) ep32->p_filesz;
		d->p_memsz  = (Elf64_Xword) ep32->p_memsz;
		d->p_flags  = ep32->p_flags;
		d->p_align  = (Elf64_Xword) ep32->p_align;

	} else {
		if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL ||
		    (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL)
			return (NULL);

		if (index >= eh64->e_phnum) {
			LIBELF_SET_ERROR(ARGUMENT, 0);
			return (NULL);
		}

		ep64 += index;

		*d = *ep64;
	}

	return (d);
}
Beispiel #2
0
Elf_Scn *
elf_getscn(Elf *e, size_t index)
{
        int ec;
        void *ehdr;
        Elf_Scn *s;

        if (e == NULL || e->e_kind != ELF_K_ELF ||
            ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
                LIBELF_SET_ERROR(ARGUMENT, 0);
                return (NULL);
        }

        if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
                return (NULL);

        if (e->e_cmd != ELF_C_WRITE &&
            (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 &&
            _libelf_load_scn(e, ehdr) == 0)
                return (NULL);

        STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next)
                if (s->s_ndx == index)
                        return (s);

        LIBELF_SET_ERROR(ARGUMENT, 0);
        return (NULL);
}
Beispiel #3
0
GElf_Ehdr *
gelf_getehdr(Elf *e, GElf_Ehdr *d)
{
	int ec;
	Elf32_Ehdr *eh32;
	Elf64_Ehdr *eh64;

	if (d == NULL || e == NULL ||
	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {
		if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL)
			return (NULL);

		(void) memcpy(d->e_ident, eh32->e_ident,
		    sizeof(eh32->e_ident));
		d->e_type		= eh32->e_type;
		d->e_machine		= eh32->e_machine;
		d->e_version		= eh32->e_version;
		d->e_entry		= eh32->e_entry;
		d->e_phoff		= eh32->e_phoff;
		d->e_shoff		= eh32->e_shoff;
		d->e_flags		= eh32->e_flags;
		d->e_ehsize		= eh32->e_ehsize;
		d->e_phentsize		= eh32->e_phentsize;
		d->e_phnum		= eh32->e_phnum;
		d->e_shentsize		= eh32->e_shentsize;
		d->e_shnum		= eh32->e_shnum;
		d->e_shstrndx		= eh32->e_shstrndx;

		return (d);
	}

	assert(ec == ELFCLASS64);

	if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL)
		return (NULL);
	*d = *eh64;

	return (d);
}
Beispiel #4
0
void *
gelf_newehdr(Elf *e, int ec)
{
	if (e != NULL &&
	    (ec == ELFCLASS32 || ec == ELFCLASS64))
		return (_libelf_ehdr(e, ec, 1));

	LIBELF_SET_ERROR(ARGUMENT, 0);
	return (NULL);
}
Beispiel #5
0
Elf_Scn *
elf_newscn(Elf *e)
{
        int ec;
        void *ehdr;
        Elf_Scn *scn;

        if (e == NULL || e->e_kind != ELF_K_ELF) {
                LIBELF_SET_ERROR(ARGUMENT, 0);
                return (NULL);
        }

        if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) {
                LIBELF_SET_ERROR(CLASS, 0);
                return (NULL);
        }

        if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
                return (NULL);

        /*
         * The application may be asking for a new section descriptor
         * on an ELF object opened with ELF_C_RDWR or ELF_C_READ.  We
         * need to bring in the existing section information before
         * appending a new one to the list.
         *
         * Per the ELF(3) API, an application is allowed to open a
         * file using ELF_C_READ, mess with its internal structure and
         * use elf_update(...,ELF_C_NULL) to compute its new layout.
         */
        if (e->e_cmd != ELF_C_WRITE &&
            (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 &&
            _libelf_load_scn(e, ehdr) == 0)
                return (NULL);

        if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) {
                assert(e->e_u.e_elf.e_nscn == 0);
                if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) ==
                    NULL)
                        return (NULL);
                e->e_u.e_elf.e_nscn++;
        }

        assert(e->e_u.e_elf.e_nscn > 0);

        if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL)
                return (NULL);

        e->e_u.e_elf.e_nscn++;

        (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY);

        return (scn);
}
Beispiel #6
0
int
gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s)
{
	int ec, phnum;
	void *ehdr;
	Elf32_Phdr *ph32;
	Elf64_Phdr *ph64;

	if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF ||
	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (e->e_cmd == ELF_C_READ) {
		LIBELF_SET_ERROR(MODE, 0);
		return (0);
	}

	if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
		return (0);

	if (ec == ELFCLASS32)
		phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
	else
		phnum = ((Elf64_Ehdr *) ehdr)->e_phnum;

	if (ndx < 0 || ndx > phnum) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	(void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY);

	if (ec == ELFCLASS64) {
		ph64 = e->e_u.e_elf.e_phdr.e_phdr64 + ndx;
		*ph64 = *s;
		return (1);
	}

	ph32 = e->e_u.e_elf.e_phdr.e_phdr32 + ndx;

	ph32->p_type     =  s->p_type;
	ph32->p_flags    =  s->p_flags;
	LIBELF_COPY_U32(ph32, s, p_offset);
	LIBELF_COPY_U32(ph32, s, p_vaddr);
	LIBELF_COPY_U32(ph32, s, p_paddr);
	LIBELF_COPY_U32(ph32, s, p_filesz);
	LIBELF_COPY_U32(ph32, s, p_memsz);
	LIBELF_COPY_U32(ph32, s, p_align);

	return (1);
}
Beispiel #7
0
int
gelf_update_ehdr(Elf *e, GElf_Ehdr *s)
{
	int ec;
	void *ehdr;
	Elf32_Ehdr *eh32;
	Elf64_Ehdr *eh64;

	if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF ||
	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (e->e_cmd == ELF_C_READ) {
		LIBELF_SET_ERROR(MODE, 0);
		return (0);
	}

	if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
		return (0);

	(void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY);

	if (ec == ELFCLASS64) {
		eh64 = (Elf64_Ehdr *) ehdr;
		*eh64 = *s;
		return (1);
	}

	eh32 = (Elf32_Ehdr *) ehdr;

	(void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident));

	eh32->e_type      = s->e_type;
	eh32->e_machine   = s->e_machine;
	eh32->e_version   = s->e_version;
	LIBELF_COPY_U32(eh32, s, e_entry);
	LIBELF_COPY_U32(eh32, s, e_phoff);
	LIBELF_COPY_U32(eh32, s, e_shoff);
	eh32->e_flags     = s->e_flags;
	eh32->e_ehsize    = s->e_ehsize;
	eh32->e_phentsize = s->e_phentsize;
	eh32->e_phnum     = s->e_phnum;
	eh32->e_shentsize = s->e_shentsize;
	eh32->e_shnum     = s->e_shnum;
	eh32->e_shstrndx  = s->e_shstrndx;

	return (1);
}
Beispiel #8
0
int
elf_setshstrndx(Elf *e, size_t strndx)
{
    void *eh;
    int ec;

    if (e == NULL || e->e_kind != ELF_K_ELF ||
            ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) ||
            ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) {
        LIBELF_SET_ERROR(ARGUMENT, 0);
        return (0);
    }

    return (_libelf_setshstrndx(e, eh, ec, strndx));
}
Beispiel #9
0
void *
_libelf_newphdr(Elf *e, int ec, size_t count)
{
	void *ehdr, *newphdr, *oldphdr;
	size_t msz;

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

	if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) {
		LIBELF_SET_ERROR(SEQUENCE, 0);
		return (NULL);
	}

	assert(e->e_class == ec);
	assert(ec == ELFCLASS32 || ec == ELFCLASS64);
	assert(e->e_version == EV_CURRENT);

	msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version);

	assert(msz > 0);

	newphdr = NULL;
	if (count > 0 && (newphdr = calloc(count, msz)) == NULL) {
		LIBELF_SET_ERROR(RESOURCE, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {
		if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL)
			free(oldphdr);
		e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr;
	} else {
		if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL)
			free(oldphdr);
		e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr;
	}

	e->e_u.e_elf.e_nphdr = count;

	elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY);

	return (newphdr);
}
static int
_libelf_getshdrnum(Elf *e, size_t *shnum)
{
	void *eh;
	int ec;

	if (e == NULL || e->e_kind != ELF_K_ELF ||
	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (-1);
	}

	if ((eh = _libelf_ehdr(e, ec, 0)) == NULL)
		return (-1);

	*shnum = e->e_u.e_elf.e_nscn;

	return (0);
}
Beispiel #11
0
void *
_libelf_getphdr(Elf *e, int ec)
{
	size_t phnum;
	size_t fsz, msz;
	uint64_t phoff;
	Elf32_Ehdr *eh32;
	Elf64_Ehdr *eh64;
	void *ehdr, *phdr;
	void (*xlator)(char *_d, char *_s, size_t _c, int _swap);

	assert(ec == ELFCLASS32 || ec == ELFCLASS64);

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

	if ((phdr = (ec == ELFCLASS32 ?
		 (void *) e->e_u.e_elf.e_phdr.e_phdr32 :
		 (void *) e->e_u.e_elf.e_phdr.e_phdr64)) != NULL)
		return (phdr);

	/*
	 * Check the PHDR related fields in the EHDR for sanity.
	 */

	if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
		return (NULL);

	phnum = e->e_u.e_elf.e_nphdr;

	if (ec == ELFCLASS32) {
		eh32      = (Elf32_Ehdr *) ehdr;
		phoff     = (uint64_t) eh32->e_phoff;
	} else {
		eh64      = (Elf64_Ehdr *) ehdr;
		phoff     = (uint64_t) eh64->e_phoff;
	}

	fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version);

	assert(fsz > 0);

	if ((uint64_t) e->e_rawsize < (phoff + fsz)) {
		LIBELF_SET_ERROR(HEADER, 0);
		return (NULL);
	}

	msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT);

	assert(msz > 0);

	if ((phdr = calloc(phnum, msz)) == NULL) {
		LIBELF_SET_ERROR(RESOURCE, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32)
		e->e_u.e_elf.e_phdr.e_phdr32 = phdr;
	else
		e->e_u.e_elf.e_phdr.e_phdr64 = phdr;


	xlator = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec);
	(*xlator)(phdr, e->e_rawfile + phoff, phnum,
	    e->e_byteorder != _libelf_host_byteorder());

	return (phdr);
}
Beispiel #12
0
Elf64_Ehdr *
elf64_getehdr(Elf *e)
{
	return (_libelf_ehdr(e, ELFCLASS64, 0));
}
Beispiel #13
0
Elf32_Ehdr *
elf32_getehdr(Elf *e)
{
	return (_libelf_ehdr(e, ELFCLASS32, 0));
}
Beispiel #14
0
Elf64_Ehdr *
elf64_newehdr(Elf *e)
{
	return (_libelf_ehdr(e, ELFCLASS64, 1));
}
Beispiel #15
0
Elf32_Ehdr *
elf32_newehdr(Elf *e)
{
	return (_libelf_ehdr(e, ELFCLASS32, 1));
}