gelf_getshdr.c revision 441f72d43a9b550baa779fc82f70816da5f74f0e
1/* Return section header.
2   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
3   Written by Ulrich Drepper <drepper@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
28GElf_Shdr *
29gelf_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}
91INTDEF(gelf_getshdr)
92