Home | History | Annotate | Download | only in libelf
      1 /* Return section header.
      2    Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 1998.
      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 GElf_Shdr *
     29 gelf_getshdr (scn, dst)
     30      Elf_Scn *scn;
     31      GElf_Shdr *dst;
     32 {
     33   GElf_Shdr *result = NULL;
     34 
     35   if (scn == NULL)
     36     return NULL;
     37 
     38   if (dst == NULL)
     39     {
     40       __libelf_seterrno (ELF_E_INVALID_OPERAND);
     41       return NULL;
     42     }
     43 
     44   rwlock_rdlock (scn->elf->lock);
     45 
     46   if (scn->elf->class == ELFCLASS32)
     47     {
     48       /* Copy the elements one-by-one.  */
     49       Elf32_Shdr *shdr = scn->shdr.e32 ?: INTUSE(elf32_getshdr) (scn);
     50 
     51       if (shdr == NULL)
     52 	{
     53 	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
     54 	  goto out;
     55 	}
     56 
     57 #define COPY(name) \
     58       dst->name = shdr->name
     59       COPY (sh_name);
     60       COPY (sh_type);
     61       COPY (sh_flags);
     62       COPY (sh_addr);
     63       COPY (sh_offset);
     64       COPY (sh_size);
     65       COPY (sh_link);
     66       COPY (sh_info);
     67       COPY (sh_addralign);
     68       COPY (sh_entsize);
     69 
     70       result = dst;
     71     }
     72   else
     73     {
     74       Elf64_Shdr *shdr = scn->shdr.e64 ?: INTUSE(elf64_getshdr) (scn);
     75 
     76       if (shdr == NULL)
     77 	{
     78 	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
     79 	  goto out;
     80 	}
     81 
     82       /* We only have to copy the data.  */
     83       result = memcpy (dst, shdr, sizeof (GElf_Shdr));
     84     }
     85 
     86  out:
     87   rwlock_unlock (scn->elf->lock);
     88 
     89   return result;
     90 }
     91 INTDEF(gelf_getshdr)
     92