Home | History | Annotate | Download | only in libelf
      1 /* Update section header.
      2    Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 2000.
      4 
      5    This program is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation, version 2.
      8 
      9    This program is distributed in the hope that it will be useful,
     10    but WITHOUT ANY WARRANTY; without even the implied warranty of
     11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12    GNU General Public License for more details.
     13 
     14    You should have received a copy of the GNU General Public License
     15    along with this program; if not, write to the Free Software Foundation,
     16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
     17 
     18 #ifdef HAVE_CONFIG_H
     19 # include <config.h>
     20 #endif
     21 
     22 #include <gelf.h>
     23 #include <string.h>
     24 
     25 #include "libelfP.h"
     26 
     27 
     28 int
     29 gelf_update_shdr (Elf_Scn *scn, GElf_Shdr *src)
     30 {
     31   int result = 0;
     32   Elf *elf;
     33 
     34   if (scn == NULL || src == NULL)
     35     return 0;
     36 
     37   elf = scn->elf;
     38   rwlock_wrlock (elf->lock);
     39 
     40   if (elf->class == ELFCLASS32)
     41     {
     42       Elf32_Shdr *shdr = scn->shdr.e32 ?: INTUSE(elf32_getshdr) (scn);
     43 
     44       if (shdr == NULL)
     45 	{
     46 	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
     47 	  goto out;
     48 	}
     49 
     50       if (unlikely (src->sh_flags > 0xffffffffull)
     51 	  || unlikely (src->sh_addr > 0xffffffffull)
     52 	  || unlikely (src->sh_offset > 0xffffffffull)
     53 	  || unlikely (src->sh_size > 0xffffffffull)
     54 	  || unlikely (src->sh_addralign > 0xffffffffull)
     55 	  || unlikely (src->sh_entsize > 0xffffffffull))
     56 	{
     57 	  __libelf_seterrno (ELF_E_INVALID_DATA);
     58 	  goto out;
     59 	}
     60 
     61 #define COPY(name) \
     62       shdr->name = src->name
     63       COPY (sh_name);
     64       COPY (sh_type);
     65       COPY (sh_flags);
     66       COPY (sh_addr);
     67       COPY (sh_offset);
     68       COPY (sh_size);
     69       COPY (sh_link);
     70       COPY (sh_info);
     71       COPY (sh_addralign);
     72       COPY (sh_entsize);
     73     }
     74   else
     75     {
     76       Elf64_Shdr *shdr = scn->shdr.e64 ?: INTUSE(elf64_getshdr) (scn);
     77 
     78       if (shdr == NULL)
     79 	{
     80 	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
     81 	  goto out;
     82 	}
     83 
     84       /* We only have to copy the data.  */
     85       (void) memcpy (shdr, src, sizeof (GElf_Shdr));
     86     }
     87 
     88   result = 1;
     89 
     90  out:
     91   rwlock_unlock (elf->lock);
     92 
     93   return result;
     94 }
     95