1 /* Update data structures for changes.
2 Copyright (C) 2000-2010 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
9 * the GNU Lesser General Public License as published by the Free
10 Software Foundation; either version 3 of the License, or (at
11 your option) any later version
15 * the GNU General Public License as published by the Free
16 Software Foundation; either version 2 of the License, or (at
17 your option) any later version
19 or both in parallel, as here.
21 elfutils is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received copies of the GNU General Public License and
27 the GNU Lesser General Public License along with this program. If
28 not, see <http://www.gnu.org/licenses/>. */
39 #include <sys/param.h>
42 #include "elf-knowledge.h"
45 # define LIBELFBITS 32
51 ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
52 size_t shnum, int *change_bop)
54 /* Always write the magic bytes. */
55 if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
57 memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
58 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
61 /* Always set the file class. */
62 update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS),
63 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
65 /* Set the data encoding if necessary. */
66 if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE))
68 ehdr->e_ident[EI_DATA] =
69 BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB;
70 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
72 else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM))
74 __libelf_seterrno (ELF_E_DATA_ENCODING);
78 *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN
79 && ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
80 || (BYTE_ORDER == BIG_ENDIAN
81 && ehdr->e_ident[EI_DATA] != ELFDATA2MSB));
83 /* Unconditionally overwrite the ELF version. */
84 update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT,
85 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
87 if (unlikely (ehdr->e_version == EV_NONE)
88 || unlikely (ehdr->e_version >= EV_NUM))
90 __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
94 if (unlikely (shnum >= SHN_LORESERVE))
96 update_if_changed (ehdr->e_shnum, 0,
97 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
100 update_if_changed (ehdr->e_shnum, shnum,
101 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
103 if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)))
105 ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
106 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
115 __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
117 ElfW2(LIBELFBITS,Ehdr) *ehdr;
121 ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf);
123 /* Set the default values. */
124 if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0)
127 /* At least the ELF header is there. */
128 off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
130 /* Set the program header position. */
131 if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL
132 && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
133 || ehdr->e_type == ET_CORE))
134 (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
135 if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
137 /* Only executables, shared objects, and core files have a program
139 if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
140 && unlikely (ehdr->e_type != ET_CORE))
142 __libelf_seterrno (ELF_E_INVALID_PHDR);
147 if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
150 if (elf->flags & ELF_F_LAYOUT)
152 /* The user is supposed to fill out e_phoff. Use it and
153 e_phnum to determine the maximum extend. */
154 size = MAX ((size_t) size,
156 + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
160 update_if_changed (ehdr->e_phoff,
161 elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
164 /* We need no alignment here. */
165 size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum);
174 assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0);
176 if (shnum >= SHN_LORESERVE)
178 /* We have to fill in the number of sections in the header
179 of the zeroth section. */
180 Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
182 update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
183 shnum, scn0->shdr_flags);
186 /* Go over all sections and find out how large they are. */
187 list = &elf->state.ELFW(elf,LIBELFBITS).scns;
189 /* Load the section headers if necessary. This loads the
190 headers for all sections. */
191 if (list->data[1].shdr.ELFW(e,LIBELFBITS) == NULL)
192 (void) __elfw2(LIBELFBITS,getshdr_wrlock) (&list->data[1]);
196 for (size_t cnt = first == true; cnt < list->cnt; ++cnt)
198 Elf_Scn *scn = &list->data[cnt];
199 ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
202 assert (shdr != NULL);
203 ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
204 ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1;
206 /* Set the sh_entsize value if we can reliably detect it. */
207 switch (shdr->sh_type)
210 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
213 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1);
216 /* Only relocatable files can contain section groups. */
217 if (ehdr->e_type != ET_REL)
219 __libelf_seterrno (ELF_E_GROUP_NOT_REL);
223 case SHT_SYMTAB_SHNDX:
224 sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
227 sh_entsize = SH_ENTSIZE_HASH (ehdr);
230 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1);
233 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1);
236 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
239 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1);
241 case SHT_SUNW_syminfo:
242 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1);
248 /* If the section header contained the wrong entry size
249 correct it and mark the header as modified. */
250 update_if_changed (shdr->sh_entsize, sh_entsize,
253 if (scn->data_read == 0
254 && __libelf_set_rawdata_wrlock (scn) != 0)
255 /* Something went wrong. The error value is already set. */
258 /* Iterate over all data blocks. */
259 if (list->data[cnt].data_list_rear != NULL)
261 Elf_Data_List *dl = &scn->data_list;
265 Elf_Data *data = &dl->data.d;
266 if (dl == &scn->data_list && data->d_buf == NULL
267 && scn->rawdata.d.d_buf != NULL)
268 data = &scn->rawdata.d;
270 if (unlikely (data->d_version == EV_NONE)
271 || unlikely (data->d_version >= EV_NUM))
273 __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
277 if (unlikely (! powerof2 (data->d_align)))
279 __libelf_seterrno (ELF_E_INVALID_ALIGN);
283 sh_align = MAX (sh_align, data->d_align);
285 if (elf->flags & ELF_F_LAYOUT)
287 /* The user specified the offset and the size.
288 All we have to do is check whether this block
289 fits in the size specified for the section. */
290 if (unlikely ((GElf_Word) (data->d_off
294 __libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
300 /* Determine the padding. */
301 offset = ((offset + data->d_align - 1)
302 & ~(data->d_align - 1));
304 update_if_changed (data->d_off, offset, changed);
306 offset += data->d_size;
309 /* Next data block. */
314 /* Get the size of the section from the raw data. If
315 none is available the value is zero. */
316 offset += scn->rawdata.d.d_size;
318 if (elf->flags & ELF_F_LAYOUT)
320 size = MAX ((GElf_Word) size,
322 + (shdr->sh_type != SHT_NOBITS
323 ? shdr->sh_size : 0));
325 /* The alignment must be a power of two. This is a
326 requirement from the ELF specification. Additionally
327 we test for the alignment of the section being large
328 enough for the largest alignment required by a data
330 if (unlikely (! powerof2 (shdr->sh_addralign))
331 || unlikely (shdr->sh_addralign < sh_align))
333 __libelf_seterrno (ELF_E_INVALID_ALIGN);
339 /* How much alignment do we need for this section. */
340 update_if_changed (shdr->sh_addralign, sh_align,
343 size = (size + sh_align - 1) & ~(sh_align - 1);
344 int offset_changed = 0;
345 update_if_changed (shdr->sh_offset, (GElf_Word) size,
347 changed |= offset_changed;
349 if (offset_changed && scn->data_list_rear == NULL)
351 /* The position of the section in the file
352 changed. Create the section data list. */
353 if (__elf_getdata_rdlock (scn, NULL) == NULL)
357 /* See whether the section size is correct. */
358 update_if_changed (shdr->sh_size, (GElf_Word) offset,
361 if (shdr->sh_type != SHT_NOBITS)
364 scn->flags |= changed;
367 /* Check that the section size is actually a multiple of
369 if (shdr->sh_entsize != 0
370 && unlikely (shdr->sh_size % shdr->sh_entsize != 0)
371 && (elf->flags & ELF_F_PERMISSIVE) == 0)
373 __libelf_seterrno (ELF_E_INVALID_SHENTSIZE);
378 assert (list->next == NULL || list->cnt == list->max);
382 while ((list = list->next) != NULL);
384 /* Store section information. */
385 if (elf->flags & ELF_F_LAYOUT)
387 /* The user is supposed to fill out e_shoff. Use it and
388 e_shnum (or sh_size of the dummy, first section header)
389 to determine the maximum extend. */
390 size = MAX ((GElf_Word) size,
392 + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
396 /* Align for section header table.
398 Yes, we use `sizeof' and not `__alignof__' since we do not
399 want to be surprised by architectures with less strict
401 #define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off))
402 size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1);
404 update_if_changed (ehdr->e_shoff, (GElf_Word) size, elf->flags);
405 update_if_changed (ehdr->e_shentsize,
406 elf_typesize (LIBELFBITS, ELF_T_SHDR, 1),
409 /* Account for the section header size. */
410 size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum);
414 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags;