LCOV - code coverage report
Current view: top level - libelf - gelf_getsymshndx.c (source / functions) Hit Total Coverage
Test: elfutils- Lines: 31 39 79.5 %
Date: 2020-06-11 18:20:19 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Get symbol information and separate section index from symbol table
       2             :    at the given index.
       3             :    Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
       4             :    This file is part of elfutils.
       5             :    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
       6             : 
       7             :    This file is free software; you can redistribute it and/or modify
       8             :    it under the terms of either
       9             : 
      10             :      * the GNU Lesser General Public License as published by the Free
      11             :        Software Foundation; either version 3 of the License, or (at
      12             :        your option) any later version
      13             : 
      14             :    or
      15             : 
      16             :      * the GNU General Public License as published by the Free
      17             :        Software Foundation; either version 2 of the License, or (at
      18             :        your option) any later version
      19             : 
      20             :    or both in parallel, as here.
      21             : 
      22             :    elfutils is distributed in the hope that it will be useful, but
      23             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      24             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      25             :    General Public License for more details.
      26             : 
      27             :    You should have received copies of the GNU General Public License and
      28             :    the GNU Lesser General Public License along with this program.  If
      29             :    not, see <http://www.gnu.org/licenses/>.  */
      30             : 
      31             : #ifdef HAVE_CONFIG_H
      32             : # include <config.h>
      33             : #endif
      34             : 
      35             : #include <assert.h>
      36             : #include <gelf.h>
      37             : #include <string.h>
      38             : 
      39             : #include "libelfP.h"
      40             : 
      41             : 
      42             : GElf_Sym *
      43  1992780287 : gelf_getsymshndx (Elf_Data *symdata, Elf_Data *shndxdata, int ndx,
      44             :                   GElf_Sym *dst, Elf32_Word *dstshndx)
      45             : {
      46  1992780287 :   Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata;
      47  1992780287 :   Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata;
      48  1992780287 :   GElf_Sym *result = NULL;
      49  1992780287 :   Elf32_Word shndx = 0;
      50             : 
      51  1992780287 :   if (symdata == NULL)
      52             :     return NULL;
      53             : 
      54  1992780287 :   if (unlikely (symdata->d_type != ELF_T_SYM)
      55  1992780287 :       || (likely (shndxdata_scn != NULL)
      56       88002 :           && unlikely (shndxdata->d_type != ELF_T_WORD)))
      57             :     {
      58           0 :       __libelf_seterrno (ELF_E_INVALID_HANDLE);
      59           0 :       return NULL;
      60             :     }
      61             : 
      62  1992780287 :   rwlock_rdlock (symdata_scn->s->elf->lock);
      63             : 
      64             :   /* The user is not required to pass a data descriptor for an extended
      65             :      section index table.  */
      66  1992780287 :   if (likely (shndxdata_scn != NULL))
      67             :     {
      68       88002 :       if (INVALID_NDX (ndx, Elf32_Word, &shndxdata_scn->d))
      69             :         {
      70           0 :           __libelf_seterrno (ELF_E_INVALID_INDEX);
      71           0 :           goto out;
      72             :         }
      73             : 
      74       88002 :       shndx = ((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx];
      75             :     }
      76             : 
      77             :   /* This is the one place where we have to take advantage of the fact
      78             :      that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
      79             :      The interface is broken so that it requires this hack.  */
      80  1992780287 :   if (symdata_scn->s->elf->class == ELFCLASS32)
      81             :     {
      82      285697 :       Elf32_Sym *src;
      83             : 
      84             :       /* Here it gets a bit more complicated.  The format of the symbol
      85             :          table entries has to be adopted.  The user better has provided
      86             :          a buffer where we can store the information.  While copying the
      87             :          data we are converting the format.  */
      88      285697 :       if (INVALID_NDX (ndx, Elf32_Sym, symdata))
      89             :         {
      90           0 :           __libelf_seterrno (ELF_E_INVALID_INDEX);
      91           0 :           goto out;
      92             :         }
      93             : 
      94      285697 :       src = &((Elf32_Sym *) symdata->d_buf)[ndx];
      95             : 
      96             :       /* This might look like a simple copy operation but it's
      97             :          not.  There are zero- and sign-extensions going on.  */
      98             : #define COPY(name) \
      99             :       dst->name = src->name
     100      285697 :       COPY (st_name);
     101             :       /* Please note that we can simply copy the `st_info' element since
     102             :          the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
     103             :          for the 64 bit variant.  */
     104      285697 :       COPY (st_info);
     105      285697 :       COPY (st_other);
     106      285697 :       COPY (st_shndx);
     107      285697 :       COPY (st_value);
     108      285697 :       COPY (st_size);
     109             :     }
     110             :   else
     111             :     {
     112             :       /* If this is a 64 bit object it's easy.  */
     113  1992494590 :       assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym));
     114             : 
     115             :       /* The data is already in the correct form.  Just make sure the
     116             :          index is OK.  */
     117  1992494590 :       if (INVALID_NDX (ndx, GElf_Sym, symdata))
     118             :         {
     119           0 :           __libelf_seterrno (ELF_E_INVALID_INDEX);
     120           0 :           goto out;
     121             :         }
     122             : 
     123  1992494590 :       *dst = ((GElf_Sym *) symdata->d_buf)[ndx];
     124             :     }
     125             : 
     126             :   /* Now we can store the section index.  */
     127  1992780287 :   if (dstshndx != NULL)
     128  1992780287 :     *dstshndx = shndx;
     129             : 
     130             :   result = dst;
     131             : 
     132  1992780287 :  out:
     133  1992780287 :   rwlock_unlock (symdata_scn->s->elf->lock);
     134             : 
     135  1992780287 :   return result;
     136             : }

Generated by: LCOV version 1.13