• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Update section header.
2    Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
3    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, version 2.
8 
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.
13 
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.  */
17 
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21 
22 #include <gelf.h>
23 #include <string.h>
24 
25 #include "libelfP.h"
26 
27 
28 int
gelf_update_shdr(Elf_Scn * scn,GElf_Shdr * src)29 gelf_update_shdr (Elf_Scn *scn, GElf_Shdr *src)
30 {
31   int result = 0;
32   Elf *elf;
33 
34   if (scn == NULL || src == NULL)
35     return 0;
36 
37   elf = scn->elf;
38   rwlock_wrlock (elf->lock);
39 
40   if (elf->class == ELFCLASS32)
41     {
42       Elf32_Shdr *shdr = scn->shdr.e32 ?: INTUSE(elf32_getshdr) (scn);
43 
44       if (shdr == NULL)
45 	{
46 	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
47 	  goto out;
48 	}
49 
50       if (unlikely (src->sh_flags > 0xffffffffull)
51 	  || unlikely (src->sh_addr > 0xffffffffull)
52 	  || unlikely (src->sh_offset > 0xffffffffull)
53 	  || unlikely (src->sh_size > 0xffffffffull)
54 	  || unlikely (src->sh_addralign > 0xffffffffull)
55 	  || unlikely (src->sh_entsize > 0xffffffffull))
56 	{
57 	  __libelf_seterrno (ELF_E_INVALID_DATA);
58 	  goto out;
59 	}
60 
61 #define COPY(name) \
62       shdr->name = src->name
63       COPY (sh_name);
64       COPY (sh_type);
65       COPY (sh_flags);
66       COPY (sh_addr);
67       COPY (sh_offset);
68       COPY (sh_size);
69       COPY (sh_link);
70       COPY (sh_info);
71       COPY (sh_addralign);
72       COPY (sh_entsize);
73     }
74   else
75     {
76       Elf64_Shdr *shdr = scn->shdr.e64 ?: INTUSE(elf64_getshdr) (scn);
77 
78       if (shdr == NULL)
79 	{
80 	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
81 	  goto out;
82 	}
83 
84       /* We only have to copy the data.  */
85       (void) memcpy (shdr, src, sizeof (GElf_Shdr));
86     }
87 
88   result = 1;
89 
90  out:
91   rwlock_unlock (elf->lock);
92 
93   return result;
94 }
95