1/* Update data structures for changes.
2   Copyright (C) 2000-2010, 2015 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#include <sys/param.h>
40
41#include "libelfP.h"
42#include "elf-knowledge.h"
43
44#ifndef LIBELFBITS
45# define LIBELFBITS 32
46#endif
47
48
49
50static int
51ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
52			       size_t shnum, int *change_bop)
53{
54  /* Always write the magic bytes.  */
55  if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
56    {
57      memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
58      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
59    }
60
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);
64
65  /* Set the data encoding if necessary.  */
66  if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE))
67    {
68      ehdr->e_ident[EI_DATA] =
69	BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB;
70      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
71    }
72  else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM))
73    {
74      __libelf_seterrno (ELF_E_DATA_ENCODING);
75      return 1;
76    }
77  else
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));
82
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);
86
87  if (unlikely (ehdr->e_version == EV_NONE))
88    {
89      ehdr->e_version = EV_CURRENT;
90      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
91    }
92  else if (unlikely (ehdr->e_version >= EV_NUM))
93    {
94      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
95      return 1;
96    }
97
98  if (unlikely (shnum >= SHN_LORESERVE))
99    {
100      update_if_changed (ehdr->e_shnum, 0,
101			 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
102    }
103  else
104    update_if_changed (ehdr->e_shnum, shnum,
105		       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
106
107  if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)))
108    {
109      ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
110      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
111    }
112
113  /* If phnum is zero make sure e_phoff is also zero and not some random
114     value.  That would cause trouble in update_file.  */
115  if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0)
116    {
117      ehdr->e_phoff = 0;
118      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
119    }
120
121  return 0;
122}
123
124
125off_t
126internal_function
127__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
128{
129  ElfW2(LIBELFBITS,Ehdr) *ehdr;
130  int changed = 0;
131  int ehdr_flags = 0;
132
133  ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf);
134
135  /* Set the default values.  */
136  if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0)
137    return -1;
138
139  /* At least the ELF header is there.  */
140  off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
141
142  /* Set the program header position.  */
143  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL
144      && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN
145	  || ehdr->e_type == ET_CORE))
146    (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
147  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
148    {
149      /* Only executables, shared objects, and core files have a program
150	 header.  */
151      if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
152	  && unlikely (ehdr->e_type != ET_CORE))
153	{
154	  __libelf_seterrno (ELF_E_INVALID_PHDR);
155	  return -1;
156	}
157
158      size_t phnum;
159      if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
160	return -1;
161
162      if (elf->flags & ELF_F_LAYOUT)
163	{
164	  /* The user is supposed to fill out e_phoff.  Use it and
165	     e_phnum to determine the maximum extend.  */
166	  size = MAX ((size_t) size,
167		      ehdr->e_phoff
168		      + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
169	}
170      else
171	{
172	  update_if_changed (ehdr->e_phoff,
173			     elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
174			     ehdr_flags);
175
176	  /* We need no alignment here.  */
177	  size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum);
178	}
179    }
180
181  if (shnum > 0)
182    {
183      Elf_ScnList *list;
184      bool first = true;
185
186      assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0);
187
188      if (shnum >= SHN_LORESERVE)
189	{
190	  /* We have to  fill in the number of sections in the header
191	     of the zeroth section.  */
192	  Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
193
194	  update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
195			     shnum, scn0->shdr_flags);
196	}
197
198      /* Go over all sections and find out how large they are.  */
199      list = &elf->state.ELFW(elf,LIBELFBITS).scns;
200
201      /* Load the section headers if necessary.  This loads the
202	 headers for all sections.  */
203      if (list->data[1].shdr.ELFW(e,LIBELFBITS) == NULL)
204	(void) __elfw2(LIBELFBITS,getshdr_wrlock) (&list->data[1]);
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	      off_t offset = 0;
213
214	      assert (shdr != NULL);
215	      ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
216	      ElfW2(LIBELFBITS,Word) 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	      if (scn->data_read == 0
271		  && __libelf_set_rawdata_wrlock (scn) != 0)
272		/* Something went wrong.  The error value is already set.  */
273		return -1;
274
275	      /* Iterate over all data blocks.  */
276	      if (list->data[cnt].data_list_rear != NULL)
277		{
278		  Elf_Data_List *dl = &scn->data_list;
279
280		  while (dl != NULL)
281		    {
282		      Elf_Data *data = &dl->data.d;
283		      if (dl == &scn->data_list && data->d_buf == NULL
284			  && scn->rawdata.d.d_buf != NULL)
285			data = &scn->rawdata.d;
286
287		      if (unlikely (data->d_version == EV_NONE)
288			  || unlikely (data->d_version >= EV_NUM))
289			{
290			  __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
291			  return -1;
292			}
293
294		      if (unlikely (! powerof2 (data->d_align)))
295			{
296			  __libelf_seterrno (ELF_E_INVALID_ALIGN);
297			  return -1;
298			}
299
300		      sh_align = MAX (sh_align, data->d_align);
301
302		      if (elf->flags & ELF_F_LAYOUT)
303			{
304			  /* The user specified the offset and the size.
305			     All we have to do is check whether this block
306			     fits in the size specified for the section.  */
307			  if (unlikely ((GElf_Word) (data->d_off
308						     + data->d_size)
309					> shdr->sh_size))
310			    {
311			      __libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
312			      return -1;
313			    }
314			}
315		      else
316			{
317			  /* Determine the padding.  */
318			  offset = ((offset + data->d_align - 1)
319				    & ~(data->d_align - 1));
320
321			  update_if_changed (data->d_off, offset, changed);
322
323			  offset += data->d_size;
324			}
325
326		      /* Next data block.  */
327		      dl = dl->next;
328		    }
329		}
330	      else
331		/* Get the size of the section from the raw data.  If
332		   none is available the value is zero.  */
333		offset += scn->rawdata.d.d_size;
334
335	      if (elf->flags & ELF_F_LAYOUT)
336		{
337		  size = MAX ((GElf_Word) size,
338			      (shdr->sh_type != SHT_NOBITS
339			       ? shdr->sh_offset + shdr->sh_size : 0));
340
341		  /* The alignment must be a power of two.  This is a
342		     requirement from the ELF specification.  Additionally
343		     we test for the alignment of the section being large
344		     enough for the largest alignment required by a data
345		     block.  */
346		  if (unlikely (! powerof2 (shdr->sh_addralign))
347		      || unlikely ((shdr->sh_addralign ?: 1) < sh_align))
348		    {
349		      __libelf_seterrno (ELF_E_INVALID_ALIGN);
350		      return -1;
351		    }
352		}
353	      else
354		{
355		  /* How much alignment do we need for this section.  */
356		  update_if_changed (shdr->sh_addralign, sh_align,
357				     scn->shdr_flags);
358
359		  size = (size + sh_align - 1) & ~(sh_align - 1);
360		  int offset_changed = 0;
361		  update_if_changed (shdr->sh_offset, (GElf_Word) size,
362				     offset_changed);
363		  changed |= offset_changed;
364
365		  if (offset_changed && scn->data_list_rear == NULL)
366		    {
367		      /* The position of the section in the file
368			 changed.  Create the section data list.  */
369		      if (__elf_getdata_rdlock (scn, NULL) == NULL)
370			return -1;
371		    }
372
373		  /* See whether the section size is correct.  */
374		  update_if_changed (shdr->sh_size, (GElf_Word) offset,
375				     changed);
376
377		  if (shdr->sh_type != SHT_NOBITS)
378		    size += offset;
379
380		  scn->flags |= changed;
381		}
382
383	      /* Check that the section size is actually a multiple of
384		 the entry size.  */
385	      if (shdr->sh_entsize != 0 && shdr->sh_entsize != 1
386		  && (elf->flags & ELF_F_PERMISSIVE) == 0)
387		{
388		  /* For compressed sections check the uncompressed size.  */
389		  ElfW2(LIBELFBITS,Word) sh_size;
390		  if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
391		    sh_size = shdr->sh_size;
392		  else
393		    {
394		      ElfW2(LIBELFBITS,Chdr) *chdr;
395		      chdr = elfw2(LIBELFBITS,getchdr) (scn);
396		      if (unlikely (chdr == NULL))
397			return -1;
398		      sh_size = chdr->ch_size;
399		    }
400
401		  if (unlikely (sh_size % shdr->sh_entsize != 0))
402		    {
403		      __libelf_seterrno (ELF_E_INVALID_SHENTSIZE);
404		      return -1;
405		    }
406		}
407	    }
408
409	  assert (list->next == NULL || list->cnt == list->max);
410
411	  first = false;
412	}
413      while ((list = list->next) != NULL);
414
415      /* Store section information.  */
416      update_if_changed (ehdr->e_shentsize,
417			 elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), ehdr_flags);
418      if (elf->flags & ELF_F_LAYOUT)
419	{
420	  /* The user is supposed to fill out e_shoff.  Use it and
421	     e_shnum (or sh_size of the dummy, first section header)
422	     to determine the maximum extend.  */
423	  size = MAX ((GElf_Word) size,
424		      (ehdr->e_shoff
425		       + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
426	}
427      else
428	{
429	  /* Align for section header table.
430
431	     Yes, we use `sizeof' and not `__alignof__' since we do not
432	     want to be surprised by architectures with less strict
433	     alignment rules.  */
434#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off))
435	  size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1);
436
437	  update_if_changed (ehdr->e_shoff, (GElf_Word) size, elf->flags);
438
439	  /* Account for the section header size.  */
440	  size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum);
441	}
442    }
443
444  elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags;
445
446  return size;
447}
448