elf_strptr.c revision b08d5a8fb42f4586d756068065186b5af7e48da
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Return string pointer from string section.
2b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
3b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   This program is free software; you can redistribute it and/or modify
6b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   it under the terms of the GNU General Public License as published by
7b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   the Free Software Foundation, version 2.
8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
9b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   This program is distributed in the hope that it will be useful,
10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   but WITHOUT ANY WARRANTY; without even the implied warranty of
11b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   GNU General Public License for more details.
13b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
14b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   You should have received a copy of the GNU General Public License
15b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   along with this program; if not, write to the Free Software Foundation,
16b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H
19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h>
20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libelf.h>
23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stddef.h>
24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libelfP.h"
26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperchar *
29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperelf_strptr (elf, idx, offset)
30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Elf *elf;
31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t idx;
32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     size_t offset;
33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (elf == NULL)
35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return NULL;
36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (elf->kind != ELF_K_ELF)
38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libelf_seterrno (ELF_E_INVALID_HANDLE);
40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  rwlock_rdlock (elf->lock);
44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  char *result = NULL;
46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Scn *strscn;
47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Find the section in the list.  */
49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_ScnList *runp = (elf->class == ELFCLASS32
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       || (offsetof (struct Elf, state.elf32.scns)
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			   == offsetof (struct Elf, state.elf64.scns))
52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       ? &elf->state.elf32.scns : &elf->state.elf64.scns);
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (1)
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (idx < runp->max)
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (idx < runp->cnt)
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    strscn = &runp->data[idx];
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  else
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      __libelf_seterrno (ELF_E_INVALID_INDEX);
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      goto out;
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      idx -= runp->max;
68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      runp = runp->next;
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (runp == NULL)
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_INVALID_INDEX);
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (elf->class == ELFCLASS32)
78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (unlikely (strscn->shdr.e32->sh_type != SHT_STRTAB))
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* This is no string section.  */
82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_INVALID_SECTION);
83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (unlikely (offset >= strscn->shdr.e32->sh_size))
87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* The given offset is too big, it is beyond this section.  */
89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else
94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (unlikely (strscn->shdr.e64->sh_type != SHT_STRTAB))
96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* This is no string section.  */
98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_INVALID_SECTION);
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (unlikely (offset >= strscn->shdr.e64->sh_size))
103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* The given offset is too big, it is beyond this section.  */
105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  goto out;
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (strscn->rawdata_base == NULL
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Read the section data.  */
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && __libelf_set_rawdata (strscn) != 0)
113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    goto out;
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result = &strscn->rawdata_base[offset];
116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper out:
118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  rwlock_unlock (elf->lock);
119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return result;
121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
122b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperINTDEF(elf_strptr)
123