LCOV - code coverage report
Current view: top level - libelf - elf_getshdrstrndx.c (source / functions) Hit Total Coverage
Test: elfutils-0.176 Lines: 42 68 61.8 %
Date: 2019-02-15 17:57:54 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Return section index of section header string table.
       2             :    Copyright (C) 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
       3             :    This file is part of elfutils.
       4             :    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
       5             : 
       6             :    This file is free software; you can redistribute it and/or modify
       7             :    it under the terms of either
       8             : 
       9             :      * the GNU Lesser General Public License as published by the Free
      10             :        Software Foundation; either version 3 of the License, or (at
      11             :        your option) any later version
      12             : 
      13             :    or
      14             : 
      15             :      * the GNU General Public License as published by the Free
      16             :        Software Foundation; either version 2 of the License, or (at
      17             :        your option) any later version
      18             : 
      19             :    or both in parallel, as here.
      20             : 
      21             :    elfutils is distributed in the hope that it will be useful, but
      22             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      24             :    General Public License for more details.
      25             : 
      26             :    You should have received copies of the GNU General Public License and
      27             :    the GNU Lesser General Public License along with this program.  If
      28             :    not, see <http://www.gnu.org/licenses/>.  */
      29             : 
      30             : #ifdef HAVE_CONFIG_H
      31             : # include <config.h>
      32             : #endif
      33             : 
      34             : #include <assert.h>
      35             : #include <errno.h>
      36             : #include <gelf.h>
      37             : #include <stddef.h>
      38             : #include <unistd.h>
      39             : 
      40             : #include <system.h>
      41             : #include "libelfP.h"
      42             : #include "common.h"
      43             : 
      44             : 
      45             : int
      46      651931 : elf_getshdrstrndx (Elf *elf, size_t *dst)
      47             : {
      48      651931 :   int result = 0;
      49             : 
      50      651931 :   if (elf == NULL)
      51             :     return -1;
      52             : 
      53      651931 :   if (unlikely (elf->kind != ELF_K_ELF))
      54             :     {
      55           0 :       __libelf_seterrno (ELF_E_INVALID_HANDLE);
      56           0 :       return -1;
      57             :     }
      58             : 
      59             :   rwlock_rdlock (elf->lock);
      60             : 
      61             :   /* We rely here on the fact that the `elf' element is a common prefix
      62             :      of `elf32' and `elf64'.  */
      63             :   assert (offsetof (struct Elf, state.elf.ehdr)
      64             :           == offsetof (struct Elf, state.elf32.ehdr));
      65             :   assert (sizeof (elf->state.elf.ehdr)
      66             :           == sizeof (elf->state.elf32.ehdr));
      67             :   assert (offsetof (struct Elf, state.elf.ehdr)
      68             :           == offsetof (struct Elf, state.elf64.ehdr));
      69             :   assert (sizeof (elf->state.elf.ehdr)
      70             :           == sizeof (elf->state.elf64.ehdr));
      71             : 
      72      651931 :   if (unlikely (elf->state.elf.ehdr == NULL))
      73             :     {
      74           0 :       __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
      75           0 :       result = -1;
      76             :     }
      77             :   else
      78             :     {
      79             :       Elf32_Word num;
      80             : 
      81     1303862 :       num = (elf->class == ELFCLASS32
      82       10950 :              ? elf->state.elf32.ehdr->e_shstrndx
      83      662881 :              : elf->state.elf64.ehdr->e_shstrndx);
      84             : 
      85             :       /* Determine whether the index is too big to fit in the ELF
      86             :          header.  */
      87      651931 :       if (unlikely (num == SHN_XINDEX))
      88             :         {
      89             :           /* Yes.  Search the zeroth section header.  */
      90          98 :           if (elf->class == ELFCLASS32)
      91             :             {
      92             :               size_t offset;
      93          53 :               if (unlikely (elf->state.elf32.scns.cnt == 0))
      94             :                 {
      95             :                   /* Cannot use SHN_XINDEX without section headers.  */
      96           0 :                   __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
      97           0 :                   result = -1;
      98           0 :                   goto out;
      99             :                 }
     100             : 
     101          53 :               if (elf->state.elf32.scns.data[0].shdr.e32 != NULL)
     102             :                 {
     103          17 :                   num = elf->state.elf32.scns.data[0].shdr.e32->sh_link;
     104          17 :                   goto success;
     105             :                 }
     106             : 
     107          36 :               offset = elf->state.elf32.ehdr->e_shoff;
     108             : 
     109          36 :               if (elf->map_address != NULL
     110          24 :                   && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
     111          24 :                   && (ALLOW_UNALIGNED
     112             :                       || (((size_t) ((char *) elf->map_address
     113             :                            + elf->start_offset + offset))
     114             :                           & (__alignof__ (Elf32_Shdr) - 1)) == 0))
     115             :                 {
     116             :                   /* First see whether the information in the ELF header is
     117             :                      valid and it does not ask for too much.  */
     118          12 :                   if (unlikely (elf->maximum_size - offset
     119             :                                 < sizeof (Elf32_Shdr)))
     120             :                     {
     121             :                       /* Something is wrong.  */
     122           0 :                       __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
     123           0 :                       result = -1;
     124           0 :                       goto out;
     125             :                     }
     126             : 
     127             :                   /* We can directly access the memory.  */
     128          24 :                   num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset
     129          12 :                                          + offset))->sh_link;
     130             :                 }
     131             :               else
     132             :                 {
     133             :                   /* We avoid reading in all the section headers.  Just read
     134             :                      the first one.  */
     135             :                   Elf32_Shdr shdr_mem;
     136             :                   ssize_t r;
     137             : 
     138          24 :                   if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem,
     139             :                                                   sizeof (Elf32_Shdr), offset))
     140             :                                 != sizeof (Elf32_Shdr)))
     141             :                     {
     142             :                       /* We must be able to read this ELF section header.  */
     143           0 :                       if (r < 0)
     144           0 :                         __libelf_seterrno (ELF_E_INVALID_FILE);
     145             :                       else
     146           0 :                         __libelf_seterrno (ELF_E_INVALID_ELF);
     147           0 :                       result = -1;
     148           0 :                       goto out;
     149             :                     }
     150             : 
     151          24 :                   if (elf->state.elf32.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
     152          32 :                     CONVERT (shdr_mem.sh_link);
     153          24 :                   num = shdr_mem.sh_link;
     154             :                 }
     155             :             }
     156             :           else
     157             :             {
     158          45 :               if (unlikely (elf->state.elf64.scns.cnt == 0))
     159             :                 {
     160             :                   /* Cannot use SHN_XINDEX without section headers.  */
     161           0 :                   __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
     162           0 :                   result = -1;
     163           0 :                   goto out;
     164             :                 }
     165             : 
     166          45 :               if (elf->state.elf64.scns.data[0].shdr.e64 != NULL)
     167             :                 {
     168          14 :                   num = elf->state.elf64.scns.data[0].shdr.e64->sh_link;
     169          14 :                   goto success;
     170             :                 }
     171             : 
     172          31 :               size_t offset = elf->state.elf64.ehdr->e_shoff;
     173             : 
     174          31 :               if (elf->map_address != NULL
     175          23 :                   && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
     176          23 :                   && (ALLOW_UNALIGNED
     177             :                       || (((size_t) ((char *) elf->map_address
     178             :                            + elf->start_offset + offset))
     179             :                           & (__alignof__ (Elf64_Shdr) - 1)) == 0))
     180             :                 {
     181             :                   /* First see whether the information in the ELF header is
     182             :                      valid and it does not ask for too much.  */
     183          11 :                   if (unlikely (elf->maximum_size - offset
     184             :                                 < sizeof (Elf64_Shdr)))
     185             :                     {
     186             :                       /* Something is wrong.  */
     187           0 :                       __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
     188           0 :                       result = -1;
     189           0 :                       goto out;
     190             :                     }
     191             : 
     192             :                   /* We can directly access the memory.  */
     193          22 :                   num = ((Elf64_Shdr *) (elf->map_address + elf->start_offset
     194          11 :                                          + offset))->sh_link;
     195             :                 }
     196             :               else
     197             :                 {
     198             :                   /* We avoid reading in all the section headers.  Just read
     199             :                      the first one.  */
     200             :                   Elf64_Shdr shdr_mem;
     201             :                   ssize_t r;
     202             : 
     203          20 :                   if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem,
     204             :                                                   sizeof (Elf64_Shdr), offset))
     205             :                                 != sizeof (Elf64_Shdr)))
     206             :                     {
     207             :                       /* We must be able to read this ELF section header.  */
     208           0 :                       if (r < 0)
     209           0 :                         __libelf_seterrno (ELF_E_INVALID_FILE);
     210             :                       else
     211           0 :                         __libelf_seterrno (ELF_E_INVALID_ELF);
     212           0 :                       result = -1;
     213           0 :                       goto out;
     214             :                     }
     215             : 
     216          20 :                   if (elf->state.elf64.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
     217          32 :                     CONVERT (shdr_mem.sh_link);
     218          20 :                   num = shdr_mem.sh_link;
     219             :                 }
     220             :             }
     221             :         }
     222             : 
     223             :       /* Store the result.  */
     224     1303764 :     success:
     225      651931 :       *dst = num;
     226             :     }
     227             : 
     228             :  out:
     229             :   rwlock_unlock (elf->lock);
     230             : 
     231             :   return result;
     232             : }
     233             : INTDEF(elf_getshdrstrndx)
     234             : /* Alias for the deprecated name.  */
     235             : strong_alias (elf_getshdrstrndx, elf_getshstrndx)

Generated by: LCOV version 1.13