Home | History | Annotate | Download | only in libelf
      1 /* Return string pointer from string section.
      2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
      3    Contributed by Ulrich Drepper <drepper (at) redhat.com>, 1998.
      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 <libelf.h>
     23 #include <stddef.h>
     24 
     25 #include "libelfP.h"
     26 
     27 
     28 char *
     29 elf_strptr (elf, idx, offset)
     30      Elf *elf;
     31      size_t idx;
     32      size_t offset;
     33 {
     34   if (elf == NULL)
     35     return NULL;
     36 
     37   if (elf->kind != ELF_K_ELF)
     38     {
     39       __libelf_seterrno (ELF_E_INVALID_HANDLE);
     40       return NULL;
     41     }
     42 
     43   rwlock_rdlock (elf->lock);
     44 
     45   char *result = NULL;
     46   Elf_Scn *strscn;
     47 
     48   /* Find the section in the list.  */
     49   Elf_ScnList *runp = (elf->class == ELFCLASS32
     50 		       || (offsetof (struct Elf, state.elf32.scns)
     51 			   == offsetof (struct Elf, state.elf64.scns))
     52 		       ? &elf->state.elf32.scns : &elf->state.elf64.scns);
     53   while (1)
     54     {
     55       if (idx < runp->max)
     56 	{
     57 	  if (idx < runp->cnt)
     58 	    strscn = &runp->data[idx];
     59 	  else
     60 	    {
     61 	      __libelf_seterrno (ELF_E_INVALID_INDEX);
     62 	      goto out;
     63 	    }
     64 	  break;
     65 	}
     66 
     67       idx -= runp->max;
     68 
     69       runp = runp->next;
     70       if (runp == NULL)
     71 	{
     72 	  __libelf_seterrno (ELF_E_INVALID_INDEX);
     73 	  goto out;
     74 	}
     75     }
     76 
     77   if (elf->class == ELFCLASS32)
     78     {
     79       if (unlikely (strscn->shdr.e32->sh_type != SHT_STRTAB))
     80 	{
     81 	  /* This is no string section.  */
     82 	  __libelf_seterrno (ELF_E_INVALID_SECTION);
     83 	  goto out;
     84 	}
     85 
     86       if (unlikely (offset >= strscn->shdr.e32->sh_size))
     87 	{
     88 	  /* The given offset is too big, it is beyond this section.  */
     89 	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
     90 	  goto out;
     91 	}
     92     }
     93   else
     94     {
     95       if (unlikely (strscn->shdr.e64->sh_type != SHT_STRTAB))
     96 	{
     97 	  /* This is no string section.  */
     98 	  __libelf_seterrno (ELF_E_INVALID_SECTION);
     99 	  goto out;
    100 	}
    101 
    102       if (unlikely (offset >= strscn->shdr.e64->sh_size))
    103 	{
    104 	  /* The given offset is too big, it is beyond this section.  */
    105 	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
    106 	  goto out;
    107 	}
    108     }
    109 
    110   if (strscn->rawdata_base == NULL
    111       /* Read the section data.  */
    112       && __libelf_set_rawdata (strscn) != 0)
    113     goto out;
    114 
    115   result = &strscn->rawdata_base[offset];
    116 
    117  out:
    118   rwlock_unlock (elf->lock);
    119 
    120   return result;
    121 }
    122 INTDEF(elf_strptr)
    123