1 /*
2  * 32.newehdr.c - implementation of the elf{32,64}_newehdr(3) functions.
3  * Copyright (C) 1995 - 2006 Michael Riepe
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include <private.h>
21 
22 #ifndef lint
23 static const char rcsid[] = "@(#) $Id: 32.newehdr.c,v 1.16 2008/05/23 08:15:34 michael Exp $";
24 #endif /* lint */
25 
26 static char*
27 _elf_newehdr(Elf *elf, unsigned cls) {
28     size_t size;
29 
30     if (!elf) {
31 	return NULL;
32     }
33     elf_assert(elf->e_magic == ELF_MAGIC);
34     if (elf->e_readable) {
35 	return _elf_getehdr(elf, cls);
36     }
37     else if (!elf->e_ehdr) {
38 	size = _msize(cls, _elf_version, ELF_T_EHDR);
39 	elf_assert(size);
40 	if ((elf->e_ehdr = (char*)malloc(size))) {
41 	    memset(elf->e_ehdr, 0, size);
42 	    elf->e_ehdr_flags |= ELF_F_DIRTY;
43 	    elf->e_kind = ELF_K_ELF;
44 	    elf->e_class = cls;
45 	    return elf->e_ehdr;
46 	}
47 	seterr(ERROR_MEM_EHDR);
48     }
49     else if (elf->e_class != cls) {
50 	seterr(ERROR_CLASSMISMATCH);
51     }
52     else {
53 	elf_assert(elf->e_kind == ELF_K_ELF);
54 	return elf->e_ehdr;
55     }
56     return NULL;
57 }
58 
59 Elf32_Ehdr*
60 elf32_newehdr(Elf *elf) {
61     return (Elf32_Ehdr*)_elf_newehdr(elf, ELFCLASS32);
62 }
63 
64 #if __LIBELF64
65 
66 Elf64_Ehdr*
67 elf64_newehdr(Elf *elf) {
68     return (Elf64_Ehdr*)_elf_newehdr(elf, ELFCLASS64);
69 }
70 
71 unsigned long
72 gelf_newehdr(Elf *elf, int cls) {
73     if (!valid_class(cls) || !_msize(cls, _elf_version, ELF_T_EHDR)) {
74 	seterr(ERROR_UNKNOWN_CLASS);
75 	return 0;
76     }
77     return (unsigned long)_elf_newehdr(elf, cls);
78 }
79 
80 #endif /* __LIBELF64 */
81