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);
}
Exemple #2
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);
}
Exemple #3
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);
}
Exemple #4
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);
}
Exemple #5
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);
}
Exemple #6
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);
}
Exemple #7
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);
}
Exemple #8
0
int
gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s)
{
	int ec;
	Elf *e;
	Elf32_Shdr *sh32;


	if (s == NULL || scn == NULL || (e = scn->s_elf) == 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);
	}

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

	if (ec == ELFCLASS64) {
		scn->s_shdr.s_shdr64 = *s;
		return (1);
	}

	sh32 = &scn->s_shdr.s_shdr32;

	sh32->sh_name	 =  s->sh_name;
	sh32->sh_type	 =  s->sh_type;
	LIBELF_COPY_U32(sh32, s, sh_flags);
	LIBELF_COPY_U32(sh32, s, sh_addr);
	LIBELF_COPY_U32(sh32, s, sh_offset);
	LIBELF_COPY_U32(sh32, s, sh_size);
	sh32->sh_link	 =  s->sh_link;
	sh32->sh_info	 =  s->sh_info;
	LIBELF_COPY_U32(sh32, s, sh_addralign);
	LIBELF_COPY_U32(sh32, s, sh_entsize);

	return (1);
}