Ejemplo n.º 1
0
GElf_Sym *
gelf_getsym(Elf_Data *d, int ndx, GElf_Sym *dst)
{
	int ec;
	Elf *e;
	Elf_Scn *scn;
	Elf32_Sym *sym32;
	Elf64_Sym *sym64;
	size_t msz;
	uint32_t sh_type;

	if (d == NULL || ndx < 0 || dst == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	assert(msz > 0);

	if (msz * ndx >= d->d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {

		sym32 = (Elf32_Sym *) d->d_buf + ndx;

		dst->st_name  = sym32->st_name;
		dst->st_value = (Elf64_Addr) sym32->st_value;
		dst->st_size  = (Elf64_Xword) sym32->st_size;
		dst->st_info  = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info),
		    ELF32_ST_TYPE(sym32->st_info));
		dst->st_other = sym32->st_other;
		dst->st_shndx = sym32->st_shndx;
	} else {

		sym64 = (Elf64_Sym *) d->d_buf + ndx;

		*dst = *sym64;
	}

	return (dst);
}
Ejemplo n.º 2
0
GElf_Rel *
gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	uint32_t sh_type;
	Elf32_Rel *rel32;
	Elf64_Rel *rel64;
	struct _Libelf_Data *d;

	d = (struct _Libelf_Data *) ed;

	if (d == NULL || ndx < 0 || dst == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	assert(msz > 0);

	if (msz * ndx >= d->d_data.d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {
		rel32 = (Elf32_Rel *) d->d_data.d_buf + ndx;

		dst->r_offset = (Elf64_Addr) rel32->r_offset;
		dst->r_info   = ELF64_R_INFO(
		    (Elf64_Xword) ELF32_R_SYM(rel32->r_info),
		    ELF32_R_TYPE(rel32->r_info));

	} else {

		rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx;

		*dst = *rel64;
	}

	return (dst);
}
Ejemplo n.º 3
0
GElf_Syminfo *
gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	uint32_t sh_type;
	struct _Libelf_Data *d;
	Elf32_Syminfo *syminfo32;
	Elf64_Syminfo *syminfo64;

	d = (struct _Libelf_Data *) ed;

	if (d == NULL || ndx < 0 || dst == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	assert(msz > 0);
	assert(ndx >= 0);

	if (msz * (size_t) ndx >= d->d_data.d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {

		syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx;

		dst->si_boundto = syminfo32->si_boundto;
		dst->si_flags   = syminfo32->si_flags;

	} else {

		syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx;

		*dst = *syminfo64;
	}

	return (dst);
}
Ejemplo n.º 4
0
int
gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	uint32_t sh_type;
	Elf32_Sym *sym32;
	Elf64_Sym *sym64;
	struct _Libelf_Data *d;

	d = (struct _Libelf_Data *) ed;

	if (d == NULL || ndx < 0 || gs == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
	assert(msz > 0);

	if (msz * ndx >= d->d_data.d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (ec == ELFCLASS32) {
		sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx;

		sym32->st_name  = gs->st_name;
		sym32->st_info  = gs->st_info;
		sym32->st_other = gs->st_other;
		sym32->st_shndx = gs->st_shndx;

		LIBELF_COPY_U32(sym32, gs, st_value);
		LIBELF_COPY_U32(sym32, gs, st_size);
	} else {
		sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx;

		*sym64 = *gs;
	}

	return (1);
}
Ejemplo n.º 5
0
GElf_Cap *
gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	Elf32_Cap *cap32;
	Elf64_Cap *cap64;
	u_int32_t sh_type;
	struct _Libelf_Data *d;

	d = (struct _Libelf_Data *) ed;

	if (d == NULL || ndx < 0 || dst == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	assert(msz > 0);

	if (msz * (size_t) ndx >= d->d_data.d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {

		cap32 = (Elf32_Cap *) d->d_data.d_buf + ndx;

		dst->c_tag  = cap32->c_tag;
		dst->c_un.c_val = (Elf64_Xword) cap32->c_un.c_val;

	} else {

		cap64 = (Elf64_Cap *) d->d_data.d_buf + ndx;

		*dst = *cap64;
	}

	return (dst);
}
Ejemplo n.º 6
0
int
gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	uint32_t sh_type;
	Elf32_Move *move32;
	Elf64_Move *move64;
	struct _Libelf_Data *d;

	d = (struct _Libelf_Data *) ed;

	if (d == NULL || ndx < 0 || gm == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
	assert(msz > 0);

	if (msz * ndx >= d->d_data.d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (ec == ELFCLASS32) {
		move32 = (Elf32_Move *) d->d_data.d_buf + ndx;

		move32->m_value  = gm->m_value;
		LIBELF_COPY_U32(move32, gm, m_info);
		LIBELF_COPY_U32(move32, gm, m_poffset);
		move32->m_repeat  = gm->m_repeat;
		move32->m_stride = gm->m_stride;

	} else {
		move64 = (Elf64_Move *) d->d_data.d_buf + ndx;

		*move64 = *gm;
	}

	return (1);
}
Ejemplo n.º 7
0
int
gelf_update_rel(Elf_Data *d, int ndx, GElf_Rel *dr)
{
	int ec;
	Elf *e;
	Elf_Scn *scn;
	Elf32_Rel *rel32;
	Elf64_Rel *rel64;
	size_t msz;
	uint32_t sh_type;

	if (d == NULL || ndx < 0 || dr == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
	assert(msz > 0);

	if (msz * ndx >= d->d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (ec == ELFCLASS32) {
		rel32 = (Elf32_Rel *) d->d_buf + ndx;

		LIBELF_COPY_U32(rel32, dr, r_offset);

		if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) ||
		    ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) {
			LIBELF_SET_ERROR(RANGE, 0);
			return (0);
		}
		rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info),
		    ELF64_R_TYPE(dr->r_info));
	} else {
		rel64 = (Elf64_Rel *) d->d_buf + ndx;

		*rel64 = *dr;
	}

	return (1);
}
Ejemplo n.º 8
0
GElf_Move *
gelf_getmove(Elf_Data *d, int ndx, GElf_Move *dst)
{
	int ec;
	Elf *e;
	Elf_Scn *scn;
	Elf32_Move *move32;
	Elf64_Move *move64;
	size_t msz;
	uint32_t sh_type;

	if (d == NULL || ndx < 0 || dst == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	assert(msz > 0);

	if (msz * ndx >= d->d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {

		move32 = (Elf32_Move *) d->d_buf + ndx;

		dst->m_value   = move32->m_value;
		dst->m_info    = (Elf64_Xword) move32->m_info;
		dst->m_poffset = (Elf64_Xword) move32->m_poffset;
		dst->m_repeat  = move32->m_repeat;
		dst->m_stride = move32->m_stride;
	} else {

		move64 = (Elf64_Move *) d->d_buf + ndx;

		*dst = *move64;
	}

	return (dst);
}
Ejemplo n.º 9
0
int
gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	Elf32_Dyn *dyn32;
	Elf64_Dyn *dyn64;
	uint32_t sh_type;
	struct _Libelf_Data *d;

	d = (struct _Libelf_Data *) ed;

	if (d == NULL || ndx < 0 || ds == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

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

	assert(msz > 0);
	assert(ndx >= 0);

	if (msz * (size_t) ndx >= d->d_data.d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (ec == ELFCLASS32) {
		dyn32 = (Elf32_Dyn *) d->d_data.d_buf + ndx;

		LIBELF_COPY_S32(dyn32, ds, d_tag);
		LIBELF_COPY_U32(dyn32, ds, d_un.d_val);
	} else {
		dyn64 = (Elf64_Dyn *) d->d_data.d_buf + ndx;

		*dyn64 = *ds;
	}

	return (1);
}
Ejemplo n.º 10
0
GElf_Dyn *
gelf_getdyn(Elf_Data *d, int ndx, GElf_Dyn *dst)
{
	int ec;
	Elf *e;
	Elf_Scn *scn;
	Elf32_Dyn *dyn32;
	Elf64_Dyn *dyn64;
	size_t msz;
	uint32_t sh_type;

	if (d == NULL || ndx < 0 || dst == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	assert(msz > 0);

	if (msz * ndx >= d->d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	if (ec == ELFCLASS32) {
		dyn32 = (Elf32_Dyn *) d->d_buf + ndx;

		dst->d_tag      = dyn32->d_tag;
		dst->d_un.d_val = (Elf64_Xword) dyn32->d_un.d_val;

	} else {

		dyn64 = (Elf64_Dyn *) d->d_buf + ndx;

		*dst = *dyn64;
	}

	return (dst);
}
Ejemplo n.º 11
0
int
gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	Elf32_Cap *cap32;
	Elf64_Cap *cap64;
	u_int32_t sh_type;
	struct _Libelf_Data *d;

	d = (struct _Libelf_Data *) ed;

	if (d == NULL || ndx < 0 || gc == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	msz = _libelf_msize(ELF_T_CAP, ec, e->e_version);
	assert(msz > 0);

	if (msz * (size_t) ndx >= d->d_data.d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (ec == ELFCLASS32) {
		cap32 = (Elf32_Cap *) d->d_data.d_buf + ndx;

		LIBELF_COPY_U32(cap32, gc, c_tag);
		LIBELF_COPY_U32(cap32, gc, c_un.c_val);
	} else {
		cap64 = (Elf64_Cap *) d->d_data.d_buf + ndx;

		*cap64 = *gc;
	}

	return (1);
}
Ejemplo n.º 12
0
int
gelf_update_syminfo(Elf_Data *d, int ndx, GElf_Syminfo *gs)
{
	int ec;
	Elf *e;
	Elf_Scn *scn;
	Elf32_Syminfo *syminfo32;
	Elf64_Syminfo *syminfo64;
	size_t msz;
	uint32_t sh_type;

	if (d == NULL || ndx < 0 || gs == NULL ||
	    (scn = d->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
	assert(msz > 0);

	if (msz * ndx >= d->d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	if (ec == ELFCLASS32) {
		syminfo32 = (Elf32_Syminfo *) d->d_buf + ndx;

		syminfo32->si_boundto  = gs->si_boundto;
		syminfo32->si_flags  = gs->si_flags;

	} else {
		syminfo64 = (Elf64_Syminfo *) d->d_buf + ndx;

		*syminfo64 = *gs;
	}

	return (1);
}
Ejemplo n.º 13
0
GElf_Sym *
gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
    Elf32_Word *shindex)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	uint32_t sh_type;
	struct _Libelf_Data *ld, *lid;

	ld = (struct _Libelf_Data *) d;
	lid = (struct _Libelf_Data *) id;

	if (gelf_getsym(d, ndx, dst) == 0)
		return (NULL);

	if (lid == NULL || (scn = lid->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL || (e != ld->d_scn->s_elf) ||
	    shindex == NULL) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD ||
	   id->d_type != ELF_T_WORD) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

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

	assert(msz > 0);
	assert(ndx >= 0);

	if (msz * (size_t) ndx >= id->d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	*shindex = ((Elf32_Word *) id->d_buf)[ndx];

	return (dst);
}
Ejemplo n.º 14
0
int
gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs,
    Elf32_Word xindex)
{
	int ec;
	Elf *e;
	size_t msz;
	Elf_Scn *scn;
	uint32_t sh_type;
	struct _Libelf_Data *ld, *lid;

	ld = (struct _Libelf_Data *) d;
	lid = (struct _Libelf_Data *) id;

	if (gelf_update_sym(d, ndx, gs) == 0)
		return (0);

	if (lid == NULL || (scn = lid->d_scn) == NULL ||
	    (e = scn->s_elf) == NULL || (e != ld->d_scn->s_elf)) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

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

	if (ec == ELFCLASS32)
		sh_type = scn->s_shdr.s_shdr32.sh_type;
	else
		sh_type = scn->s_shdr.s_shdr64.sh_type;

	if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD ||
	    d->d_type != ELF_T_WORD) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
	assert(msz > 0);

	if (msz * ndx >= id->d_size) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (0);
	}

	*(((Elf32_Word *) id->d_buf) + ndx) = xindex;

	return (1);
}
Ejemplo n.º 15
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);
}
Ejemplo n.º 16
0
void *
_libelf_ehdr(Elf *e, int ec, int allocate)
{
    void *ehdr;
    size_t fsz, msz;
    uint16_t phnum, shnum, strndx;
    uint64_t shoff;
    int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s,
                  size_t _c, int _swap);

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

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

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

    if (e->e_version != EV_CURRENT) {
        LIBELF_SET_ERROR(VERSION, 0);
        return (NULL);
    }

    if (e->e_class == ELFCLASSNONE)
        e->e_class = ec;

    if (ec == ELFCLASS32)
        ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32;
    else
        ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64;

    if (ehdr != NULL)	/* already have a translated ehdr */
        return (ehdr);

    fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
    assert(fsz > 0);

    if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) {
        LIBELF_SET_ERROR(HEADER, 0);
        return (NULL);
    }

    msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT);

    assert(msz > 0);

    if ((ehdr = calloc((size_t) 1, msz)) == NULL) {
        LIBELF_SET_ERROR(RESOURCE, 0);
        return (NULL);
    }

    if (ec == ELFCLASS32) {
        e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr;
        EHDR_INIT(ehdr,32);
    } else {
        e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr;
        EHDR_INIT(ehdr,64);
    }

    if (allocate)
        e->e_flags |= ELF_F_DIRTY;

    if (e->e_cmd == ELF_C_WRITE)
        return (ehdr);

    xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec);
    (*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1,
              e->e_byteorder != LIBELF_PRIVATE(byteorder));

    if (ec == ELFCLASS32) {
        phnum = ((Elf32_Ehdr *) ehdr)->e_phnum;
        shnum = ((Elf32_Ehdr *) ehdr)->e_shnum;
        shoff = ((Elf32_Ehdr *) ehdr)->e_shoff;
        strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx;
    } else {
        phnum = ((Elf64_Ehdr *) ehdr)->e_phnum;
        shnum = ((Elf64_Ehdr *) ehdr)->e_shnum;
        shoff = ((Elf64_Ehdr *) ehdr)->e_shoff;
        strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx;
    }

    if (shnum >= SHN_LORESERVE ||
            (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM ||
                              strndx == SHN_XINDEX))) {
        LIBELF_SET_ERROR(HEADER, 0);
        return (NULL);
    }

    /*
     * If extended numbering is being used, read the correct
     * number of sections and program header entries.
     */
    if ((shnum == 0 && shoff != 0) || phnum == PN_XNUM || strndx == SHN_XINDEX) {
        if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0)
            return (NULL);
    } else {
        /* not using extended numbering */
        e->e_u.e_elf.e_nphdr = phnum;
        e->e_u.e_elf.e_nscn = shnum;
        e->e_u.e_elf.e_strndx = strndx;
    }

    return (ehdr);
}
Ejemplo n.º 17
0
Elf_Data *
elf_getdata(Elf_Scn *s, Elf_Data *d)
{
	Elf *e;
	size_t fsz, msz, count;
	int elfclass, elftype;
	unsigned int sh_type;
	uint64_t sh_align, sh_offset, sh_size;
	void (*xlate)(char *_d, char *_s, size_t _c, int _swap);

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

	if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL)
		return (d);

	if (d != NULL)
		return (STAILQ_NEXT(d, d_next));

	if (e->e_rawfile == NULL) {
		LIBELF_SET_ERROR(SEQUENCE, 0);
		return (NULL);
	}

	elfclass = e->e_class;

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

	if (elfclass == ELFCLASS32) {
		sh_type   = s->s_shdr.s_shdr32.sh_type;
		sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset;
		sh_size   = (uint64_t) s->s_shdr.s_shdr32.sh_size;
		sh_align  = (uint64_t) s->s_shdr.s_shdr32.sh_addralign;
	} else {
		sh_type   = s->s_shdr.s_shdr64.sh_type;
		sh_offset = s->s_shdr.s_shdr64.sh_offset;
		sh_size   = s->s_shdr.s_shdr64.sh_size;
		sh_align  = s->s_shdr.s_shdr64.sh_addralign;
	}

	if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
	    elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
	    sh_offset + sh_size > (uint64_t) e->e_rawsize)) {
		LIBELF_SET_ERROR(SECTION, 0);
		return (NULL);
	}

	if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)(elftype,
		 (size_t) 1, e->e_version)) == 0) {
		LIBELF_SET_ERROR(UNIMPL, 0);
		return (NULL);
	}


	if (sh_size % fsz) {
		LIBELF_SET_ERROR(SECTION, 0);
		return (NULL);
	}

	count = sh_size / fsz;

	msz = _libelf_msize(elftype, elfclass, e->e_version);

	assert(msz > 0);

	if ((d = _libelf_allocate_data(s)) == NULL)
		return (NULL);

	d->d_buf     = NULL;
	d->d_off     = 0;
	d->d_align   = sh_align;
	d->d_size    = msz * count;
	d->d_type    = elftype;
	d->d_version = e->e_version;

	if (sh_type == SHT_NOBITS)
		return (d);

	d->d_flags  |= LIBELF_F_MALLOCED;

	if ((d->d_buf = malloc(msz*count)) == NULL) {
		(void) _libelf_release_data(d);
		LIBELF_SET_ERROR(RESOURCE, 0);
		return (NULL);
	}

	STAILQ_INSERT_TAIL(&s->s_data, d, d_next);

	xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass);
	(*xlate)(d->d_buf, e->e_rawfile + sh_offset, count, e->e_byteorder !=
	    _libelf_host_byteorder());

	return (d);
}
Ejemplo n.º 18
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);
}
Ejemplo n.º 19
0
Elf_Data *
elf_getdata(Elf_Scn *s, Elf_Data *ed)
{
	Elf *e;
	unsigned int sh_type;
	int elfclass, elftype;
	size_t fsz, msz, count;
	struct _Libelf_Data *d;
	uint64_t sh_align, sh_offset, sh_size;
	int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);

	d = (struct _Libelf_Data *) ed;

	if (s == NULL || (e = s->s_elf) == NULL ||
	    (d != NULL && s != d->d_scn)) {
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	assert(e->e_kind == ELF_K_ELF);

	if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL)
		return (&d->d_data);

	if (d != NULL)
		return (&STAILQ_NEXT(d, d_next)->d_data);

	if (e->e_rawfile == NULL) {
		/*
		 * In the ELF_C_WRITE case, there is no source that
		 * can provide data for the section.
		 */
		LIBELF_SET_ERROR(ARGUMENT, 0);
		return (NULL);
	}

	elfclass = e->e_class;

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

	if (elfclass == ELFCLASS32) {
		sh_type   = s->s_shdr.s_shdr32.sh_type;
		sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset;
		sh_size   = (uint64_t) s->s_shdr.s_shdr32.sh_size;
		sh_align  = (uint64_t) s->s_shdr.s_shdr32.sh_addralign;
	} else {
		sh_type   = s->s_shdr.s_shdr64.sh_type;
		sh_offset = s->s_shdr.s_shdr64.sh_offset;
		sh_size   = s->s_shdr.s_shdr64.sh_size;
		sh_align  = s->s_shdr.s_shdr64.sh_addralign;
	}

	if (sh_type == SHT_NULL) {
		LIBELF_SET_ERROR(SECTION, 0);
		return (NULL);
	}

	if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST ||
	    elftype > ELF_T_LAST || (sh_type != SHT_NOBITS &&
	    sh_offset + sh_size > (uint64_t) e->e_rawsize)) {
		LIBELF_SET_ERROR(SECTION, 0);
		return (NULL);
	}

	if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)
            (elftype, (size_t) 1, e->e_version)) == 0) {
		LIBELF_SET_ERROR(UNIMPL, 0);
		return (NULL);
	}

	if (sh_size % fsz) {
		LIBELF_SET_ERROR(SECTION, 0);
		return (NULL);
	}

	count = sh_size / fsz;

	msz = _libelf_msize(elftype, elfclass, e->e_version);

	assert(msz > 0);

	if ((d = _libelf_allocate_data(s)) == NULL)
		return (NULL);

	d->d_data.d_buf     = NULL;
	d->d_data.d_off     = 0;
	d->d_data.d_align   = sh_align;
	d->d_data.d_size    = msz * count;
	d->d_data.d_type    = elftype;
	d->d_data.d_version = e->e_version;

	if (sh_type == SHT_NOBITS || sh_size == 0) {
	        STAILQ_INSERT_TAIL(&s->s_data, d, d_next);
		return (&d->d_data);
        }

	if ((d->d_data.d_buf = malloc(msz*count)) == NULL) {
		(void) _libelf_release_data(d);
		LIBELF_SET_ERROR(RESOURCE, 0);
		return (NULL);
	}

	d->d_flags  |= LIBELF_F_DATA_MALLOCED;

	xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass);
	if (!(*xlate)(d->d_data.d_buf, d->d_data.d_size,
	    e->e_rawfile + sh_offset, count,
	    e->e_byteorder != LIBELF_PRIVATE(byteorder))) {
		_libelf_release_data(d);
		LIBELF_SET_ERROR(DATA, 0);
		return (NULL);
	}

	STAILQ_INSERT_TAIL(&s->s_data, d, d_next);

	return (&d->d_data);
}
Ejemplo n.º 20
0
Elf_Data *
_libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding,
              int elfclass, int direction)
{
    int byteswap;
    size_t cnt, dsz, fsz, msz;
    uintptr_t sb, se, db, de;

    if (encoding == ELFDATANONE)
        encoding = LIBELF_PRIVATE(byteorder);

    if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) ||
            dst == NULL || src == NULL || dst == src)	{
        LIBELF_SET_ERROR(ARGUMENT, 0);
        return (NULL);
    }

    assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
    assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY);

    if (dst->d_version != src->d_version) {
        LIBELF_SET_ERROR(UNIMPL, 0);
        return (NULL);
    }

    if  (src->d_buf == NULL || dst->d_buf == NULL) {
        LIBELF_SET_ERROR(DATA, 0);
        return (NULL);
    }

    if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) {
        LIBELF_SET_ERROR(DATA, 0);
        return (NULL);
    }

    if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize)
               (src->d_type, (size_t) 1, src->d_version)) == 0)
        return (NULL);

    msz = _libelf_msize(src->d_type, elfclass, src->d_version);

    assert(msz > 0);

    if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) {
        LIBELF_SET_ERROR(DATA, 0);
        return (NULL);
    }

    /*
     * Determine the number of objects that need to be converted, and
     * the space required for the converted objects in the destination
     * buffer.
     */
    if (direction == ELF_TOMEMORY) {
        cnt = src->d_size / fsz;
        dsz = cnt * msz;
    } else {
        cnt = src->d_size / msz;
        dsz = cnt * fsz;
    }

    if (dst->d_size  <  dsz) {
        LIBELF_SET_ERROR(DATA, 0);
        return (NULL);
    }

    sb = (uintptr_t) src->d_buf;
    se = sb + src->d_size;
    db = (uintptr_t) dst->d_buf;
    de = db + dst->d_size;

    /*
     * Check for overlapping buffers.  Note that db == sb is
     * allowed.
     */
    if (db != sb && de > sb && se > db) {
        LIBELF_SET_ERROR(DATA, 0);
        return (NULL);
    }

    if ((direction == ELF_TOMEMORY ? db : sb) %
            _libelf_malign(src->d_type, elfclass)) {
        LIBELF_SET_ERROR(DATA, 0);
        return (NULL);
    }

    dst->d_type = src->d_type;
    dst->d_size = dsz;

    byteswap = encoding != LIBELF_PRIVATE(byteorder);

    if (src->d_size == 0 ||
            (db == sb && !byteswap && fsz == msz))
        return (dst);	/* nothing more to do */

    if (!(_libelf_get_translator(src->d_type, direction, elfclass))
            (dst->d_buf, dsz, src->d_buf, cnt, byteswap)) {
        LIBELF_SET_ERROR(DATA, 0);
        return (NULL);
    }

    return (dst);
}