LCOV - code coverage report
Current view: top level - elfutils/libelf - elf_getdata.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 104 126 82.5 %
Date: 2012-10-31 Functions: 5 5 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 72 100 72.0 %

           Branch data     Line data    Source code
       1                 :            : /* Return the next data element from the section after possibly converting it.
       2                 :            :    Copyright (C) 1998-2005, 2006, 2007 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 <stddef.h>
      36                 :            : #include <string.h>
      37                 :            : #include <unistd.h>
      38                 :            : 
      39                 :            : #include "libelfP.h"
      40                 :            : #include <system.h>
      41                 :            : #include "common.h"
      42                 :            : #include "elf-knowledge.h"
      43                 :            : 
      44                 :            : 
      45                 :            : #define TYPEIDX(Sh_Type) \
      46                 :            :   (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM                                     \
      47                 :            :    ? Sh_Type                                                                  \
      48                 :            :    : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW                          \
      49                 :            :       ? SHT_NUM + Sh_Type - SHT_GNU_HASH                                      \
      50                 :            :       : 0))
      51                 :            : 
      52                 :            : /* Associate section types with libelf types.  */
      53                 :            : static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
      54                 :            :   {
      55                 :            :     [EV_CURRENT - 1] =
      56                 :            :     {
      57                 :            :       [SHT_SYMTAB] = ELF_T_SYM,
      58                 :            :       [SHT_RELA] = ELF_T_RELA,
      59                 :            :       [SHT_HASH] = ELF_T_WORD,
      60                 :            :       [SHT_DYNAMIC] = ELF_T_DYN,
      61                 :            :       [SHT_REL] = ELF_T_REL,
      62                 :            :       [SHT_DYNSYM] = ELF_T_SYM,
      63                 :            :       [SHT_INIT_ARRAY] = ELF_T_ADDR,
      64                 :            :       [SHT_FINI_ARRAY] = ELF_T_ADDR,
      65                 :            :       [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
      66                 :            :       [SHT_GROUP] = ELF_T_WORD,
      67                 :            :       [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
      68                 :            :       [SHT_NOTE] = ELF_T_NHDR,
      69                 :            :       [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
      70                 :            :       [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
      71                 :            :       [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
      72                 :            :       [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO,
      73                 :            :       [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
      74                 :            :       [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
      75                 :            :       [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
      76                 :            :     }
      77                 :            :   };
      78                 :            : 
      79                 :            : #if !ALLOW_UNALIGNED
      80                 :            : /* Associate libelf types with their internal alignment requirements.  */
      81                 :            : const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
      82                 :            :   {
      83                 :            : # define TYPE_ALIGNS(Bits)                                                    \
      84                 :            :     {                                                                         \
      85                 :            :       [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)),                          \
      86                 :            :       [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)),                          \
      87                 :            :       [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)),                          \
      88                 :            :       [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)),                            \
      89                 :            :       [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)),                    \
      90                 :            :       [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)),                            \
      91                 :            :       [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)),                          \
      92                 :            :       [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)),                            \
      93                 :            :       [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)),                        \
      94                 :            :       [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)),                      \
      95                 :            :       [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)),                      \
      96                 :            :       [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)),                      \
      97                 :            :       [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),                          \
      98                 :            :       [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),                            \
      99                 :            :       [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),                          \
     100                 :            :     }
     101                 :            :     [EV_CURRENT - 1] =
     102                 :            :     {
     103                 :            :       [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
     104                 :            :       [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
     105                 :            :     }
     106                 :            : # undef TYPE_ALIGNS
     107                 :            :   };
     108                 :            : #endif
     109                 :            : 
     110                 :            : 
     111                 :            : /* Convert the data in the current section.  */
     112                 :            : static void
     113                 :      63268 : convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
     114                 :            :               int data, size_t size, Elf_Type type)
     115                 :            : {
     116                 :      63268 :   const size_t align = __libelf_type_align (eclass, type);
     117                 :            : 
     118         [ +  + ]:      63268 :   if (data == MY_ELFDATA)
     119                 :            :     {
     120                 :            :       if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
     121                 :            :         /* No need to copy, we can use the raw data.  */
     122                 :      62793 :         scn->data_base = scn->rawdata_base;
     123                 :            :       else
     124                 :            :         {
     125                 :            :           scn->data_base = (char *) malloc (size);
     126                 :            :           if (scn->data_base == NULL)
     127                 :            :             {
     128                 :            :               __libelf_seterrno (ELF_E_NOMEM);
     129                 :            :               return;
     130                 :            :             }
     131                 :            : 
     132                 :            :           /* The copy will be appropriately aligned for direct access.  */
     133                 :            :           memcpy (scn->data_base, scn->rawdata_base, size);
     134                 :            :         }
     135                 :            :     }
     136                 :            :   else
     137                 :            :     {
     138                 :            :       xfct_t fp;
     139                 :            : 
     140                 :        475 :       scn->data_base = (char *) malloc (size);
     141         [ -  + ]:        475 :       if (scn->data_base == NULL)
     142                 :            :         {
     143                 :          0 :           __libelf_seterrno (ELF_E_NOMEM);
     144                 :            :           return;
     145                 :            :         }
     146                 :            : 
     147                 :            :       /* Get the conversion function.  */
     148                 :            : #if EV_NUM != 2
     149                 :            :       fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
     150                 :            : #else
     151                 :        475 :       fp = __elf_xfctstom[0][0][eclass - 1][type];
     152                 :            : #endif
     153                 :            : 
     154                 :        475 :       fp (scn->data_base, scn->rawdata_base, size, 0);
     155                 :            :     }
     156                 :            : 
     157                 :      63268 :   scn->data_list.data.d.d_buf = scn->data_base;
     158                 :      63268 :   scn->data_list.data.d.d_size = size;
     159                 :      63268 :   scn->data_list.data.d.d_type = type;
     160                 :      63268 :   scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
     161                 :      63268 :   scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
     162                 :      63268 :   scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
     163                 :            : 
     164                 :      63268 :   scn->data_list.data.s = scn;
     165                 :            : }
     166                 :            : 
     167                 :            : 
     168                 :            : /* Store the information for the raw data in the `rawdata' element.  */
     169                 :            : int
     170                 :            : internal_function
     171                 :      69558 : __libelf_set_rawdata_wrlock (Elf_Scn *scn)
     172                 :            : {
     173                 :            :   size_t offset;
     174                 :            :   size_t size;
     175                 :            :   size_t align;
     176                 :            :   int type;
     177                 :      69558 :   Elf *elf = scn->elf;
     178                 :            : 
     179         [ +  + ]:      69558 :   if (elf->class == ELFCLASS32)
     180                 :            :     {
     181                 :      23263 :       Elf32_Shdr *shdr
     182         [ +  + ]:      23263 :         = scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
     183                 :            : 
     184         [ +  - ]:      23263 :       if (shdr == NULL)
     185                 :            :         /* Something went terribly wrong.  */
     186                 :            :         return 1;
     187                 :            : 
     188                 :      23263 :       offset = shdr->sh_offset;
     189                 :      23263 :       size = shdr->sh_size;
     190                 :      23263 :       type = shdr->sh_type;
     191                 :      23263 :       align = shdr->sh_addralign;
     192                 :            :     }
     193                 :            :   else
     194                 :            :     {
     195                 :      46295 :       Elf64_Shdr *shdr
     196         [ +  + ]:      46295 :         = scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
     197                 :            : 
     198         [ +  - ]:      46295 :       if (shdr == NULL)
     199                 :            :         /* Something went terribly wrong.  */
     200                 :            :         return 1;
     201                 :            : 
     202                 :      46295 :       offset = shdr->sh_offset;
     203                 :      46295 :       size = shdr->sh_size;
     204                 :      46295 :       type = shdr->sh_type;
     205                 :      46295 :       align = shdr->sh_addralign;
     206                 :            :     }
     207                 :            : 
     208                 :            :   /* If the section has no data (for whatever reason), leave the `d_buf'
     209                 :            :      pointer NULL.  */
     210         [ +  + ]:      69558 :   if (size != 0 && type != SHT_NOBITS)
     211                 :            :     {
     212                 :            :       /* First a test whether the section is valid at all.  */
     213                 :            :       size_t entsize;
     214                 :            : 
     215         [ +  + ]:      69290 :       if (type == SHT_HASH)
     216                 :            :         {
     217                 :            :           GElf_Ehdr ehdr_mem;
     218                 :         35 :           GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
     219 [ +  + ][ -  + ]:         35 :           entsize = SH_ENTSIZE_HASH (ehdr);
                 [ #  # ]
     220                 :            :         }
     221                 :            :       else
     222                 :            :         {
     223 [ +  + ][ +  + ]:      69255 :           Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
     224         [ +  + ]:      69255 :           if (t == ELF_T_VDEF || t == ELF_T_NHDR
     225 [ +  + ][ +  + ]:      69003 :               || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
     226                 :            :             entsize = 1;
     227                 :            :           else
     228                 :      68948 :             entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t];
     229                 :            :         }
     230                 :            : 
     231                 :            :       /* We assume it is an array of bytes if it is none of the structured
     232                 :            :          sections we know of.  */
     233         [ -  + ]:      69290 :       if (entsize == 0)
     234                 :          0 :         entsize = 1;
     235                 :            : 
     236         [ -  + ]:      69290 :       if (unlikely (size % entsize != 0))
     237                 :            :         {
     238                 :          0 :           __libelf_seterrno (ELF_E_INVALID_DATA);
     239                 :          0 :           return 1;
     240                 :            :         }
     241                 :            : 
     242                 :            :       /* We can use the mapped or loaded data if available.  */
     243         [ +  + ]:      69290 :       if (elf->map_address != NULL)
     244                 :            :         {
     245                 :            :           /* First see whether the information in the section header is
     246                 :            :              valid and it does not ask for too much.  */
     247         [ -  + ]:      68330 :           if (unlikely (offset + size > elf->maximum_size))
     248                 :            :             {
     249                 :            :               /* Something is wrong.  */
     250                 :          0 :               __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
     251                 :          0 :               return 1;
     252                 :            :             }
     253                 :            : 
     254                 :      68330 :           scn->rawdata_base = scn->rawdata.d.d_buf
     255                 :      68330 :             = (char *) elf->map_address + elf->start_offset + offset;
     256                 :            :         }
     257         [ +  - ]:        960 :       else if (likely (elf->fildes != -1))
     258                 :            :         {
     259                 :            :           /* We have to read the data from the file.  Allocate the needed
     260                 :            :              memory.  */
     261                 :        960 :           scn->rawdata_base = scn->rawdata.d.d_buf
     262                 :        960 :             = (char *) malloc (size);
     263         [ -  + ]:        960 :           if (scn->rawdata.d.d_buf == NULL)
     264                 :            :             {
     265                 :          0 :               __libelf_seterrno (ELF_E_NOMEM);
     266                 :          0 :               return 1;
     267                 :            :             }
     268                 :            : 
     269                 :        960 :           ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
     270                 :        960 :                                    elf->start_offset + offset);
     271         [ -  + ]:        960 :           if (unlikely ((size_t) n != size))
     272                 :            :             {
     273                 :            :               /* Cannot read the data.  */
     274                 :          0 :               free (scn->rawdata.d.d_buf);
     275                 :          0 :               scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
     276                 :          0 :               __libelf_seterrno (ELF_E_READ_ERROR);
     277                 :          0 :               return 1;
     278                 :            :             }
     279                 :            :         }
     280                 :            :       else
     281                 :            :         {
     282                 :            :           /* The file descriptor is already closed, we cannot get the data
     283                 :            :              anymore.  */
     284                 :          0 :           __libelf_seterrno (ELF_E_FD_DISABLED);
     285                 :          0 :           return 1;
     286                 :            :         }
     287                 :            :     }
     288                 :            : 
     289                 :      69558 :   scn->rawdata.d.d_size = size;
     290                 :            :   /* Some broken ELF ABI for 64-bit machines use the wrong hash table
     291                 :            :      entry size.  See elf-knowledge.h for more information.  */
     292 [ +  + ][ +  + ]:      69558 :   if (type == SHT_HASH && elf->class == ELFCLASS64)
     293                 :         20 :     {
     294                 :            :       GElf_Ehdr ehdr_mem;
     295                 :         20 :       GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
     296                 :            :       scn->rawdata.d.d_type
     297 [ +  + ][ -  + ]:         20 :         = (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
                 [ #  # ]
     298                 :            :     }
     299                 :            :   else
     300 [ +  + ][ +  + ]:      69538 :     scn->rawdata.d.d_type = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
     301                 :      69558 :   scn->rawdata.d.d_off = 0;
     302                 :      69558 :   scn->rawdata.d.d_align = align;
     303                 :            :   if (elf->class == ELFCLASS32
     304                 :            :       || (offsetof (struct Elf, state.elf32.ehdr)
     305                 :            :           == offsetof (struct Elf, state.elf64.ehdr)))
     306                 :      69558 :     scn->rawdata.d.d_version =
     307                 :      69558 :       elf->state.elf32.ehdr->e_ident[EI_VERSION];
     308                 :            :   else
     309                 :            :     scn->rawdata.d.d_version =
     310                 :            :       elf->state.elf64.ehdr->e_ident[EI_VERSION];
     311                 :            : 
     312                 :      69558 :   scn->rawdata.s = scn;
     313                 :            : 
     314                 :      69558 :   scn->data_read = 1;
     315                 :            : 
     316                 :            :   /* We actually read data from the file.  At least we tried.  */
     317                 :      69558 :   scn->flags |= ELF_F_FILEDATA;
     318                 :            : 
     319                 :      69558 :   return 0;
     320                 :            : }
     321                 :            : 
     322                 :            : int
     323                 :            : internal_function
     324                 :        294 : __libelf_set_rawdata (Elf_Scn *scn)
     325                 :            : {
     326                 :            :   int result;
     327                 :            : 
     328         [ +  - ]:        294 :   if (scn == NULL)
     329                 :            :     return 1;
     330                 :            : 
     331                 :            :   rwlock_wrlock (scn->elf->lock);
     332                 :        294 :   result = __libelf_set_rawdata_wrlock (scn);
     333                 :            :   rwlock_unlock (scn->elf->lock);
     334                 :            : 
     335                 :        294 :   return result;
     336                 :            : }
     337                 :            : 
     338                 :            : Elf_Data *
     339                 :            : internal_function
     340                 :     108748 : __elf_getdata_rdlock (scn, data)
     341                 :            :      Elf_Scn *scn;
     342                 :            :      Elf_Data *data;
     343                 :            : {
     344                 :     108748 :   Elf_Data *result = NULL;
     345                 :            :   Elf *elf;
     346                 :     108748 :   int locked = 0;
     347                 :            : 
     348         [ +  - ]:     108748 :   if (scn == NULL)
     349                 :            :     return NULL;
     350                 :            : 
     351         [ -  + ]:     108748 :   if (unlikely (scn->elf->kind != ELF_K_ELF))
     352                 :            :     {
     353                 :          0 :       __libelf_seterrno (ELF_E_INVALID_HANDLE);
     354                 :          0 :       return NULL;
     355                 :            :     }
     356                 :            : 
     357                 :            :   /* We will need this multiple times later on.  */
     358                 :     108748 :   elf = scn->elf;
     359                 :            : 
     360                 :            :   /* If `data' is not NULL this means we are not addressing the initial
     361                 :            :      data in the file.  But this also means this data is already read
     362                 :            :      (since otherwise it is not possible to have a valid `data' pointer)
     363                 :            :      and all the data structures are initialized as well.  In this case
     364                 :            :      we can simply walk the list of data records.  */
     365         [ +  + ]:     108748 :   if (data != NULL)
     366                 :            :     {
     367                 :            :       Elf_Data_List *runp;
     368                 :            : 
     369                 :            :       /* It is not possible that if DATA is not NULL the first entry is
     370                 :            :          returned.  But this also means that there must be a first data
     371                 :            :          entry.  */
     372         [ +  - ]:         38 :       if (scn->data_list_rear == NULL
     373                 :            :           /* The section the reference data is for must match the section
     374                 :            :              parameter.  */
     375         [ -  + ]:         38 :           || unlikely (((Elf_Data_Scn *) data)->s != scn))
     376                 :            :         {
     377                 :          0 :           __libelf_seterrno (ELF_E_DATA_MISMATCH);
     378                 :          0 :           goto out;
     379                 :            :         }
     380                 :            : 
     381                 :            :       /* We start searching with the first entry.  */
     382                 :         38 :       runp = &scn->data_list;
     383                 :            : 
     384                 :            :       while (1)
     385                 :            :         {
     386                 :            :           /* If `data' does not match any known record punt.  */
     387         [ -  + ]:         38 :           if (runp == NULL)
     388                 :            :             {
     389                 :          0 :               __libelf_seterrno (ELF_E_DATA_MISMATCH);
     390                 :          0 :               goto out;
     391                 :            :             }
     392                 :            : 
     393         [ -  + ]:         38 :           if (&runp->data.d == data)
     394                 :            :             /* Found the entry.  */
     395                 :            :             break;
     396                 :            : 
     397                 :          0 :           runp = runp->next;
     398                 :          0 :         }
     399                 :            : 
     400                 :            :       /* Return the data for the next data record.  */
     401         [ -  + ]:         38 :       result = runp->next ? &runp->next->data.d : NULL;
     402                 :         38 :       goto out;
     403                 :            :     }
     404                 :            : 
     405                 :            :   /* If the data for this section was not yet initialized do it now.  */
     406         [ +  + ]:     108710 :   if (scn->data_read == 0)
     407                 :            :     {
     408                 :            :       /* We cannot acquire a write lock while we are holding a read
     409                 :            :          lock.  Therefore give up the read lock and then get the write
     410                 :            :          lock.  But this means that the data could meanwhile be
     411                 :            :          modified, therefore start the tests again.  */
     412                 :            :       rwlock_unlock (elf->lock);
     413                 :            :       rwlock_wrlock (elf->lock);
     414                 :      63345 :       locked = 1;
     415                 :            : 
     416                 :            :       /* Read the data from the file.  There is always a file (or
     417                 :            :          memory region) associated with this descriptor since
     418                 :            :          otherwise the `data_read' flag would be set.  */
     419 [ +  - ][ +  - ]:      63345 :       if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
     420                 :            :         /* Something went wrong.  The error value is already set.  */
     421                 :            :         goto out;
     422                 :            :     }
     423                 :            : 
     424                 :            :   /* At this point we know the raw data is available.  But it might be
     425                 :            :      empty in case the section has size zero (for whatever reason).
     426                 :            :      Now create the converted data in case this is necessary.  */
     427         [ +  + ]:     108710 :   if (scn->data_list_rear == NULL)
     428                 :            :     {
     429 [ +  + ][ +  - ]:      63532 :       if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
     430                 :            :         {
     431         [ +  + ]:      63268 :           if (!locked)
     432                 :            :             {
     433                 :            :               rwlock_unlock (elf->lock);
     434                 :            :               rwlock_wrlock (elf->lock);
     435         [ +  - ]:        185 :               if (scn->data_list_rear != NULL)
     436                 :            :                 goto pass;
     437                 :            :             }
     438                 :            : 
     439                 :            :           /* Convert according to the version and the type.   */
     440                 :      63268 :           convert_data (scn, __libelf_version, elf->class,
     441                 :            :                         (elf->class == ELFCLASS32
     442                 :            :                          || (offsetof (struct Elf, state.elf32.ehdr)
     443                 :            :                              == offsetof (struct Elf, state.elf64.ehdr))
     444                 :      63268 :                          ? elf->state.elf32.ehdr->e_ident[EI_DATA]
     445                 :            :                          : elf->state.elf64.ehdr->e_ident[EI_DATA]),
     446                 :            :                         scn->rawdata.d.d_size, scn->rawdata.d.d_type);
     447                 :            :         }
     448                 :            :       else
     449                 :            :         {
     450                 :            :           /* This is an empty or NOBITS section.  There is no buffer but
     451                 :            :              the size information etc is important.  */
     452                 :        264 :           scn->data_list.data.d = scn->rawdata.d;
     453                 :        264 :           scn->data_list.data.s = scn;
     454                 :            :         }
     455                 :            : 
     456                 :      63532 :       scn->data_list_rear = &scn->data_list;
     457                 :            :     }
     458                 :            : 
     459                 :            :   /* If no data is present we cannot return any.  */
     460         [ +  - ]:     108710 :   if (scn->data_list_rear != NULL)
     461                 :            :   pass:
     462                 :            :     /* Return the first data element in the list.  */
     463                 :     108710 :     result = &scn->data_list.data.d;
     464                 :            : 
     465                 :            :  out:
     466                 :     108748 :   return result;
     467                 :            : }
     468                 :            : 
     469                 :            : Elf_Data *
     470                 :     109606 : elf_getdata (scn, data)
     471                 :            :      Elf_Scn *scn;
     472                 :            :      Elf_Data *data;
     473                 :            : {
     474                 :            :   Elf_Data *result;
     475                 :            : 
     476         [ +  + ]:     109606 :   if (scn == NULL)
     477                 :            :     return NULL;
     478                 :            : 
     479                 :            :   rwlock_rdlock (scn->elf->lock);
     480                 :     108742 :   result = __elf_getdata_rdlock (scn, data);
     481                 :            :   rwlock_unlock (scn->elf->lock);
     482                 :            : 
     483                 :     109606 :   return result;
     484                 :            : }
     485                 :            : INTDEF(elf_getdata)

Generated by: LCOV version 1.9