LCOV - code coverage report
Current view: top level - libelf - elf32_updatenull.c (source / functions) Coverage Total Hit
Test: elfutils-0.193 Lines: 82.3 % 181 149
Test Date: 2025-09-16 21:19:19 Functions: 100.0 % 4 4
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 82.2 % 152 125

             Branch data     Line data    Source code
       1                 :             : /* Update data structures for changes.
       2                 :             :    Copyright (C) 2000-2010, 2015, 2016 Red Hat, Inc.
       3                 :             :    This file is part of elfutils.
       4                 :             :    Written by Ulrich Drepper <drepper@redhat.com>, 2000.
       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 <libelf.h>
      36                 :             : #include <stdbool.h>
      37                 :             : #include <string.h>
      38                 :             : 
      39                 :             : #include "libelfP.h"
      40                 :             : #include "elf-knowledge.h"
      41                 :             : 
      42                 :             : #ifndef LIBELFBITS
      43                 :             : # define LIBELFBITS 32
      44                 :             : #endif
      45                 :             : 
      46                 :             : /* Some fields contain 32/64 sizes.  We cannot use Elf32/64_Word for those,
      47                 :             :    since those are both 32bits.  Elf32/64_Xword is always 64bits.  */
      48                 :             : #define Elf32_SizeWord Elf32_Word
      49                 :             : #define Elf64_SizeWord Elf64_Xword
      50                 :             : 
      51                 :             : 
      52                 :             : static int
      53                 :        1462 : ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
      54                 :             :                                size_t shnum, int *change_bop)
      55                 :             : {
      56                 :             :   /* Always write the magic bytes.  */
      57         [ +  + ]:        1462 :   if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
      58                 :             :     {
      59                 :         566 :       memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
      60                 :         566 :       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
      61                 :             :     }
      62                 :             : 
      63                 :             :   /* Always set the file class.  */
      64         [ +  + ]:        1462 :   update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS),
      65                 :             :                      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
      66                 :             : 
      67                 :             :   /* Set the data encoding if necessary.  */
      68         [ +  + ]:        1462 :   if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE))
      69                 :             :     {
      70                 :           8 :       ehdr->e_ident[EI_DATA] =
      71                 :             :         BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB;
      72                 :           8 :       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
      73                 :             :     }
      74         [ -  + ]:        1454 :   else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM))
      75                 :             :     {
      76                 :           0 :       __libelf_seterrno (ELF_E_DATA_ENCODING);
      77                 :           0 :       return 1;
      78                 :             :     }
      79                 :             :   else
      80                 :        1454 :     *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN
      81                 :             :                     && ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
      82                 :        1454 :                    || (BYTE_ORDER == BIG_ENDIAN
      83                 :             :                        && ehdr->e_ident[EI_DATA] != ELFDATA2MSB));
      84                 :             : 
      85                 :             :   /* Unconditionally overwrite the ELF version.  */
      86         [ +  + ]:        1462 :   update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT,
      87                 :             :                      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
      88                 :             : 
      89         [ +  + ]:        1462 :   if (unlikely (ehdr->e_version == EV_NONE))
      90                 :             :     {
      91                 :           8 :       ehdr->e_version = EV_CURRENT;
      92                 :           8 :       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
      93                 :             :     }
      94         [ -  + ]:        1454 :   else if (unlikely (ehdr->e_version != EV_CURRENT))
      95                 :             :     {
      96                 :           0 :       __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
      97                 :           0 :       return 1;
      98                 :             :     }
      99                 :             : 
     100         [ +  + ]:        1462 :   if (unlikely (shnum >= SHN_LORESERVE))
     101                 :             :     {
     102         [ +  + ]:          34 :       update_if_changed (ehdr->e_shnum, 0,
     103                 :             :                          elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
     104                 :             :     }
     105                 :             :   else
     106         [ +  + ]:        1428 :     update_if_changed (ehdr->e_shnum, shnum,
     107                 :             :                        elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
     108                 :             : 
     109         [ +  + ]:        1462 :   if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)))
     110                 :             :     {
     111                 :         946 :       ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
     112                 :         946 :       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
     113                 :             :     }
     114                 :             : 
     115                 :             :   /* If phnum is zero make sure e_phoff is also zero and not some random
     116                 :             :      value.  That would cause trouble in update_file.  */
     117   [ +  +  +  - ]:        1462 :   if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0)
     118                 :             :     {
     119                 :           0 :       ehdr->e_phoff = 0;
     120                 :           0 :       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
     121                 :             :     }
     122                 :             : 
     123                 :             :   return 0;
     124                 :             : }
     125                 :             : 
     126                 :             : 
     127                 :             : int64_t
     128                 :             : internal_function
     129                 :        1462 : __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
     130                 :             : {
     131                 :        1462 :   ElfW2(LIBELFBITS,Ehdr) *ehdr;
     132                 :        1462 :   int changed = 0;
     133                 :        1462 :   int ehdr_flags = 0;
     134                 :             : 
     135                 :        1462 :   ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf);
     136                 :             : 
     137                 :             :   /* Set the default values.  */
     138         [ +  - ]:        1462 :   if (ehdr == NULL
     139         [ -  + ]:        1462 :       || ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0)
     140                 :           0 :     return -1;
     141                 :             : 
     142                 :             :   /* At least the ELF header is there.  */
     143                 :        1462 :   ElfW2(LIBELFBITS,SizeWord) size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
     144                 :             : 
     145                 :             :   /* Set the program header position.  */
     146         [ +  + ]:        1462 :   if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
     147                 :         664 :     (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
     148         [ +  + ]:        1462 :   if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
     149                 :             :     {
     150                 :         854 :       size_t phnum;
     151         [ -  + ]:         854 :       if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
     152                 :           0 :         return -1;
     153                 :             : 
     154         [ +  + ]:         854 :       if (elf->flags & ELF_F_LAYOUT)
     155                 :             :         {
     156                 :             :           /* The user is supposed to fill out e_phoff.  Use it and
     157                 :             :              e_phnum to determine the maximum extend.  */
     158                 :         724 :           size = MAX (size,
     159                 :             :                       ehdr->e_phoff
     160                 :             :                       + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
     161                 :             :         }
     162                 :             :       else
     163                 :             :         {
     164         [ +  + ]:         130 :           update_if_changed (ehdr->e_phoff,
     165                 :             :                              elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
     166                 :             :                              ehdr_flags);
     167                 :             : 
     168                 :             :           /* We need no alignment here.  */
     169                 :         130 :           size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum);
     170                 :             :         }
     171                 :             :     }
     172                 :             : 
     173         [ +  + ]:        1462 :   if (shnum > 0)
     174                 :             :     {
     175                 :        1432 :       struct Elf_Scn *scn1 = NULL;
     176                 :        1432 :       Elf_ScnList *list;
     177                 :        1432 :       bool first = true;
     178                 :             : 
     179         [ -  + ]:        1432 :       assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0);
     180                 :             : 
     181         [ +  + ]:        1432 :       if (shnum >= SHN_LORESERVE)
     182                 :             :         {
     183                 :             :           /* We have to  fill in the number of sections in the header
     184                 :             :              of the zeroth section.  */
     185                 :          34 :           Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
     186                 :             : 
     187         [ +  - ]:          34 :           update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
     188                 :             :                              shnum, scn0->shdr_flags);
     189                 :             :         }
     190                 :             : 
     191                 :             :       /* Go over all sections and find out how large they are.  */
     192                 :        1432 :       list = &elf->state.ELFW(elf,LIBELFBITS).scns;
     193                 :             : 
     194                 :             :       /* Find the first section. */
     195         [ +  + ]:        1432 :       if (list->cnt > 1)
     196                 :        1424 :         scn1 = &list->data[1];
     197         [ +  - ]:           8 :       else if (list->next != NULL)
     198                 :           8 :         scn1 = &list->next->data[0];
     199                 :             : 
     200                 :             :       /* Load the section headers if necessary.  This loads the
     201                 :             :          headers for all sections.  */
     202         [ +  + ]:        1432 :       if (scn1 != NULL && scn1->shdr.ELFW(e,LIBELFBITS) == NULL)
     203                 :          58 :         (void) __elfw2(LIBELFBITS,getshdr_wrlock) (scn1);
     204                 :             : 
     205                 :        3394 :       do
     206                 :             :         {
     207         [ +  + ]:     3835804 :           for (size_t cnt = first == true; cnt < list->cnt; ++cnt)
     208                 :             :             {
     209                 :     3832410 :               Elf_Scn *scn = &list->data[cnt];
     210                 :     3832410 :               ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
     211                 :     3832410 :               int64_t offset = 0;
     212                 :             : 
     213         [ -  + ]:     3832410 :               assert (shdr != NULL);
     214                 :     3832410 :               ElfW2(LIBELFBITS,SizeWord) sh_entsize = shdr->sh_entsize;
     215                 :     3832410 :               ElfW2(LIBELFBITS,SizeWord) sh_align = shdr->sh_addralign ?: 1;
     216         [ -  + ]:     3832410 :               if (unlikely (! powerof2 (sh_align)))
     217                 :             :                 {
     218                 :           0 :                   __libelf_seterrno (ELF_E_INVALID_ALIGN);
     219                 :           0 :                   return -1;
     220                 :             :                 }
     221                 :             : 
     222                 :             :               /* Set the sh_entsize value if we can reliably detect it.  */
     223   [ +  +  +  +  :     3832410 :               switch (shdr->sh_type)
          +  +  +  +  -  
                -  -  + ]
     224                 :             :                 {
     225                 :        1066 :                 case SHT_SYMTAB:
     226                 :        1066 :                   sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
     227                 :        1066 :                   break;
     228                 :        2190 :                 case SHT_RELA:
     229                 :        2190 :                   sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1);
     230                 :        2190 :                   break;
     231                 :       44052 :                 case SHT_GROUP:
     232                 :             :                   /* Only relocatable files can contain section groups.  */
     233         [ -  + ]:       44052 :                   if (ehdr->e_type != ET_REL)
     234                 :             :                     {
     235                 :           0 :                       __libelf_seterrno (ELF_E_GROUP_NOT_REL);
     236                 :           0 :                       return -1;
     237                 :             :                     }
     238                 :       44056 :                   FALLTHROUGH;
     239                 :             :                 case SHT_SYMTAB_SHNDX:
     240                 :       44056 :                   sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
     241                 :       44056 :                   break;
     242                 :         264 :                 case SHT_HASH:
     243   [ +  +  +  +  :         264 :                   sh_entsize = SH_ENTSIZE_HASH (ehdr);
                   +  + ]
     244                 :             :                   break;
     245                 :         472 :                 case SHT_DYNAMIC:
     246                 :         472 :                   sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1);
     247                 :         472 :                   break;
     248                 :         428 :                 case SHT_REL:
     249                 :         428 :                   sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1);
     250                 :         428 :                   break;
     251                 :         468 :                 case SHT_DYNSYM:
     252                 :         468 :                   sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
     253                 :         468 :                   break;
     254                 :           0 :                 case SHT_SUNW_move:
     255                 :           0 :                   sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1);
     256                 :           0 :                   break;
     257                 :           0 :                 case SHT_SUNW_syminfo:
     258                 :           0 :                   sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1);
     259                 :           0 :                   break;
     260                 :           0 :                 case SHT_RELR:
     261                 :           0 :                   sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELR, 1);
     262                 :           0 :                   break;
     263                 :             :                 default:
     264                 :             :                   break;
     265                 :             :                 }
     266                 :             : 
     267                 :             :               /* If the section header contained the wrong entry size
     268                 :             :                  correct it and mark the header as modified.  */
     269         [ +  + ]:     3832410 :               update_if_changed (shdr->sh_entsize, sh_entsize,
     270                 :             :                                  scn->shdr_flags);
     271                 :             : 
     272                 :             :               /* Likewise for the alignment of a compressed section.
     273                 :             :                  For a SHF_COMPRESSED section set the correct
     274                 :             :                  sh_addralign value, which must match the d_align of
     275                 :             :                  the data (see __libelf_set_rawdata in elf_getdata.c).  */
     276         [ +  + ]:     3832410 :               if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
     277                 :             :                 {
     278                 :        1000 :                   sh_align = __libelf_type_align (ELFW(ELFCLASS,LIBELFBITS),
     279                 :             :                                                   ELF_T_CHDR);
     280         [ +  + ]:        1000 :                   update_if_changed (shdr->sh_addralign, sh_align,
     281                 :             :                                      scn->shdr_flags);
     282                 :             :                 }
     283                 :             : 
     284         [ +  + ]:     3832410 :               if (scn->data_read == 0
     285         [ -  + ]:      527360 :                   && __libelf_set_rawdata_wrlock (scn) != 0)
     286                 :             :                 /* Something went wrong.  The error value is already set.  */
     287                 :             :                 return -1;
     288                 :             : 
     289                 :             :               /* Iterate over all data blocks.  */
     290         [ +  + ]:     3832410 :               if (list->data[cnt].data_list_rear != NULL)
     291                 :             :                 {
     292                 :     3305038 :                   Elf_Data_List *dl = &scn->data_list;
     293                 :             : 
     294         [ +  + ]:     6610440 :                   while (dl != NULL)
     295                 :             :                     {
     296                 :     3305402 :                       Elf_Data *data = &dl->data.d;
     297   [ +  +  +  + ]:     3305402 :                       if (dl == &scn->data_list && data->d_buf == NULL
     298         [ -  + ]:      135762 :                           && scn->rawdata.d.d_buf != NULL)
     299                 :           0 :                         data = &scn->rawdata.d;
     300                 :             : 
     301         [ -  + ]:     3305402 :                       if (unlikely (data->d_version != EV_CURRENT))
     302                 :             :                         {
     303                 :           0 :                           __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
     304                 :           0 :                           return -1;
     305                 :             :                         }
     306                 :             : 
     307         [ -  + ]:     3305402 :                       if (unlikely (! powerof2 (data->d_align)))
     308                 :             :                         {
     309                 :           0 :                           __libelf_seterrno (ELF_E_INVALID_ALIGN);
     310                 :           0 :                           return -1;
     311                 :             :                         }
     312                 :             : 
     313                 :     3305402 :                       sh_align = MAX (sh_align, data->d_align);
     314                 :             : 
     315         [ +  + ]:     3305402 :                       if (elf->flags & ELF_F_LAYOUT)
     316                 :             :                         {
     317                 :             :                           /* The user specified the offset and the size.
     318                 :             :                              All we have to do is check whether this block
     319                 :             :                              fits in the size specified for the section.  */
     320         [ -  + ]:      802398 :                           if (unlikely ((ElfW2(LIBELFBITS,SizeWord))
     321                 :             :                                         (data->d_off + data->d_size)
     322                 :             :                                         > shdr->sh_size))
     323                 :             :                             {
     324                 :           0 :                               __libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
     325                 :           0 :                               return -1;
     326                 :             :                             }
     327                 :             :                         }
     328                 :             :                       else
     329                 :             :                         {
     330                 :             :                           /* Determine the padding.  */
     331                 :     2503004 :                           offset = ((offset + data->d_align - 1)
     332                 :     2503004 :                                     & ~(data->d_align - 1));
     333                 :             : 
     334         [ +  + ]:     2503004 :                           update_if_changed (data->d_off, offset, changed);
     335                 :             : 
     336                 :     2503004 :                           offset += data->d_size;
     337                 :             :                         }
     338                 :             : 
     339                 :             :                       /* Next data block.  */
     340                 :     3305402 :                       dl = dl->next;
     341                 :             :                     }
     342                 :             :                 }
     343                 :             :               else
     344                 :             :                 /* Get the size of the section from the raw data.  If
     345                 :             :                    none is available the value is zero.  */
     346                 :      527372 :                 offset += scn->rawdata.d.d_size;
     347                 :             : 
     348         [ +  + ]:     3832410 :               if (elf->flags & ELF_F_LAYOUT)
     349                 :             :                 {
     350         [ +  + ]:      803730 :                   size = MAX (size,
     351                 :             :                               (shdr->sh_type != SHT_NOBITS
     352                 :             :                                ? shdr->sh_offset + shdr->sh_size : 0));
     353                 :             : 
     354                 :             :                   /* The alignment must be a power of two.  This is a
     355                 :             :                      requirement from the ELF specification.  Additionally
     356                 :             :                      we test for the alignment of the section being large
     357                 :             :                      enough for the largest alignment required by a data
     358                 :             :                      block.  */
     359         [ +  - ]:      803730 :                   if (unlikely (! powerof2 (shdr->sh_addralign))
     360         [ -  + ]:      803730 :                       || unlikely ((shdr->sh_addralign ?: 1) < sh_align))
     361                 :             :                     {
     362                 :           0 :                       __libelf_seterrno (ELF_E_INVALID_ALIGN);
     363                 :           0 :                       return -1;
     364                 :             :                     }
     365                 :             :                 }
     366                 :             :               else
     367                 :             :                 {
     368                 :             :                   /* How much alignment do we need for this section.  */
     369         [ +  + ]:     3028680 :                   update_if_changed (shdr->sh_addralign, sh_align,
     370                 :             :                                      scn->shdr_flags);
     371                 :             : 
     372                 :     3028680 :                   size = (size + sh_align - 1) & ~(sh_align - 1);
     373                 :     3028680 :                   int offset_changed = 0;
     374         [ +  + ]:     3028680 :                   update_if_changed (shdr->sh_offset, size, offset_changed);
     375                 :     5005662 :                   changed |= offset_changed;
     376                 :             : 
     377         [ +  + ]:     1976982 :                   if (offset_changed && scn->data_list_rear == NULL)
     378                 :             :                     {
     379                 :             :                       /* The position of the section in the file
     380                 :             :                          changed.  Create the section data list.  */
     381         [ -  + ]:         348 :                       if (__elf_getdata_rdlock (scn, NULL) == NULL)
     382                 :             :                         return -1;
     383                 :             :                     }
     384                 :             : 
     385                 :             :                   /* See whether the section size is correct.  */
     386                 :     3028680 :                   int size_changed = 0;
     387         [ +  + ]:     3028680 :                   update_if_changed (shdr->sh_size,
     388                 :             :                                      (ElfW2(LIBELFBITS,SizeWord)) offset,
     389                 :             :                                      size_changed);
     390                 :     3028680 :                   changed |= size_changed;
     391                 :             : 
     392         [ +  + ]:     3028680 :                   if (shdr->sh_type != SHT_NOBITS)
     393                 :     2894246 :                     size += offset;
     394                 :             : 
     395                 :     3028680 :                   scn->shdr_flags |= (offset_changed | size_changed);
     396                 :     3028680 :                   scn->flags |= changed;
     397                 :             :                 }
     398                 :             : 
     399                 :             :               /* Check that the section size is actually a multiple of
     400                 :             :                  the entry size.  */
     401         [ +  + ]:     3832410 :               if (shdr->sh_entsize != 0 && shdr->sh_entsize != 1
     402         [ +  - ]:       52262 :                   && (elf->flags & ELF_F_PERMISSIVE) == 0)
     403                 :             :                 {
     404                 :             :                   /* For compressed sections check the uncompressed size.  */
     405                 :       52262 :                   ElfW2(LIBELFBITS,SizeWord) sh_size;
     406         [ +  + ]:       52262 :                   if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
     407                 :       52244 :                     sh_size = shdr->sh_size;
     408                 :             :                   else
     409                 :             :                     {
     410                 :          18 :                       ElfW2(LIBELFBITS,Chdr) *chdr;
     411                 :          18 :                       chdr = __elfw2(LIBELFBITS,getchdr_wrlock) (scn);
     412         [ -  + ]:          18 :                       if (unlikely (chdr == NULL))
     413                 :             :                         return -1;
     414                 :          18 :                       sh_size = chdr->ch_size;
     415                 :             :                     }
     416                 :             : 
     417         [ -  + ]:       52262 :                   if (unlikely (sh_size % shdr->sh_entsize != 0))
     418                 :             :                     {
     419                 :           0 :                       __libelf_seterrno (ELF_E_INVALID_SHENTSIZE);
     420                 :           0 :                       return -1;
     421                 :             :                     }
     422                 :             :                 }
     423                 :             :             }
     424                 :             : 
     425   [ +  +  -  + ]:        3394 :           assert (list->next == NULL || list->cnt == list->max);
     426                 :             : 
     427                 :        3394 :           first = false;
     428                 :             :         }
     429         [ +  + ]:        3394 :       while ((list = list->next) != NULL);
     430                 :             : 
     431                 :             :       /* Store section information.  */
     432         [ +  + ]:        1432 :       update_if_changed (ehdr->e_shentsize,
     433                 :             :                          elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), ehdr_flags);
     434         [ +  + ]:        1432 :       if (elf->flags & ELF_F_LAYOUT)
     435                 :             :         {
     436                 :             :           /* The user is supposed to fill out e_shoff.  Use it and
     437                 :             :              e_shnum (or sh_size of the dummy, first section header)
     438                 :             :              to determine the maximum extend.  */
     439                 :         768 :           size = MAX (size,
     440                 :             :                       (ehdr->e_shoff
     441                 :             :                        + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
     442                 :             :         }
     443                 :             :       else
     444                 :             :         {
     445                 :             :           /* Align for section header table.
     446                 :             : 
     447                 :             :              Yes, we use `sizeof' and not `__alignof__' since we do not
     448                 :             :              want to be surprised by architectures with less strict
     449                 :             :              alignment rules.  */
     450                 :             : #define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off))
     451                 :         664 :           size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1);
     452                 :             : 
     453         [ +  + ]:         664 :           update_if_changed (ehdr->e_shoff, size, elf->flags);
     454                 :             : 
     455                 :             :           /* Account for the section header size.  */
     456                 :         664 :           size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum);
     457                 :             :         }
     458                 :             :     }
     459                 :             : 
     460                 :        1462 :   elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags;
     461                 :             : 
     462                 :        1462 :   return size;
     463                 :             : }
        

Generated by: LCOV version 2.0-1