xref: /illumos-gate/usr/src/cmd/sgs/libelf/common/newehdr.c (revision e7cbe64f7a72dae5cb44f100db60ca88f3313c65)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1988 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #if !defined(_ELF64)
34 #pragma weak elf32_newehdr = _elf32_newehdr
35 #endif
36 
37 #include "syn.h"
38 #include <stdlib.h>
39 #include <errno.h>
40 #include "decl.h"
41 #include "msg.h"
42 
43 /*
44  * This module is compiled twice, the second time having
45  * -D_ELF64 defined.  The following set of macros, along
46  * with machelf.h, represent the differences between the
47  * two compilations.  Be careful *not* to add any class-
48  * dependent code (anything that has elf32 or elf64 in the
49  * name) to this code without hiding it behind a switch-
50  * able macro like these.
51  */
52 #if	defined(_ELF64)
53 
54 #define	ELFCLASS		ELFCLASS64
55 #define	_elf_ehdr_init		_elf64_ehdr_init
56 #define	elf_newehdr		elf64_newehdr
57 #define	getehdr			elf64_getehdr
58 
59 #else	/* else ELF32 */
60 
61 #define	ELFCLASS		ELFCLASS32
62 #define	_elf_ehdr_init		_elf32_ehdr_init
63 #define	elf_newehdr		_elf32_newehdr
64 #define	getehdr			elf32_getehdr
65 
66 #endif	/* ELF64 */
67 
68 
69 Ehdr *
70 elf_newehdr(Elf * elf)
71 {
72 	register
73 	Ehdr	*eh;
74 
75 	if (elf == 0)
76 		return (0);
77 
78 	/*
79 	 * If reading file, return its hdr
80 	 */
81 
82 	ELFWLOCK(elf)
83 	if (elf->ed_myflags & EDF_READ) {
84 		ELFUNLOCK(elf)
85 		if ((eh = (Ehdr *)getehdr(elf)) != 0) {
86 			ELFWLOCK(elf)
87 			elf->ed_ehflags |= ELF_F_DIRTY;
88 			ELFUNLOCK(elf)
89 		}
90 		return (eh);
91 	}
92 
93 	/*
94 	 * Writing file
95 	 */
96 
97 	if (elf->ed_class == ELFCLASSNONE)
98 		elf->ed_class = ELFCLASS;
99 	else if (elf->ed_class != ELFCLASS) {
100 		_elf_seterr(EREQ_CLASS, 0);
101 		ELFUNLOCK(elf)
102 		return (0);
103 	}
104 	ELFUNLOCK(elf);
105 	if ((eh = (Ehdr *)getehdr(elf)) != 0) {	/* this cooks if necessary */
106 		ELFWLOCK(elf)
107 		elf->ed_ehflags |= ELF_F_DIRTY;
108 		ELFUNLOCK(elf)
109 		return (eh);
110 	}
111 	ELFWLOCK(elf)
112 
113 	if ((eh = (Ehdr *)malloc(sizeof (Ehdr))) == 0) {
114 		_elf_seterr(EMEM_EHDR, errno);
115 		ELFUNLOCK(elf)
116 		return (0);
117 	}
118 	*eh = _elf_ehdr_init;
119 	elf->ed_myflags |= EDF_EHALLOC;
120 	elf->ed_ehflags |= ELF_F_DIRTY;
121 	elf->ed_ehdr = eh;
122 	ELFUNLOCK(elf)
123 	return (eh);
124 }
125