summaryrefslogtreecommitdiff
path: root/elfutils/libelf/gelf_fsize.c
blob: fc6faa0bcf8cb0d0152f5e2d69673e9fca4466f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/* Return the size of an object file type.
   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
   Written by Ulrich Drepper <drepper@redhat.com>, 1998.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 as
   published by the Free Software Foundation.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <gelf.h>
#include <stddef.h>

#include "libelfP.h"


/* These are the sizes for all the known types.  */
const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
{
  /* We have no entry for EV_NONE siince we have to set an error.  */
  [EV_CURRENT - 1] = {
    [ELFCLASS32 - 1] = {
#define TYPE_SIZES(LIBELFBITS) \
      [ELF_T_ADDR]	= ELFW2(LIBELFBITS, FSZ_ADDR),			      \
      [ELF_T_OFF]	= ELFW2(LIBELFBITS, FSZ_OFF),			      \
      [ELF_T_BYTE]	= 1,						      \
      [ELF_T_HALF]	= ELFW2(LIBELFBITS, FSZ_HALF),			      \
      [ELF_T_WORD]	= ELFW2(LIBELFBITS, FSZ_WORD),			      \
      [ELF_T_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
      [ELF_T_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
      [ELF_T_SXWORD]	= ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
      [ELF_T_EHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)),		      \
      [ELF_T_SHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Shdr)),		      \
      [ELF_T_SYM]	= sizeof (ElfW2(LIBELFBITS, Ext_Sym)),		      \
      [ELF_T_REL]	= sizeof (ElfW2(LIBELFBITS, Ext_Rel)),		      \
      [ELF_T_RELA]	= sizeof (ElfW2(LIBELFBITS, Ext_Rela)),		      \
      [ELF_T_PHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Phdr)),		      \
      [ELF_T_DYN]	= sizeof (ElfW2(LIBELFBITS, Ext_Dyn)),		      \
      [ELF_T_VDEF]	= sizeof (ElfW2(LIBELFBITS, Ext_Verdef)),	      \
      [ELF_T_VDAUX]	= sizeof (ElfW2(LIBELFBITS, Ext_Verdaux)),	      \
      [ELF_T_VNEED]	= sizeof (ElfW2(LIBELFBITS, Ext_Verneed)),	      \
      [ELF_T_VNAUX]	= sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)),	      \
      [ELF_T_NHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)),		      \
      [ELF_T_SYMINFO]	= sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)),	      \
      [ELF_T_MOVE]	= sizeof (ElfW2(LIBELFBITS, Ext_Move))
      TYPE_SIZES (32)
    },
    [ELFCLASS64 - 1] = {
      TYPE_SIZES (64)
    }
  }
};


size_t
gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int version)
{
  /* We do not have differences between file and memory sizes.  Better
     not since otherwise `mmap' would not work.  */
  if (elf == NULL)
    return 0;

  if (version == EV_NONE || version >= EV_NUM)
    {
      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
      return 0;
    }

  if (type >= ELF_T_NUM)
    {
      __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
      return 0;
    }

#if EV_NUM != 2
  return count * __libelf_type_sizes[version - 1][elf->class - 1][type];
#else
  return count * __libelf_type_sizes[0][elf->class - 1][type];
#endif
}
INTDEF(gelf_fsize)