diff -r 1af5c1be89f8 -r 92d87f2e53c2 tools/elf4rom/libs/libelf-0.8.10/lib/gelfehdr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelfehdr.c Fri Jan 15 09:07:44 2010 +0000 @@ -0,0 +1,140 @@ +/* + * gelfehdr.c - gelf_* translation functions. + * Copyright (C) 2000 - 2006 Michael Riepe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#if __LIBELF64 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: gelfehdr.c,v 1.8 2006/07/07 22:16:43 michael Exp $"; +#endif /* lint */ + +#define check_and_copy(type, d, s, name, eret) \ + do { \ + if (sizeof((d)->name) < sizeof((s)->name) \ + && (type)(s)->name != (s)->name) { \ + seterr(ERROR_BADVALUE); \ + return (eret); \ + } \ + (d)->name = (type)(s)->name; \ + } while (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); + } + 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; +} + +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); + } + else { + seterr(ERROR_UNKNOWN_CLASS); + } + return 0; + } + return 1; +} + +#endif /* __LIBELF64 */