Home | History | Annotate | Download | only in libelf
      1 /* Update ELF 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_ehdr (Elf *elf, GElf_Ehdr *src)
     30 {
     31   int result = 0;
     32 
     33   if (elf == NULL)
     34     return 0;
     35 
     36   if (unlikely (elf->kind != ELF_K_ELF))
     37     {
     38       __libelf_seterrno (ELF_E_INVALID_HANDLE);
     39       return 0;
     40     }
     41 
     42   rwlock_wrlock (elf->lock);
     43 
     44   if (elf->class == ELFCLASS32)
     45     {
     46       Elf32_Ehdr *ehdr = elf->state.elf32.ehdr;
     47 
     48       if (ehdr == NULL)
     49 	{
     50 	  __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
     51 	  goto out;
     52 	}
     53 
     54       /* We have to convert the data to the 32 bit format.  This might
     55 	 overflow some fields so we have to test for this case before
     56 	 copying.  */
     57       if (unlikely (src->e_entry > 0xffffffffull)
     58 	  || unlikely (src->e_phoff > 0xffffffffull)
     59 	  || unlikely (src->e_shoff > 0xffffffffull))
     60 	{
     61 	  __libelf_seterrno (ELF_E_INVALID_DATA);
     62 	  goto out;
     63 	}
     64 
     65       /* Copy the data.  */
     66       memcpy (ehdr->e_ident, src->e_ident, EI_NIDENT);
     67 #define COPY(name) \
     68       ehdr->name = src->name
     69       COPY (e_type);
     70       COPY (e_machine);
     71       COPY (e_version);
     72       COPY (e_entry);
     73       COPY (e_phoff);
     74       COPY (e_shoff);
     75       COPY (e_flags);
     76       COPY (e_ehsize);
     77       COPY (e_phentsize);
     78       COPY (e_phnum);
     79       COPY (e_shentsize);
     80       COPY (e_shnum);
     81       COPY (e_shstrndx);
     82     }
     83   else
     84     {
     85       Elf64_Ehdr *ehdr = elf->state.elf64.ehdr;
     86 
     87       if (ehdr == NULL)
     88 	{
     89 	  __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
     90 	  goto out;
     91 	}
     92 
     93       /* Just copy the data.  */
     94       memcpy (ehdr, src, sizeof (Elf64_Ehdr));
     95     }
     96 
     97   result = 1;
     98 
     99  out:
    100   rwlock_unlock (elf->lock);
    101 
    102   return result;
    103 }
    104