1 /* Create new ELF program header table.
2 Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
3 Written by Ulrich Drepper <drepper@redhat.com>, 1998.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation.
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.
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. */
29 # define LIBELFBITS 32
33 ElfW2(LIBELFBITS,Phdr) *
34 elfw2(LIBELFBITS,newphdr) (Elf *elf, size_t count)
36 ElfW2(LIBELFBITS,Phdr) *result;
41 if (unlikely (elf->kind != ELF_K_ELF))
43 __libelf_seterrno (ELF_E_INVALID_HANDLE);
47 rwlock_wrlock (elf->lock);
50 elf->class = ELFW(ELFCLASS,LIBELFBITS);
51 else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
53 __libelf_seterrno (ELF_E_INVALID_CLASS);
58 if (unlikely (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL))
60 __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
65 /* A COUNT of zero means remove existing table. */
68 /* Free the old program header. */
69 if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
71 if (elf->state.ELFW(elf,LIBELFBITS).phdr_flags & ELF_F_MALLOCED)
72 free (elf->state.ELFW(elf,LIBELFBITS).phdr);
74 /* Set the pointer to NULL. */
75 elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
76 /* Set the `e_phnum' member to the new value. */
77 elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = 0;
78 /* Also set the size. */
79 elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize =
80 sizeof (ElfW2(LIBELFBITS,Phdr));
82 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY;
83 elf->flags |= ELF_F_DIRTY;
84 __libelf_seterrno (ELF_E_NOERROR);
89 else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count ||
90 elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
92 /* Allocate a new program header with the appropriate number of
94 result = (ElfW2(LIBELFBITS,Phdr) *)
95 realloc (elf->state.ELFW(elf,LIBELFBITS).phdr,
96 count * sizeof (ElfW2(LIBELFBITS,Phdr)));
98 __libelf_seterrno (ELF_E_NOMEM);
101 /* Now set the result. */
102 elf->state.ELFW(elf,LIBELFBITS).phdr = result;
103 /* Clear the whole memory. */
104 memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr)));
105 /* Set the `e_phnum' member to the new value. */
106 elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = count;
107 /* Also set the size. */
108 elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize =
109 elf_typesize (LIBELFBITS, ELF_T_PHDR, 1);
110 /* Remember we allocated the array and mark the structure is
112 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
113 ELF_F_DIRTY | ELF_F_MALLOCED;
114 /* We have to rewrite the entire file if the size of the
115 program header is changed. */
116 elf->flags |= ELF_F_DIRTY;
121 /* We have the same number of entries. Just clear the array. */
122 assert (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize
123 == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
125 /* Mark the structure as modified. */
126 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY;
128 result = elf->state.ELFW(elf,LIBELFBITS).phdr;
132 rwlock_unlock (elf->lock);
136 INTDEF(elfw2(LIBELFBITS,newphdr))