1cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath/* Update information in dynamic table at the given index.
21ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard   Copyright (C) 2007, 2015 Red Hat, Inc.
3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is part of elfutils.
4cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is free software; you can redistribute it and/or modify
6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   it under the terms of either
7cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU Lesser General Public License as published by the Free
9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 3 of the License, or (at
10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or
13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU General Public License as published by the Free
15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 2 of the License, or (at
16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or both in parallel, as here.
19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   elfutils is distributed in the hope that it will be useful, but
21cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath   WITHOUT ANY WARRANTY; without even the implied warranty of
22cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath   General Public License for more details.
24cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
25de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   You should have received copies of the GNU General Public License and
26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   the GNU Lesser General Public License along with this program.  If
27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   not, see <http://www.gnu.org/licenses/>.  */
28cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
29cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#ifdef HAVE_CONFIG_H
30cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath# include <config.h>
31cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#endif
32cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
33cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#include <gelf.h>
34cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#include <string.h>
35cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
36cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#include "libelfP.h"
37cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
38cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
39cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrathint
401ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaardgelf_update_auxv (Elf_Data *data, int ndx, GElf_auxv_t *src)
41cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath{
42cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
43cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  Elf_Scn *scn;
44cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  int result = 0;
45cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
46cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  if (data == NULL)
47cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    return 0;
48cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
49cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  if (unlikely (ndx < 0))
50cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    {
51cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      __libelf_seterrno (ELF_E_INVALID_INDEX);
52cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      return 0;
53cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    }
54cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
55cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  if (unlikely (data_scn->d.d_type != ELF_T_AUXV))
56cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    {
57cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      /* The type of the data better should match.  */
58cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      __libelf_seterrno (ELF_E_DATA_MISMATCH);
59cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      return 0;
60cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    }
61cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
62cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  scn = data_scn->s;
63b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  rwlock_wrlock (scn->elf->lock);
64cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
65cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  if (scn->elf->class == ELFCLASS32)
66cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    {
67cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      Elf32_auxv_t *auxv;
68cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
69cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      /* There is the possibility that the values in the input are
70cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	 too large.  */
71cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      if (unlikely (src->a_type > 0xffffffffll)
72cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	  || unlikely (src->a_un.a_val > 0xffffffffull))
73cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	{
74cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	  __libelf_seterrno (ELF_E_INVALID_DATA);
75cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	  goto out;
76cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	}
77cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
78cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      /* Check whether we have to resize the data buffer.  */
79cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size))
80cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	{
81cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	  __libelf_seterrno (ELF_E_INVALID_INDEX);
82cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	  goto out;
83cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	}
84cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
85cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      auxv = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx];
86cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
87cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      auxv->a_type = src->a_type;
88cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      auxv->a_un.a_val = src->a_un.a_val;
89cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    }
90cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  else
91cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    {
92cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      /* Check whether we have to resize the data buffer.  */
93cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      if (unlikely ((ndx + 1) * sizeof (Elf64_auxv_t) > data_scn->d.d_size))
94cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	{
95cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	  __libelf_seterrno (ELF_E_INVALID_INDEX);
96cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	  goto out;
97cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath	}
98cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
99cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath      ((Elf64_auxv_t *) data_scn->d.d_buf)[ndx] = *src;
100cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath    }
101cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
102cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  result = 1;
103cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
104cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  /* Mark the section as modified.  */
105cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  scn->flags |= ELF_F_DIRTY;
106cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
107cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath out:
108b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  rwlock_unlock (scn->elf->lock);
109cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath
110cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath  return result;
111cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath}
112