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