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)
91 /* Allocate a new program header with the appropriate number of
93 result = (ElfW2(LIBELFBITS,Phdr) *)
94 realloc (elf->state.ELFW(elf,LIBELFBITS).phdr,
95 count * sizeof (ElfW2(LIBELFBITS,Phdr)));
97 __libelf_seterrno (ELF_E_NOMEM);
100 /* Now set the result. */
101 elf->state.ELFW(elf,LIBELFBITS).phdr = result;
102 /* Clear the whole memory. */
103 memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr)));
104 /* Set the `e_phnum' member to the new value. */
105 elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = count;
106 /* Also set the size. */
107 elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize =
108 elf_typesize (LIBELFBITS, ELF_T_PHDR, 1);
109 /* Remember we allocated the array and mark the structure is
111 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
112 ELF_F_DIRTY | ELF_F_MALLOCED;
113 /* We have to rewrite the entire file if the size of the
114 program header is changed. */
115 elf->flags |= ELF_F_DIRTY;
120 /* We have the same number of entries. Just clear the array. */
121 assert (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize
122 == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
124 /* Mark the structure as modified. */
125 elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY;
127 result = elf->state.ELFW(elf,LIBELFBITS).phdr;
131 rwlock_unlock (elf->lock);
135 INTDEF(elfw2(LIBELFBITS,newphdr))