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