blob: b066fd62f8c73e71c6622fc09435b74b78457d25 [file] [log] [blame]
The Android Open Source Project593c3652008-10-21 07:00:00 -07001/* Update information in dynamic table at the given index.
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
28int
29gelf_update_dyn (data, ndx, src)
30 Elf_Data *data;
31 int ndx;
32 GElf_Dyn *src;
33{
34 Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
35 Elf_Scn *scn;
36 int result = 0;
37
38 if (data == NULL)
39 return 0;
40
41 if (unlikely (ndx < 0))
42 {
43 __libelf_seterrno (ELF_E_INVALID_INDEX);
44 return 0;
45 }
46
47 if (unlikely (data_scn->d.d_type != ELF_T_DYN))
48 {
49 /* The type of the data better should match. */
50 __libelf_seterrno (ELF_E_DATA_MISMATCH);
51 return 0;
52 }
53
54 scn = data_scn->s;
55 rwlock_wrlock (scn->elf->lock);
56
57 if (scn->elf->class == ELFCLASS32)
58 {
59 Elf32_Dyn *dyn;
60
61 /* There is the possibility that the values in the input are
62 too large. */
63 if (unlikely (src->d_tag < -0x80000000ll)
64 || unlikely (src->d_tag > 0x7fffffffll)
65 || unlikely (src->d_un.d_val > 0xffffffffull))
66 {
67 __libelf_seterrno (ELF_E_INVALID_DATA);
68 goto out;
69 }
70
71 /* Check whether we have to resize the data buffer. */
72 if (unlikely ((ndx + 1) * sizeof (Elf32_Dyn) > data_scn->d.d_size))
73 {
74 __libelf_seterrno (ELF_E_INVALID_INDEX);
75 goto out;
76 }
77
78 dyn = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx];
79
80 dyn->d_tag = src->d_tag;
81 dyn->d_un.d_val = src->d_un.d_val;
82 }
83 else
84 {
85 /* Check whether we have to resize the data buffer. */
86 if (unlikely ((ndx + 1) * sizeof (Elf64_Dyn) > data_scn->d.d_size))
87 {
88 __libelf_seterrno (ELF_E_INVALID_INDEX);
89 goto out;
90 }
91
92 ((Elf64_Dyn *) data_scn->d.d_buf)[ndx] = *src;
93 }
94
95 result = 1;
96
97 /* Mark the section as modified. */
98 scn->flags |= ELF_F_DIRTY;
99
100 out:
101 rwlock_unlock (scn->elf->lock);
102
103 return result;
104}