LCOV - code coverage report
Current view: top level - libelf - elf32_getphdr.c (source / functions) Hit Total Coverage
Test: elfutils- Lines: 70 92 76.1 %
Date: 2020-06-11 18:20:19 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Get ELF program header table.
       2             :    Copyright (C) 1998-2010, 2014, 2015 Red Hat, Inc.
       3             :    This file is part of elfutils.
       4             :    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
       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 <errno.h>
      35             : #include <stdbool.h>
      36             : #include <stdlib.h>
      37             : #include <unistd.h>
      38             : #include <assert.h>
      39             : 
      40             : #include <system.h>
      41             : #include "libelfP.h"
      42             : #include "common.h"
      43             : 
      44             : #ifndef LIBELFBITS
      45             : # define LIBELFBITS 32
      46             : #endif
      47             : 
      48             : ElfW2(LIBELFBITS,Phdr) *
      49        6895 : __elfw2(LIBELFBITS,getphdr_wrlock) (Elf *elf)
      50             : {
      51        6895 :   ElfW2(LIBELFBITS,Phdr) *result;
      52             : 
      53             :   /* If the program header entry has already been filled in the code
      54             :      below must already have been run.  So the class is set, too.  No
      55             :      need to waste any more time here.  */
      56        6895 :   result = elf->state.ELFW(elf,LIBELFBITS).phdr;
      57        6895 :   if (likely (result != NULL))
      58             :     return result;
      59             : 
      60        6895 :   if (elf->class == 0)
      61           0 :     elf->class = ELFW(ELFCLASS,LIBELFBITS);
      62        6895 :   else if (elf->class != ELFW(ELFCLASS,LIBELFBITS))
      63             :     {
      64           0 :       __libelf_seterrno (ELF_E_INVALID_CLASS);
      65           0 :       result = NULL;
      66           0 :       goto out;
      67             :     }
      68             : 
      69        6895 :   if (likely (result == NULL))
      70             :     {
      71             :       /* Read the section header table.  */
      72        6895 :       ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
      73             : 
      74             :       /* If no program header exists return NULL.  */
      75        6895 :       size_t phnum;
      76        6895 :       if (__elf_getphdrnum_rdlock (elf, &phnum) != 0)
      77         265 :         goto out;
      78        6895 :       if (phnum == 0 || ehdr->e_phoff == 0)
      79             :         {
      80         265 :           __libelf_seterrno (ELF_E_NO_PHDR);
      81         265 :           goto out;
      82             :         }
      83             : 
      84             :       /* Check this doesn't overflow.  */
      85        6630 :       size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
      86             : 
      87        6630 :       if (phnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))
      88        6630 :           || ehdr->e_phoff > elf->maximum_size
      89        6630 :           || elf->maximum_size - ehdr->e_phoff < size)
      90             :         {
      91           0 :           __libelf_seterrno (ELF_E_INVALID_DATA);
      92           0 :           goto out;
      93             :         }
      94             : 
      95        6630 :       if (elf->map_address != NULL)
      96             :         {
      97             :           /* First see whether the information in the ELF header is
      98             :              valid and it does not ask for too much.  */
      99        5948 :           if (unlikely (ehdr->e_phoff >= elf->maximum_size)
     100             :               || unlikely (elf->maximum_size - ehdr->e_phoff < size))
     101             :             {
     102             :               /* Something is wrong.  */
     103           0 :               __libelf_seterrno (ELF_E_INVALID_PHDR);
     104           0 :               goto out;
     105             :             }
     106             : 
     107             :           /* All the data is already mapped.  Use it.  */
     108       11896 :           void *file_phdr = ((char *) elf->map_address
     109        5948 :                              + elf->start_offset + ehdr->e_phoff);
     110        5948 :           if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
     111             :               && (ALLOW_UNALIGNED
     112             :                   || ((uintptr_t) file_phdr
     113             :                       & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
     114             :             /* Simply use the mapped data.  */
     115        5736 :             elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr;
     116             :           else
     117             :             {
     118         212 :               ElfW2(LIBELFBITS,Phdr) *notcvt;
     119         212 :               ElfW2(LIBELFBITS,Phdr) *phdr;
     120             : 
     121             :               /* Allocate memory for the program headers.  We know the number
     122             :                  of entries from the ELF header.  */
     123         424 :               phdr = elf->state.ELFW(elf,LIBELFBITS).phdr =
     124         212 :                 (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
     125         212 :               if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
     126             :                 {
     127           0 :                   __libelf_seterrno (ELF_E_NOMEM);
     128           0 :                   goto out;
     129             :                 }
     130         212 :               elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
     131             :                 ELF_F_MALLOCED | ELF_F_DIRTY;
     132             : 
     133             :               /* Now copy the data and at the same time convert the
     134             :                  byte order.  */
     135             : 
     136         212 :               if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
     137             :                 {
     138           0 :                   assert (! ALLOW_UNALIGNED);
     139             :                   memcpy (phdr, file_phdr, size);
     140             :                 }
     141             :               else
     142             :                 {
     143             :                   bool copy = ! (ALLOW_UNALIGNED
     144             :                                  || ((uintptr_t) file_phdr
     145             :                                      & (__alignof__ (ElfW2(LIBELFBITS,Phdr))
     146             :                                         - 1)) == 0);
     147             :                   if (! copy)
     148             :                     notcvt = file_phdr;
     149             :                   else
     150             :                     {
     151             :                       notcvt = (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
     152             :                       if (unlikely (notcvt == NULL))
     153             :                         {
     154             :                           __libelf_seterrno (ELF_E_NOMEM);
     155             :                           goto out;
     156             :                         }
     157             :                       memcpy (notcvt, file_phdr, size);
     158             :                     }
     159             : 
     160        1467 :                   for (size_t cnt = 0; cnt < phnum; ++cnt)
     161             :                     {
     162        1255 :                       CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type);
     163        1255 :                       CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset);
     164        1255 :                       CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr);
     165        1255 :                       CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr);
     166        1255 :                       CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz);
     167        1255 :                       CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz);
     168        1255 :                       CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags);
     169        2510 :                       CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align);
     170             :                     }
     171             : 
     172             :                   if (copy)
     173             :                     free (notcvt);
     174             :                 }
     175             :             }
     176             :         }
     177         682 :       else if (likely (elf->fildes != -1))
     178             :         {
     179             :           /* Allocate memory for the program headers.  We know the number
     180             :              of entries from the ELF header.  */
     181        1364 :           elf->state.ELFW(elf,LIBELFBITS).phdr =
     182         682 :             (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
     183         682 :           if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
     184             :             {
     185           0 :               __libelf_seterrno (ELF_E_NOMEM);
     186           0 :               goto out;
     187             :             }
     188         682 :           elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED;
     189             : 
     190             :           /* Read the header.  */
     191        2046 :           ssize_t n = pread_retry (elf->fildes,
     192             :                                    elf->state.ELFW(elf,LIBELFBITS).phdr, size,
     193         682 :                                    elf->start_offset + ehdr->e_phoff);
     194         682 :           if (unlikely ((size_t) n != size))
     195             :             {
     196             :               /* Severe problems.  We cannot read the data.  */
     197           0 :               __libelf_seterrno (ELF_E_READ_ERROR);
     198           0 :               free (elf->state.ELFW(elf,LIBELFBITS).phdr);
     199           0 :               elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
     200           0 :               goto out;
     201             :             }
     202             : 
     203             :           /* If the byte order of the file is not the same as the one
     204             :              of the host convert the data now.  */
     205         682 :           if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
     206             :             {
     207         186 :               ElfW2(LIBELFBITS,Phdr) *phdr
     208             :                 = elf->state.ELFW(elf,LIBELFBITS).phdr;
     209             : 
     210        1338 :               for (size_t cnt = 0; cnt < phnum; ++cnt)
     211             :                 {
     212        1152 :                   CONVERT (phdr[cnt].p_type);
     213        1152 :                   CONVERT (phdr[cnt].p_offset);
     214        1152 :                   CONVERT (phdr[cnt].p_vaddr);
     215        1152 :                   CONVERT (phdr[cnt].p_paddr);
     216        1152 :                   CONVERT (phdr[cnt].p_filesz);
     217        1152 :                   CONVERT (phdr[cnt].p_memsz);
     218        1152 :                   CONVERT (phdr[cnt].p_flags);
     219        2304 :                   CONVERT (phdr[cnt].p_align);
     220             :                 }
     221             :             }
     222             :         }
     223             :       else
     224             :         {
     225             :           /* The file descriptor was already enabled and not all data was
     226             :              read.  */
     227           0 :           __libelf_seterrno (ELF_E_FD_DISABLED);
     228           0 :           goto out;
     229             :         }
     230             : 
     231        6630 :       result = elf->state.ELFW(elf,LIBELFBITS).phdr;
     232             :     }
     233             : 
     234           0 :  out:
     235             :   return result;
     236             : }
     237             : 
     238             : ElfW2(LIBELFBITS,Phdr) *
     239        6601 : elfw2(LIBELFBITS,getphdr) (Elf *elf)
     240             : {
     241        6601 :   ElfW2(LIBELFBITS,Phdr) *result;
     242             : 
     243        6601 :   if (elf == NULL)
     244             :     return NULL;
     245             : 
     246        6601 :   if (unlikely (elf->kind != ELF_K_ELF))
     247             :     {
     248           0 :       __libelf_seterrno (ELF_E_INVALID_HANDLE);
     249           0 :       return NULL;
     250             :     }
     251             : 
     252             :   /* If the program header entry has already been filled in the code
     253             :    * in getphdr_wrlock must already have been run.  So the class is
     254             :    * set, too.  No need to waste any more time here.  */
     255        6601 :   result = elf->state.ELFW(elf,LIBELFBITS).phdr;
     256        6601 :   if (likely (result != NULL))
     257             :     return result;
     258             : 
     259        6601 :   rwlock_wrlock (elf->lock);
     260        6601 :   result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
     261        6601 :   rwlock_unlock (elf->lock);
     262             : 
     263        6601 :   return result;
     264             : }
     265             : INTDEF(elfw2(LIBELFBITS,getphdr))

Generated by: LCOV version 1.13