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