1 /* Update data structures for changes.
2 Copyright (C) 2000-2010, 2015, 2016 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
8
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
12
13 or
14
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
18
19 or both in parallel, as here.
20
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.
25
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/>. */
29
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33
34 #include <assert.h>
35 #include <endian.h>
36 #include <libelf.h>
37 #include <stdbool.h>
38 #include <string.h>
39
40 #include <system.h>
41 #include "libelfP.h"
42 #include "elf-knowledge.h"
43
44 #ifndef LIBELFBITS
45 # define LIBELFBITS 32
46 #endif
47
48 /* Some fields contain 32/64 sizes. We cannot use Elf32/64_Word for those,
49 since those are both 32bits. Elf32/64_Xword is always 64bits. */
50 #define Elf32_SizeWord Elf32_Word
51 #define Elf64_SizeWord Elf64_Xword
52
53
54 static int
ELFW(default_ehdr,LIBELFBITS)55 ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
56 size_t shnum, int *change_bop)
57 {
58 /* Always write the magic bytes. */
59 if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
60 {
61 memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
62 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
63 }
64
65 /* Always set the file class. */
66 update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS),
67 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
68
69 /* Set the data encoding if necessary. */
70 if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE))
71 {
72 ehdr->e_ident[EI_DATA] =
73 BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB;
74 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
75 }
76 else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM))
77 {
78 __libelf_seterrno (ELF_E_DATA_ENCODING);
79 return 1;
80 }
81 else
82 *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN
83 && ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
84 || (BYTE_ORDER == BIG_ENDIAN
85 && ehdr->e_ident[EI_DATA] != ELFDATA2MSB));
86
87 /* Unconditionally overwrite the ELF version. */
88 update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT,
89 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
90
91 if (unlikely (ehdr->e_version == EV_NONE))
92 {
93 ehdr->e_version = EV_CURRENT;
94 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
95 }
96 else if (unlikely (ehdr->e_version != EV_CURRENT))
97 {
98 __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
99 return 1;
100 }
101
102 if (unlikely (shnum >= SHN_LORESERVE))
103 {
104 update_if_changed (ehdr->e_shnum, 0,
105 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
106 }
107 else
108 update_if_changed (ehdr->e_shnum, shnum,
109 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
110
111 if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)))
112 {
113 ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
114 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
115 }
116
117 /* If phnum is zero make sure e_phoff is also zero and not some random
118 value. That would cause trouble in update_file. */
119 if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0)
120 {
121 ehdr->e_phoff = 0;
122 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
123 }
124
125 return 0;
126 }
127
128
129 int64_t
130 internal_function
__elfw2(LIBELFBITS,updatenull_wrlock)131 __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
132 {
133 ElfW2(LIBELFBITS,Ehdr) *ehdr;
134 int changed = 0;
135 int ehdr_flags = 0;
136
137 ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf);
138
139 /* Set the default values. */
140 if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0)
141 return -1;
142
143 /* At least the ELF header is there. */
144 ElfW2(LIBELFBITS,SizeWord) size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
145
146 /* Set the program header position. */
147 if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
148 (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
149 if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
150 {
151 size_t phnum;
152 if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
153 return -1;
154
155 if (elf->flags & ELF_F_LAYOUT)
156 {
157 /* The user is supposed to fill out e_phoff. Use it and
158 e_phnum to determine the maximum extend. */
159 size = MAX (size,
160 ehdr->e_phoff
161 + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
162 }
163 else
164 {
165 update_if_changed (ehdr->e_phoff,
166 elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
167 ehdr_flags);
168
169 /* We need no alignment here. */
170 size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum);
171 }
172 }
173
174 if (shnum > 0)
175 {
176 struct Elf_Scn *scn1 = NULL;
177 Elf_ScnList *list;
178 bool first = true;
179
180 assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0);
181
182 if (shnum >= SHN_LORESERVE)
183 {
184 /* We have to fill in the number of sections in the header
185 of the zeroth section. */
186 Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
187
188 update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
189 shnum, scn0->shdr_flags);
190 }
191
192 /* Go over all sections and find out how large they are. */
193 list = &elf->state.ELFW(elf,LIBELFBITS).scns;
194
195 /* Find the first section. */
196 if (list->cnt > 1)
197 scn1 = &list->data[1];
198 else if (list->next != NULL)
199 scn1 = &list->next->data[0];
200
201 /* Load the section headers if necessary. This loads the
202 headers for all sections. */
203 if (scn1 != NULL && scn1->shdr.ELFW(e,LIBELFBITS) == NULL)
204 (void) __elfw2(LIBELFBITS,getshdr_wrlock) (scn1);
205
206 do
207 {
208 for (size_t cnt = first == true; cnt < list->cnt; ++cnt)
209 {
210 Elf_Scn *scn = &list->data[cnt];
211 ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
212 int64_t offset = 0;
213
214 assert (shdr != NULL);
215 ElfW2(LIBELFBITS,SizeWord) sh_entsize = shdr->sh_entsize;
216 ElfW2(LIBELFBITS,SizeWord) sh_align = shdr->sh_addralign ?: 1;
217 if (unlikely (! powerof2 (sh_align)))
218 {
219 __libelf_seterrno (ELF_E_INVALID_ALIGN);
220 return -1;
221 }
222
223 /* Set the sh_entsize value if we can reliably detect it. */
224 switch (shdr->sh_type)
225 {
226 case SHT_SYMTAB:
227 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
228 break;
229 case SHT_RELA:
230 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1);
231 break;
232 case SHT_GROUP:
233 /* Only relocatable files can contain section groups. */
234 if (ehdr->e_type != ET_REL)
235 {
236 __libelf_seterrno (ELF_E_GROUP_NOT_REL);
237 return -1;
238 }
239 FALLTHROUGH;
240 case SHT_SYMTAB_SHNDX:
241 sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
242 break;
243 case SHT_HASH:
244 sh_entsize = SH_ENTSIZE_HASH (ehdr);
245 break;
246 case SHT_DYNAMIC:
247 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1);
248 break;
249 case SHT_REL:
250 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1);
251 break;
252 case SHT_DYNSYM:
253 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
254 break;
255 case SHT_SUNW_move:
256 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1);
257 break;
258 case SHT_SUNW_syminfo:
259 sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1);
260 break;
261 default:
262 break;
263 }
264
265 /* If the section header contained the wrong entry size
266 correct it and mark the header as modified. */
267 update_if_changed (shdr->sh_entsize, sh_entsize,
268 scn->shdr_flags);
269
270 /* Likewise for the alignment of a compressed section.
271 For a SHF_COMPRESSED section set the correct
272 sh_addralign value, which must match the d_align of
273 the data (see __libelf_set_rawdata in elf_getdata.c). */
274 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
275 {
276 sh_align = __libelf_type_align (ELFW(ELFCLASS,LIBELFBITS),
277 ELF_T_CHDR);
278 update_if_changed (shdr->sh_addralign, sh_align,
279 scn->shdr_flags);
280 }
281
282 if (scn->data_read == 0
283 && __libelf_set_rawdata_wrlock (scn) != 0)
284 /* Something went wrong. The error value is already set. */
285 return -1;
286
287 /* Iterate over all data blocks. */
288 if (list->data[cnt].data_list_rear != NULL)
289 {
290 Elf_Data_List *dl = &scn->data_list;
291
292 while (dl != NULL)
293 {
294 Elf_Data *data = &dl->data.d;
295 if (dl == &scn->data_list && data->d_buf == NULL
296 && scn->rawdata.d.d_buf != NULL)
297 data = &scn->rawdata.d;
298
299 if (unlikely (data->d_version != EV_CURRENT))
300 {
301 __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
302 return -1;
303 }
304
305 if (unlikely (! powerof2 (data->d_align)))
306 {
307 __libelf_seterrno (ELF_E_INVALID_ALIGN);
308 return -1;
309 }
310
311 sh_align = MAX (sh_align, data->d_align);
312
313 if (elf->flags & ELF_F_LAYOUT)
314 {
315 /* The user specified the offset and the size.
316 All we have to do is check whether this block
317 fits in the size specified for the section. */
318 if (unlikely ((ElfW2(LIBELFBITS,SizeWord))
319 (data->d_off + data->d_size)
320 > shdr->sh_size))
321 {
322 __libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
323 return -1;
324 }
325 }
326 else
327 {
328 /* Determine the padding. */
329 offset = ((offset + data->d_align - 1)
330 & ~(data->d_align - 1));
331
332 update_if_changed (data->d_off, offset, changed);
333
334 offset += data->d_size;
335 }
336
337 /* Next data block. */
338 dl = dl->next;
339 }
340 }
341 else
342 /* Get the size of the section from the raw data. If
343 none is available the value is zero. */
344 offset += scn->rawdata.d.d_size;
345
346 if (elf->flags & ELF_F_LAYOUT)
347 {
348 size = MAX (size,
349 (shdr->sh_type != SHT_NOBITS
350 ? shdr->sh_offset + shdr->sh_size : 0));
351
352 /* The alignment must be a power of two. This is a
353 requirement from the ELF specification. Additionally
354 we test for the alignment of the section being large
355 enough for the largest alignment required by a data
356 block. */
357 if (unlikely (! powerof2 (shdr->sh_addralign))
358 || unlikely ((shdr->sh_addralign ?: 1) < sh_align))
359 {
360 __libelf_seterrno (ELF_E_INVALID_ALIGN);
361 return -1;
362 }
363 }
364 else
365 {
366 /* How much alignment do we need for this section. */
367 update_if_changed (shdr->sh_addralign, sh_align,
368 scn->shdr_flags);
369
370 size = (size + sh_align - 1) & ~(sh_align - 1);
371 int offset_changed = 0;
372 update_if_changed (shdr->sh_offset, size, offset_changed);
373 changed |= offset_changed;
374
375 if (offset_changed && scn->data_list_rear == NULL)
376 {
377 /* The position of the section in the file
378 changed. Create the section data list. */
379 if (__elf_getdata_rdlock (scn, NULL) == NULL)
380 return -1;
381 }
382
383 /* See whether the section size is correct. */
384 int size_changed = 0;
385 update_if_changed (shdr->sh_size,
386 (ElfW2(LIBELFBITS,SizeWord)) offset,
387 size_changed);
388 changed |= size_changed;
389
390 if (shdr->sh_type != SHT_NOBITS)
391 size += offset;
392
393 scn->shdr_flags |= (offset_changed | size_changed);
394 scn->flags |= changed;
395 }
396
397 /* Check that the section size is actually a multiple of
398 the entry size. */
399 if (shdr->sh_entsize != 0 && shdr->sh_entsize != 1
400 && (elf->flags & ELF_F_PERMISSIVE) == 0)
401 {
402 /* For compressed sections check the uncompressed size. */
403 ElfW2(LIBELFBITS,SizeWord) sh_size;
404 if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
405 sh_size = shdr->sh_size;
406 else
407 {
408 ElfW2(LIBELFBITS,Chdr) *chdr;
409 chdr = elfw2(LIBELFBITS,getchdr) (scn);
410 if (unlikely (chdr == NULL))
411 return -1;
412 sh_size = chdr->ch_size;
413 }
414
415 if (unlikely (sh_size % shdr->sh_entsize != 0))
416 {
417 __libelf_seterrno (ELF_E_INVALID_SHENTSIZE);
418 return -1;
419 }
420 }
421 }
422
423 assert (list->next == NULL || list->cnt == list->max);
424
425 first = false;
426 }
427 while ((list = list->next) != NULL);
428
429 /* Store section information. */
430 update_if_changed (ehdr->e_shentsize,
431 elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), ehdr_flags);
432 if (elf->flags & ELF_F_LAYOUT)
433 {
434 /* The user is supposed to fill out e_shoff. Use it and
435 e_shnum (or sh_size of the dummy, first section header)
436 to determine the maximum extend. */
437 size = MAX (size,
438 (ehdr->e_shoff
439 + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
440 }
441 else
442 {
443 /* Align for section header table.
444
445 Yes, we use `sizeof' and not `__alignof__' since we do not
446 want to be surprised by architectures with less strict
447 alignment rules. */
448 #define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off))
449 size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1);
450
451 update_if_changed (ehdr->e_shoff, size, elf->flags);
452
453 /* Account for the section header size. */
454 size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum);
455 }
456 }
457
458 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags;
459
460 return size;
461 }
462