1/* Create new ELF header.
2   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
3   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation, version 2.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software Foundation,
16   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21
22#include <stdlib.h>
23#include <string.h>
24
25#include "libelfP.h"
26
27#ifndef LIBELFBITS
28# define LIBELFBITS 32
29#endif
30
31
32ElfW2(LIBELFBITS,Ehdr) *
33elfw2(LIBELFBITS,newehdr) (elf)
34     Elf *elf;
35{
36  ElfW2(LIBELFBITS,Ehdr) *result;
37
38  if (elf == NULL)
39    return NULL;
40
41  if (unlikely (elf->kind != ELF_K_ELF))
42    {
43      __libelf_seterrno (ELF_E_INVALID_HANDLE);
44      return NULL;
45    }
46
47  rwlock_wrlock (elf->lock);
48
49  if (elf->class == 0)
50    elf->class = ELFW(ELFCLASS,LIBELFBITS);
51  else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
52    {
53      __libelf_seterrno (ELF_E_INVALID_CLASS);
54      result = NULL;
55      goto out;
56    }
57
58  /* Don't create an ELF header if one already exists.  */
59  if (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL)
60    {
61      /* We use the memory in the ELF descriptor.  */
62      elf->state.ELFW(elf,LIBELFBITS).ehdr =
63	&elf->state.ELFW(elf,LIBELFBITS).ehdr_mem;
64
65      /* We clear this memory.  */
66      memset (elf->state.ELFW(elf,LIBELFBITS).ehdr, '\0',
67	      sizeof (ElfW2(LIBELFBITS,Ehdr)));
68
69      /* Mark the ELF header has modified.  */
70      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
71    }
72
73  result = elf->state.ELFW(elf,LIBELFBITS).ehdr;
74
75 out:
76  rwlock_unlock (elf->lock);
77
78  return result;
79}
80INTDEF(elfw2(LIBELFBITS,newehdr))
81