1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Update symbol information and section index in symbol table at the
2b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   given index.
31ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
4de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is part of elfutils.
5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
6b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is free software; you can redistribute it and/or modify
8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   it under the terms of either
9b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU Lesser General Public License as published by the Free
11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 3 of the License, or (at
12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or
15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU General Public License as published by the Free
17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 2 of the License, or (at
18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or both in parallel, as here.
21de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
22de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   elfutils is distributed in the hope that it will be useful, but
23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   WITHOUT ANY WARRANTY; without even the implied warranty of
24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   General Public License for more details.
26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   You should have received copies of the GNU General Public License and
28de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   the GNU Lesser General Public License along with this program.  If
29de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   not, see <http://www.gnu.org/licenses/>.  */
30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H
32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h>
33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <gelf.h>
36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h>
37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h>
38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libelfP.h"
40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
431ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaardgelf_update_symshndx (Elf_Data *symdata, Elf_Data *shndxdata, int ndx,
441ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard		      GElf_Sym *src, Elf32_Word srcshndx)
45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata;
47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata;
48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Scn *scn;
49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf32_Word *shndx = NULL;
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  int result = 0;
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (symdata == NULL)
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return 0;
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (unlikely (symdata_scn->d.d_type != ELF_T_SYM))
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* The type of the data better should match.  */
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libelf_seterrno (ELF_E_DATA_MISMATCH);
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return 0;
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  scn = symdata_scn->s;
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We simply have to believe the user that the two sections belong to
64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     the same ELF file.  */
65b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  rwlock_wrlock (scn->elf->lock);
66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* The user is not required to pass a data descriptor for an extended
68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     section index table.  */
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shndxdata_scn != NULL)
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size))
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_INVALID_INDEX);
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      shndx = &((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx];
78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* But if s/he does not the extended sectio index must be zero.  */
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (unlikely (srcshndx != 0))
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libelf_seterrno (ELF_E_INVALID_INDEX);
83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      goto out;
84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (scn->elf->class == ELFCLASS32)
87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Elf32_Sym *sym;
89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* There is the possibility that the values in the input are
91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 too large.  */
92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (unlikely (src->st_value > 0xffffffffull)
93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  || unlikely (src->st_size > 0xffffffffull))
94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_INVALID_DATA);
96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Check whether we have to resize the data buffer.  */
100a9039623c272f458a53f09009c2a0e1d6e60491dJakub Jelinek      if (INVALID_NDX (ndx, Elf32_Sym, &symdata_scn->d))
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_INVALID_INDEX);
103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      sym = &((Elf32_Sym *) symdata_scn->d.d_buf)[ndx];
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define COPY(name) \
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      sym->name = src->name
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      COPY (st_name);
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      COPY (st_value);
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      COPY (st_size);
113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Please note that we can simply copy the `st_info' element since
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 for the 64 bit variant.  */
116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      COPY (st_info);
117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      COPY (st_other);
118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      COPY (st_shndx);
119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else
121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Check whether we have to resize the data buffer.  */
123a9039623c272f458a53f09009c2a0e1d6e60491dJakub Jelinek      if (INVALID_NDX (ndx, Elf64_Sym, &symdata_scn->d))
124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_INVALID_INDEX);
126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ((Elf64_Sym *) symdata_scn->d.d_buf)[ndx] = *src;
130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Now we can store the section index.  */
133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shndx != NULL)
134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    *shndx = srcshndx;
135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result = 1;
137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Mark the section as modified.  */
139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  scn->flags |= ELF_F_DIRTY;
140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out:
142b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath  rwlock_unlock (scn->elf->lock);
143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return result;
145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
146