示例#1
0
int
gelf_getclass(Elf *elf) {
    if (elf && elf->e_kind == ELF_K_ELF && valid_class(elf->e_class)) {
	return elf->e_class;
    }
    return ELFCLASSNONE;
}
示例#2
0
GElf_Phdr*
gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst) {
    GElf_Phdr buf;
    char *tmp;
    size_t n;

    if (!elf) {
	return NULL;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    tmp = _elf_getphdr(elf, elf->e_class);
    if (!tmp) {
	return NULL;
    }
    if (ndx < 0 || ndx >= elf->e_phnum) {
	seterr(ERROR_BADINDEX);
	return NULL;
    }
    n = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
    if (n == 0) {
	seterr(ERROR_UNIMPLEMENTED);
	return NULL;
    }
    if (!dst) {
	dst = &buf;
    }
    if (elf->e_class == ELFCLASS64) {
	*dst = *(Elf64_Phdr*)(tmp + ndx * n);
    }
    else if (elf->e_class == ELFCLASS32) {
	Elf32_Phdr *src = (Elf32_Phdr*)(tmp + ndx * n);

	check_and_copy(GElf_Word,  dst, src, p_type,   NULL);
	check_and_copy(GElf_Word,  dst, src, p_flags,  NULL);
	check_and_copy(GElf_Off,   dst, src, p_offset, NULL);
	check_and_copy(GElf_Addr,  dst, src, p_vaddr,  NULL);
	check_and_copy(GElf_Addr,  dst, src, p_paddr,  NULL);
	check_and_copy(GElf_Xword, dst, src, p_filesz, NULL);
	check_and_copy(GElf_Xword, dst, src, p_memsz,  NULL);
	check_and_copy(GElf_Xword, dst, src, p_align,  NULL);
    }
    else {
	if (valid_class(elf->e_class)) {
	    seterr(ERROR_UNIMPLEMENTED);
	}
	else {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
	return NULL;
    }
    if (dst == &buf) {
	dst = (GElf_Phdr*)malloc(sizeof(GElf_Phdr));
	if (!dst) {
	    seterr(ERROR_MEM_PHDR);
	    return NULL;
	}
	*dst = buf;
    }
    return dst;
}
示例#3
0
int
gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) {
    if (!scn || !src) {
	return 0;
    }
    elf_assert(scn->s_magic == SCN_MAGIC);
    elf_assert(scn->s_elf);
    elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
    if (scn->s_elf->e_class == ELFCLASS64) {
	scn->s_shdr64 = *src;
    }
    else if (scn->s_elf->e_class == ELFCLASS32) {
	Elf32_Shdr *dst = &scn->s_shdr32;

	check_and_copy(Elf32_Word, dst, src, sh_name,      0);
	check_and_copy(Elf32_Word, dst, src, sh_type,      0);
	check_and_copy(Elf32_Word, dst, src, sh_flags,     0);
	check_and_copy(Elf32_Addr, dst, src, sh_addr,      0);
	check_and_copy(Elf32_Off,  dst, src, sh_offset,    0);
	check_and_copy(Elf32_Word, dst, src, sh_size,      0);
	check_and_copy(Elf32_Word, dst, src, sh_link,      0);
	check_and_copy(Elf32_Word, dst, src, sh_info,      0);
	check_and_copy(Elf32_Word, dst, src, sh_addralign, 0);
	check_and_copy(Elf32_Word, dst, src, sh_entsize,   0);
    }
    else if (valid_class(scn->s_elf->e_class)) {
	seterr(ERROR_UNIMPLEMENTED);
	return 0;
    }
    else {
	seterr(ERROR_UNKNOWN_CLASS);
	return 0;
    }
    return 1;
}
示例#4
0
文件: 32.fsize.c 项目: BitK-/libcgcef
/*
 * Extension: report memory size
 */
size_t
gcgcef_msize(CGCEf *cgcef, CGCEf_Type type, size_t count, unsigned ver) {
    size_t n;

    if (cgcef) {
	if (cgcef->e_kind != CGCEF_K_CGCEF) {
	    seterr(ERROR_NOTCGCEF);
	}
	else if (!valid_class(cgcef->e_class)) {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
	else if (!valid_version(ver)) {
	    seterr(ERROR_UNKNOWN_VERSION);
	}
	else if (!valid_type(type)) {
	    seterr(ERROR_UNKNOWN_TYPE);
	}
	else if (!(n = _msize(cgcef->e_class, ver, type))) {
	    seterr(ERROR_UNKNOWN_TYPE);
	}
	else {
	    return count * n;
	}
    }
    return 0;
}
示例#5
0
/*
 * Extension: report memory size
 */
size_t
gelf_msize(Elf *elf, Elf_Type type, size_t count, unsigned ver) {
    size_t n;

    if (elf) {
	if (elf->e_kind != ELF_K_ELF) {
	    seterr(ERROR_NOTELF);
	}
	else if (!valid_class(elf->e_class)) {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
	else if (!valid_version(ver)) {
	    seterr(ERROR_UNKNOWN_VERSION);
	}
	else if (!valid_type(type)) {
	    seterr(ERROR_UNKNOWN_TYPE);
	}
	else if (!(n = _msize(elf->e_class, ver, type))) {
	    seterr(ERROR_UNKNOWN_TYPE);
	}
	else {
	    return count * n;
	}
    }
    return 0;
}
示例#6
0
unsigned long
gcgcef_newphdr(CGCEf *cgcef, size_t phnum) {
    if (!valid_class(cgcef->e_class)) {
	seterr(ERROR_UNKNOWN_CLASS);
	return 0;
    }
    return (unsigned long)_cgcef_newphdr(cgcef, phnum, cgcef->e_class);
}
示例#7
0
unsigned long
gelf_newphdr(Elf *elf, size_t phnum) {
    if (!valid_class(elf->e_class)) {
	seterr(ERROR_UNKNOWN_CLASS);
	return 0;
    }
    return (unsigned long)_elf_newphdr(elf, phnum, elf->e_class);
}
示例#8
0
int
elf_getshstrndx(Elf *elf, size_t *resultp) {
    size_t num = 0;
    size_t dummy;
    Elf_Scn *scn;

    if (!elf) {
	return LIBELF_FAILURE;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    if (resultp == NULL) {
	resultp = &dummy;	/* handle NULL pointer gracefully */
    }
    if (elf->e_kind != ELF_K_ELF) {
	seterr(ERROR_NOTELF);
	return LIBELF_FAILURE;
    }
    if (!elf->e_ehdr && !_elf_cook(elf)) {
	return LIBELF_FAILURE;
    }
    if (elf->e_class == ELFCLASS32) {
	num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx;
    }
#if __LIBELF64
    else if (elf->e_class == ELFCLASS64) {
	num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx;
    }
#endif /* __LIBELF64 */
    else {
	if (valid_class(elf->e_class)) {
	    seterr(ERROR_UNIMPLEMENTED);
	}
	else {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
	return LIBELF_FAILURE;
    }
    if (num != SHN_XINDEX) {
	*resultp = num;
	return LIBELF_SUCCESS;
    }
    /*
     * look at first section header
     */
    if (!(scn = elf->e_scn_1)) {
	seterr(ERROR_NOSUCHSCN);
	return LIBELF_FAILURE;
    }
    elf_assert(scn->s_magic == SCN_MAGIC);
#if __LIBELF64
    if (elf->e_class == ELFCLASS64) {
	*resultp = scn->s_shdr64.sh_link;
	return LIBELF_SUCCESS;
    }
#endif /* __LIBELF64 */
    *resultp = scn->s_shdr32.sh_link;
    return LIBELF_SUCCESS;
}
示例#9
0
unsigned long gelf_newehdr(Elf * elf, int cls)
{
	if (!valid_class(cls) || !_msize(cls, _elf_version, ELF_T_EHDR)) {
		seterr(ERROR_UNKNOWN_CLASS);
		return 0;
	}

	return (unsigned long)_elf_newehdr(elf, cls);
}
示例#10
0
GElf_Ehdr*
gelf_getehdr(Elf *elf, GElf_Ehdr *dst) {
    GElf_Ehdr buf;
    char *tmp;

    if (!elf) {
	return NULL;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    tmp = _elf_getehdr(elf, elf->e_class);
    if (!tmp) {
	return NULL;
    }
    if (!dst) {
	dst = &buf;
    }
    if (elf->e_class == ELFCLASS64) {
	*dst = *(Elf64_Ehdr*)tmp;
    }
    else if (elf->e_class == ELFCLASS32) {
	Elf32_Ehdr *src = (Elf32_Ehdr*)tmp;

	memcpy(dst->e_ident, src->e_ident, EI_NIDENT);
	check_and_copy(GElf_Half, dst, src, e_type,      NULL);
	check_and_copy(GElf_Half, dst, src, e_machine,   NULL);
	check_and_copy(GElf_Word, dst, src, e_version,   NULL);
	check_and_copy(GElf_Addr, dst, src, e_entry,     NULL);
	check_and_copy(GElf_Off,  dst, src, e_phoff,     NULL);
	check_and_copy(GElf_Off,  dst, src, e_shoff,     NULL);
	check_and_copy(GElf_Word, dst, src, e_flags,     NULL);
	check_and_copy(GElf_Half, dst, src, e_ehsize,    NULL);
	check_and_copy(GElf_Half, dst, src, e_phentsize, NULL);
	check_and_copy(GElf_Half, dst, src, e_phnum,     NULL);
	check_and_copy(GElf_Half, dst, src, e_shentsize, NULL);
	check_and_copy(GElf_Half, dst, src, e_shnum,     NULL);
	check_and_copy(GElf_Half, dst, src, e_shstrndx,  NULL);
    }
    else if (valid_class(elf->e_class)) {
	seterr(ERROR_UNIMPLEMENTED);
	return NULL;
    }
    else {
	seterr(ERROR_UNKNOWN_CLASS);
	return NULL;
    }
    if (dst == &buf) {
	dst = (GElf_Ehdr*)malloc(sizeof(GElf_Ehdr));
	if (!dst) {
	    seterr(ERROR_MEM_EHDR);
	    return NULL;
	}
	*dst = buf;
    }
    return dst;
}
示例#11
0
GElf_Shdr*
gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) {
    GElf_Shdr buf;

    if (!scn) {
	return NULL;
    }
    elf_assert(scn->s_magic == SCN_MAGIC);
    elf_assert(scn->s_elf);
    elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
    if (!dst) {
	dst = &buf;
    }
    if (scn->s_elf->e_class == ELFCLASS64) {
	*dst = scn->s_shdr64;
    }
    else if (scn->s_elf->e_class == ELFCLASS32) {
	Elf32_Shdr *src = &scn->s_shdr32;

	check_and_copy(GElf_Word,  dst, src, sh_name,      NULL);
	check_and_copy(GElf_Word,  dst, src, sh_type,      NULL);
	check_and_copy(GElf_Xword, dst, src, sh_flags,     NULL);
	check_and_copy(GElf_Addr,  dst, src, sh_addr,      NULL);
	check_and_copy(GElf_Off,   dst, src, sh_offset,    NULL);
	check_and_copy(GElf_Xword, dst, src, sh_size,      NULL);
	check_and_copy(GElf_Word,  dst, src, sh_link,      NULL);
	check_and_copy(GElf_Word,  dst, src, sh_info,      NULL);
	check_and_copy(GElf_Xword, dst, src, sh_addralign, NULL);
	check_and_copy(GElf_Xword, dst, src, sh_entsize,   NULL);
    }
    else {
	if (valid_class(scn->s_elf->e_class)) {
	    seterr(ERROR_UNIMPLEMENTED);
	}
	else {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
	return NULL;
    }
    if (dst == &buf) {
	dst = (GElf_Shdr*)malloc(sizeof(GElf_Shdr));
	if (!dst) {
	    seterr(ERROR_MEM_SHDR);
	    return NULL;
	}
	*dst = buf;
    }
    return dst;
}
示例#12
0
size_t
gelf_fsize(Elf *elf, Elf_Type type, size_t count, unsigned ver) {
    if (elf) {
	if (elf->e_kind != ELF_K_ELF) {
	    seterr(ERROR_NOTELF);
	}
	else if (valid_class(elf->e_class)) {
	    return count * _elf_fsize(elf->e_class, type, ver);
	}
	else {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
    }
    return 0;
}
示例#13
0
文件: 32.fsize.c 项目: BitK-/libcgcef
size_t
gcgcef_fsize(CGCEf *cgcef, CGCEf_Type type, size_t count, unsigned ver) {
    if (cgcef) {
	if (cgcef->e_kind != CGCEF_K_CGCEF) {
	    seterr(ERROR_NOTCGCEF);
	}
	else if (valid_class(cgcef->e_class)) {
	    return count * _cgcef_fsize(cgcef->e_class, type, ver);
	}
	else {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
    }
    return 0;
}
示例#14
0
int
gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src) {
    char *tmp;
    size_t n;

    if (!elf || !src) {
	return 0;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    tmp = _elf_getphdr(elf, elf->e_class);
    if (!tmp) {
	return 0;
    }
    if (ndx < 0 || ndx >= elf->e_phnum) {
	seterr(ERROR_BADINDEX);
	return 0;
    }
    n = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
    if (n == 0) {
	seterr(ERROR_UNIMPLEMENTED);
	return 0;
    }
    if (elf->e_class == ELFCLASS64) {
	*(Elf64_Phdr*)(tmp + ndx * n) = *src;
    }
    else if (elf->e_class == ELFCLASS32) {
	Elf32_Phdr *dst = (Elf32_Phdr*)(tmp + ndx * n);

	check_and_copy(Elf32_Word, dst, src, p_type,   0);
	check_and_copy(Elf32_Off,  dst, src, p_offset, 0);
	check_and_copy(Elf32_Addr, dst, src, p_vaddr,  0);
	check_and_copy(Elf32_Addr, dst, src, p_paddr,  0);
	check_and_copy(Elf32_Word, dst, src, p_filesz, 0);
	check_and_copy(Elf32_Word, dst, src, p_memsz,  0);
	check_and_copy(Elf32_Word, dst, src, p_flags,  0);
	check_and_copy(Elf32_Word, dst, src, p_align,  0);
    }
    else {
	if (valid_class(elf->e_class)) {
	    seterr(ERROR_UNIMPLEMENTED);
	}
	else {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
	return 0;
    }
    return 1;
}
示例#15
0
static char*
get_addr_and_class(const Elf_Data *data, int ndx, Elf_Type type, unsigned *cls) {
    Scn_Data *sd = (Scn_Data*)data;
    Elf_Scn *scn;
    Elf *elf;
    size_t n;

    if (!sd) {
	return NULL;
    }
    elf_assert(sd->sd_magic == DATA_MAGIC);
    scn = sd->sd_scn;
    elf_assert(scn);
    elf_assert(scn->s_magic == SCN_MAGIC);
    elf = scn->s_elf;
    elf_assert(elf);
    elf_assert(elf->e_magic == ELF_MAGIC);
    if (elf->e_kind != ELF_K_ELF) {
	seterr(ERROR_NOTELF);
	return NULL;
    }
    if (!valid_class(elf->e_class)) {
	seterr(ERROR_UNKNOWN_CLASS);
	return NULL;
    }
    if (data->d_type != type) {
	seterr(ERROR_BADTYPE);
	return NULL;
    }
    n = _msize(elf->e_class, data->d_version, type);
    if (n == 0) {
	seterr(ERROR_UNIMPLEMENTED);
	return NULL;
    }
    if (ndx < 0 || data->d_size < (ndx + 1) * n) {
	seterr(ERROR_BADINDEX);
	return NULL;
    }
    if (!data->d_buf) {
	seterr(ERROR_NULLBUF);
	return NULL;
    }
    if (cls) {
	*cls = elf->e_class;
    }
    return (char*)data->d_buf + n * ndx;
}
示例#16
0
int
elfx_update_shstrndx(Elf *elf, size_t value) {
    size_t extvalue = 0;
    Elf_Scn *scn;

    if (!elf) {
	return LIBELF_FAILURE;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    if (value >= SHN_LORESERVE) {
	extvalue = value;
	value = SHN_XINDEX;
    }
    if (elf->e_kind != ELF_K_ELF) {
	seterr(ERROR_NOTELF);
	return LIBELF_FAILURE;
    }
    if (!elf->e_ehdr && !_elf_cook(elf)) {
	return LIBELF_FAILURE;
    }
    if (!(scn = _elf_first_scn(elf))) {
	return LIBELF_FAILURE;
    }
    elf_assert(scn->s_magic == SCN_MAGIC);
    if (elf->e_class == ELFCLASS32) {
	((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx = value;
	scn->s_shdr32.sh_link = extvalue;
    }
#if __LIBELF64
    else if (elf->e_class == ELFCLASS64) {
	((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx = value;
	scn->s_shdr64.sh_link = extvalue;
    }
#endif /* __LIBELF64 */
    else {
	if (valid_class(elf->e_class)) {
	    seterr(ERROR_UNIMPLEMENTED);
	}
	else {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
	return LIBELF_FAILURE;
    }
    elf->e_ehdr_flags |= ELF_F_DIRTY;
    scn->s_shdr_flags |= ELF_F_DIRTY;
    return LIBELF_SUCCESS;
}
示例#17
0
int
gelf_update_ehdr(Elf *elf, GElf_Ehdr *src) {
    char *tmp;

    if (!elf || !src) {
	return 0;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    tmp = _elf_getehdr(elf, elf->e_class);
    if (!tmp) {
	return 0;
    }
    if (elf->e_class == ELFCLASS64) {
	*(Elf64_Ehdr*)tmp = *src;
    }
    else if (elf->e_class == ELFCLASS32) {
	Elf32_Ehdr *dst = (Elf32_Ehdr*)tmp;

	memcpy(dst->e_ident, src->e_ident, EI_NIDENT);
	check_and_copy(Elf32_Half, dst, src, e_type,      0);
	check_and_copy(Elf32_Half, dst, src, e_machine,   0);
	check_and_copy(Elf32_Word, dst, src, e_version,   0);
	check_and_copy(Elf32_Addr, dst, src, e_entry,     0);
	check_and_copy(Elf32_Off,  dst, src, e_phoff,     0);
	check_and_copy(Elf32_Off,  dst, src, e_shoff,     0);
	check_and_copy(Elf32_Word, dst, src, e_flags,     0);
	check_and_copy(Elf32_Half, dst, src, e_ehsize,    0);
	check_and_copy(Elf32_Half, dst, src, e_phentsize, 0);
	check_and_copy(Elf32_Half, dst, src, e_phnum,     0);
	check_and_copy(Elf32_Half, dst, src, e_shentsize, 0);
	check_and_copy(Elf32_Half, dst, src, e_shnum,     0);
	check_and_copy(Elf32_Half, dst, src, e_shstrndx,  0);
    }
    else if (valid_class(elf->e_class)) {
	seterr(ERROR_UNIMPLEMENTED);
	return 0;
    }
    else {
	seterr(ERROR_UNKNOWN_CLASS);
	return 0;
    }
    return 1;
}
示例#18
0
Elf_Data*
gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) {
    if (elf) {
        if (elf->e_kind != ELF_K_ELF) {
            seterr(ERROR_NOTELF);
        }
        else if (elf->e_class == ELFCLASS32) {
            return elf32_xlatetof(dst, src, encode);
        }
        else if (elf->e_class == ELFCLASS64) {
            return elf64_xlatetof(dst, src, encode);
        }
        else if (valid_class(elf->e_class)) {
            seterr(ERROR_UNIMPLEMENTED);
        }
        else {
            seterr(ERROR_UNKNOWN_CLASS);
        }
    }
    return NULL;
}
示例#19
0
int
_elf_update_shnum(Elf *elf, size_t shnum) {
    Elf_Scn *scn;

    if (elf->e_class == ELFCLASS32) {
	if (shnum >= SHN_LORESERVE) {
	    scn = elf->e_scn_1;
	    elf_assert(scn->s_index == 0);
	    scn->s_shdr_flags |= ELF_F_DIRTY;
	    scn->s_shdr32.sh_size = shnum;
	    shnum = 0;
	}
	elf->e_ehdr_flags |= ELF_F_DIRTY;
	((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = shnum;
	return 0;
    }
#if __LIBELF64
    else if (elf->e_class == ELFCLASS64) {
	if (shnum >= SHN_LORESERVE) {
	    scn = elf->e_scn_1;
	    elf_assert(scn->s_index == 0);
	    scn->s_shdr_flags |= ELF_F_DIRTY;
	    scn->s_shdr64.sh_size = shnum;
	    shnum = 0;
	}
	elf->e_ehdr_flags |= ELF_F_DIRTY;
	((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = shnum;
	return 0;
    }
#endif /* __LIBELF64 */
    else if (valid_class(elf->e_class)) {
	seterr(ERROR_UNIMPLEMENTED);
    }
    else {
	seterr(ERROR_UNKNOWN_CLASS);
    }
    return -1;
}
示例#20
0
size_t elf_delscn(Elf * elf, Elf_Scn * scn)
{
	Elf_Scn *pscn;
	Scn_Data *sd;
	Scn_Data *tmp;
	size_t index;

	if (!elf || !scn) {
		return SHN_UNDEF;
	}
	elf_assert(elf->e_magic == ELF_MAGIC);
	elf_assert(scn->s_magic == SCN_MAGIC);
	elf_assert(elf->e_ehdr);
	if (scn->s_elf != elf) {
		seterr(ERROR_ELFSCNMISMATCH);
		return SHN_UNDEF;
	}
	elf_assert(elf->e_scn_1);
	if (scn == elf->e_scn_1) {
		seterr(ERROR_NULLSCN);
		return SHN_UNDEF;
	}

	/*
	 * Find previous section.
	 */
	for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) {
		if (pscn->s_link == scn) {
			break;
		}
	}
	if (pscn->s_link != scn) {
		seterr(ERROR_ELFSCNMISMATCH);
		return SHN_UNDEF;
	}
	/*
	 * Unlink section.
	 */
	if (elf->e_scn_n == scn) {
		elf->e_scn_n = pscn;
	}
	pscn->s_link = scn->s_link;
	index = scn->s_index;
	/*
	 * Free section descriptor and data.
	 */
	for (sd = scn->s_data_1; sd; sd = tmp) {
		elf_assert(sd->sd_magic == DATA_MAGIC);
		elf_assert(sd->sd_scn == scn);
		tmp = sd->sd_link;
		if (sd->sd_free_data && sd->sd_memdata) {
			free(sd->sd_memdata);
		}
		if (sd->sd_freeme) {
			free(sd);
		}
	}
	if ((sd = scn->s_rawdata)) {
		elf_assert(sd->sd_magic == DATA_MAGIC);
		elf_assert(sd->sd_scn == scn);
		if (sd->sd_free_data && sd->sd_memdata) {
			free(sd->sd_memdata);
		}
		if (sd->sd_freeme) {
			free(sd);
		}
	}
	if (scn->s_freeme) {
		elf_assert(scn->s_index > 0);
		free(scn);
	}
	/*
	 * Adjust section indices.
	 */
	for (scn = pscn->s_link; scn; scn = scn->s_link) {
		elf_assert(scn->s_index > index);
		scn->s_index--;
	}
	/*
	 * Adjust ELF header and well-known section headers.
	 */
	if (elf->e_class == ELFCLASS32) {
		_elf32_update_shdr(elf, index);
		return index;
	}
#if __LIBELF64
	else if (elf->e_class == ELFCLASS64) {
		_elf64_update_shdr(elf, index);
		return index;
	}
#endif				/* __LIBELF64 */
	else if (valid_class(elf->e_class)) {
		seterr(ERROR_UNIMPLEMENTED);
	} else {
		seterr(ERROR_UNKNOWN_CLASS);
	}
	return SHN_UNDEF;
}
示例#21
0
char*
elf_strptr(Elf *elf, size_t section, size_t offset) {
    Elf_Data *data;
    Elf_Scn *scn;
    size_t n;
    char *s;

    if (!elf) {
	return NULL;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    if (!(scn = elf_getscn(elf, section))) {
	return NULL;
    }
    if (scn->s_index == SHN_UNDEF) {
	seterr(ERROR_NOSTRTAB);
	return NULL;
    }
    /*
     * checking the section header is more appropriate
     */
    if (elf->e_class == ELFCLASS32) {
	if (scn->s_shdr32.sh_type != SHT_STRTAB) {
	    seterr(ERROR_NOSTRTAB);
	    return NULL;
	}
    }
#if __LIBELF64
    else if (elf->e_class == ELFCLASS64) {
	if (scn->s_shdr64.sh_type != SHT_STRTAB) {
	    seterr(ERROR_NOSTRTAB);
	    return NULL;
	}
    }
#endif /* __LIBELF64 */
    else if (valid_class(elf->e_class)) {
	seterr(ERROR_UNIMPLEMENTED);
	return NULL;
    }
    else {
	seterr(ERROR_UNKNOWN_CLASS);
	return NULL;
    }
    /*
     * Find matching buffer
     */
    n = 0;
    data = NULL;
    if (elf->e_elf_flags & ELF_F_LAYOUT) {
	/*
	 * Programmer is responsible for d_off
	 * Note: buffers may be in any order!
	 */
	while ((data = elf_getdata(scn, data))) {
	    n = data->d_off;
	    if (offset >= n && offset - n < data->d_size) {
		/*
		 * Found it
		 */
		break;
	    }
	}
    }
    else {
	/*
	 * Calculate offsets myself
	 */
	while ((data = elf_getdata(scn, data))) {
	    if (data->d_align > 1) {
		n += data->d_align - 1;
		n -= n % data->d_align;
	    }
	    if (offset < n) {
		/*
		 * Invalid offset: points into a hole
		 */
		seterr(ERROR_BADSTROFF);
		return NULL;
	    }
	    if (offset - n < data->d_size) {
		/*
		 * Found it
		 */
		break;
	    }
	    n += data->d_size;
	}
    }
    if (data == NULL) {
	/*
	 * Not found
	 */
	seterr(ERROR_BADSTROFF);
	return NULL;
    }
    if (data->d_buf == NULL) {
	/*
	 * Buffer is NULL (usually the programmers' fault)
	 */
	seterr(ERROR_NULLBUF);
	return NULL;
    }
    offset -= n;
    s = (char*)data->d_buf;
    for (n = offset; n < data->d_size; n++) {
	if (s[n] == '\0') {
	    /*
	     * Return properly NUL terminated string
	     */
	    return s + offset;
	}
    }
    /*
     * String is not NUL terminated
     * Return error to avoid SEGV in application
     */
    seterr(ERROR_UNTERM);
    return NULL;
}
示例#22
0
static off_t
scn_data_layout(Elf_Scn *scn, unsigned v, unsigned type, size_t *algn, unsigned *flag) {
    Elf *elf = scn->s_elf;
    Elf_Data *data;
    int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
    size_t scn_align = 1;
    size_t len = 0;
    Scn_Data *sd;
    size_t fsize;

    if (!(sd = scn->s_data_1)) {
	/* no data in section */
	*algn = scn_align;
	return (off_t)len;
    }
    /* load data from file, if any */
    if (!(data = elf_getdata(scn, NULL))) {
	return (off_t)-1;
    }
    elf_assert(data == &sd->sd_data);
    for (; sd; sd = sd->sd_link) {
	elf_assert(sd->sd_magic == DATA_MAGIC);
	elf_assert(sd->sd_scn == scn);

	if (!valid_version(sd->sd_data.d_version)) {
	    return (off_t)-1;
	}

	fsize = sd->sd_data.d_size;
	if (fsize && type != SHT_NOBITS && valid_type(sd->sd_data.d_type)) {
	    if (elf->e_class == ELFCLASS32) {
		fsize = _elf32_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
	    }
#if __LIBELF64
	    else if (elf->e_class == ELFCLASS64) {
		fsize = _elf64_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
	    }
#endif /* __LIBELF64 */
	    else {
		elf_assert(valid_class(elf->e_class));
		seterr(ERROR_UNIMPLEMENTED);
		return (off_t)-1;
	    }
	    if (fsize == (size_t)-1) {
		return (off_t)-1;
	    }
	}

	if (layout) {
	    align(len, sd->sd_data.d_align);
	    scn_align = max(scn_align, sd->sd_data.d_align);
	    rewrite(sd->sd_data.d_off, (off_t)len, sd->sd_data_flags);
	    len += fsize;
	}
	else {
	    len = max(len, sd->sd_data.d_off + fsize);
	}

	*flag |= sd->sd_data_flags;
    }
    *algn = scn_align;
    return (off_t)len;
}
示例#23
0
static off_t
_elf_output(Elf *elf, int fd, size_t len, off_t (*_elf_write)(Elf*, char*, size_t)) {
    char *buf;
    off_t err;

    elf_assert(len);
#if HAVE_FTRUNCATE
    ftruncate(fd, 0);
#endif /* HAVE_FTRUNCATE */
#if HAVE_MMAP
    /*
     * Make sure the file is (at least) len bytes long
     */
#if HAVE_FTRUNCATE
    if (ftruncate(fd, len)) {
#else /* HAVE_FTRUNCATE */
    {
#endif /* HAVE_FTRUNCATE */
	if (lseek(fd, (off_t)len - 1, SEEK_SET) != (off_t)len - 1) {
	    seterr(ERROR_IO_SEEK);
	    return -1;
	}
	if (write(fd, "", 1) != 1) {
	    seterr(ERROR_IO_WRITE);
	    return -1;
	}
    }
    buf = (void*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (buf != (char*)-1) {
	if ((char)_elf_fill && !(elf->e_elf_flags & ELF_F_LAYOUT)) {
	    memset(buf, _elf_fill, len);
	}
	err = _elf_write(elf, buf, len);
	munmap(buf, len);
	return err;
    }
#endif /* HAVE_MMAP */
    if (!(buf = (char*)malloc(len))) {
	seterr(ERROR_MEM_OUTBUF);
	return -1;
    }
    memset(buf, _elf_fill, len);
    err = _elf_write(elf, buf, len);
    if (err != -1 && (size_t)err == len) {
	if (lseek(fd, (off_t)0, SEEK_SET)) {
	    seterr(ERROR_IO_SEEK);
	    err = -1;
	}
	else if (write(fd, buf, len) != len) {
	    seterr(ERROR_IO_WRITE);
	    err = -1;
	}
    }
    free(buf);
    return err;
}

off_t
elf_update(Elf *elf, Elf_Cmd cmd) {
    unsigned flag;
    off_t len;

    if (!elf) {
	return -1;
    }
    elf_assert(elf->e_magic == ELF_MAGIC);
    if (cmd == ELF_C_WRITE) {
	if (!elf->e_writable) {
	    seterr(ERROR_RDONLY);
	    return -1;
	}
	if (elf->e_disabled) {
	    seterr(ERROR_FDDISABLED);
	    return -1;
	}
    }
    else if (cmd != ELF_C_NULL) {
	seterr(ERROR_INVALID_CMD);
	return -1;
    }

    if (!elf->e_ehdr) {
	seterr(ERROR_NOEHDR);
    }
    else if (elf->e_kind != ELF_K_ELF) {
	seterr(ERROR_NOTELF);
    }
    else if (elf->e_class == ELFCLASS32) {
	len = _elf32_layout(elf, &flag);
	if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
	    len = _elf_output(elf, elf->e_fd, (size_t)len, _elf32_write);
	}
	return len;
    }
#if __LIBELF64
    else if (elf->e_class == ELFCLASS64) {
	len = _elf64_layout(elf, &flag);
	if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
	    len = _elf_output(elf, elf->e_fd, (size_t)len, _elf64_write);
	}
	return len;
    }
#endif /* __LIBELF64 */
    else if (valid_class(elf->e_class)) {
	seterr(ERROR_UNIMPLEMENTED);
    }
    else {
	seterr(ERROR_UNKNOWN_CLASS);
    }
    return -1;
}
示例#24
0
文件: getdata.c 项目: xyuan/Path64
static Elf_Data*
_elf_cook_scn(Elf *elf, Elf_Scn *scn, Scn_Data *sd) {
    Elf_Data dst;
    Elf_Data src;
    int flag = 0;
    size_t dlen;

    elf_assert(elf->e_data);

    /*
     * Prepare source
     */
    src = sd->sd_data;
    src.d_version = elf->e_version;
    if (elf->e_rawdata) {
	src.d_buf = elf->e_rawdata + scn->s_offset;
    }
    else {
	src.d_buf = elf->e_data + scn->s_offset;
    }

    /*
     * Prepare destination (needs prepared source!)
     */
    dst = sd->sd_data;
    if (elf->e_class == ELFCLASS32) {
	dlen = _elf32_xltsize(&src, dst.d_version, elf->e_encoding, 0);
    }
#if __LIBELF64
    else if (elf->e_class == ELFCLASS64) {
	dlen = _elf64_xltsize(&src, dst.d_version, elf->e_encoding, 0);
    }
#endif /* __LIBELF64 */
    else {
	elf_assert(valid_class(elf->e_class));
	seterr(ERROR_UNIMPLEMENTED);
	return NULL;
    }
    if (dlen == (size_t)-1) {
	return NULL;
    }
    dst.d_size = dlen;
    if (elf->e_rawdata != elf->e_data && dst.d_size <= src.d_size) {
	dst.d_buf = elf->e_data + scn->s_offset;
    }
    else if (!(dst.d_buf = malloc(dst.d_size))) {
	seterr(ERROR_MEM_SCNDATA);
	return NULL;
    }
    else {
	flag = 1;
    }

    /*
     * Translate data
     */
    if (_elf_xlatetom(elf, &dst, &src)) {
	sd->sd_memdata = (char*)dst.d_buf;
	sd->sd_data = dst;
	if (!(sd->sd_free_data = flag)) {
	    elf->e_cooked = 1;
	}
	return &sd->sd_data;
    }

    if (flag) {
	free(dst.d_buf);
    }
    return NULL;
}
示例#25
0
文件: getdata.c 项目: xyuan/Path64
Elf_Data*
elf_getdata(Elf_Scn *scn, Elf_Data *data) {
    Scn_Data *sd;
    Elf *elf;

    if (!scn) {
	return NULL;
    }
    elf_assert(scn->s_magic == SCN_MAGIC);
    if (scn->s_index == SHN_UNDEF) {
	seterr(ERROR_NULLSCN);
    }
    else if (data) {
	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
	    elf_assert(sd->sd_magic == DATA_MAGIC);
	    elf_assert(sd->sd_scn == scn);
	    if (data == &sd->sd_data) {
		/*
		 * sd_link allocated by elf_newdata().
		 */
		return &sd->sd_link->sd_data;
	    }
	}
	seterr(ERROR_SCNDATAMISMATCH);
    }
    else if ((sd = scn->s_data_1)) {
	elf_assert(sd->sd_magic == DATA_MAGIC);
	elf_assert(sd->sd_scn == scn);
	elf = scn->s_elf;
	elf_assert(elf);
	elf_assert(elf->e_magic == ELF_MAGIC);
	if (sd->sd_freeme) {
	    /* allocated by elf_newdata() */
	    return &sd->sd_data;
	}
	else if (scn->s_type == SHT_NULL) {
	    seterr(ERROR_NULLSCN);
	}
	else if (sd->sd_memdata) {
	    /* already cooked */
	    return &sd->sd_data;
	}
	else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) {
	    seterr(ERROR_OUTSIDE);
	}
	else if (scn->s_type == SHT_NOBITS || !scn->s_size) {
	    /* no data to read */
	    return &sd->sd_data;
	}
	else if (scn->s_offset + scn->s_size > elf->e_size) {
	    seterr(ERROR_TRUNC_SCN);
	}
	else if (valid_class(elf->e_class)) {
	    return _elf_cook_scn(elf, scn, sd);
	}
	else {
	    seterr(ERROR_UNKNOWN_CLASS);
	}
    }
    return NULL;
}