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; }
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; }
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; }
GElf_Sym* gelf_getsym(Elf_Data *src, int ndx, GElf_Sym *dst) { GElf_Sym buf; unsigned cls; char *tmp; if (!dst) { dst = &buf; } tmp = get_addr_and_class(src, ndx, ELF_T_SYM, &cls); if (!tmp) { return NULL; } if (cls == ELFCLASS64) { *dst = *(Elf64_Sym*)tmp; } else if (cls == ELFCLASS32) { Elf32_Sym *src = (Elf32_Sym*)tmp; check_and_copy(GElf_Word, dst, src, st_name, NULL); check_and_copy(unsigned char, dst, src, st_info, NULL); check_and_copy(unsigned char, dst, src, st_other, NULL); check_and_copy(GElf_Half, dst, src, st_shndx, NULL); check_and_copy(GElf_Addr, dst, src, st_value, NULL); check_and_copy(GElf_Xword, dst, src, st_size, NULL); } else { seterr(ERROR_UNIMPLEMENTED); return NULL; } if (dst == &buf) { dst = (GElf_Sym*)malloc(sizeof(GElf_Sym)); if (!dst) { seterr(ERROR_MEM_SYM); return NULL; } *dst = buf; } return dst; }
int gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src) { unsigned cls; char *tmp; tmp = get_addr_and_class(dst, ndx, ELF_T_SYM, &cls); if (!tmp) { return 0; } if (cls == ELFCLASS64) { *(Elf64_Sym*)tmp = *src; } else if (cls == ELFCLASS32) { Elf32_Sym *dst = (Elf32_Sym*)tmp; check_and_copy(Elf32_Word, dst, src, st_name, 0); check_and_copy(Elf32_Addr, dst, src, st_value, 0); check_and_copy(Elf32_Word, dst, src, st_size, 0); check_and_copy(unsigned char, dst, src, st_info, 0); check_and_copy(unsigned char, dst, src, st_other, 0); check_and_copy(Elf32_Half, dst, src, st_shndx, 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; }
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; }
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; }