1/* Return the size of an object file type.
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 <stddef.h>
24
25#include "libelfP.h"
26
27
28/* These are the sizes for all the known types.  */
29const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
30{
31  /* We have no entry for EV_NONE siince we have to set an error.  */
32  [EV_CURRENT - 1] = {
33    [ELFCLASS32 - 1] = {
34#define TYPE_SIZES(LIBELFBITS) \
35      [ELF_T_ADDR]	= ELFW2(LIBELFBITS, FSZ_ADDR),			      \
36      [ELF_T_OFF]	= ELFW2(LIBELFBITS, FSZ_OFF),			      \
37      [ELF_T_BYTE]	= 1,						      \
38      [ELF_T_HALF]	= ELFW2(LIBELFBITS, FSZ_HALF),			      \
39      [ELF_T_WORD]	= ELFW2(LIBELFBITS, FSZ_WORD),			      \
40      [ELF_T_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
41      [ELF_T_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
42      [ELF_T_SXWORD]	= ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
43      [ELF_T_EHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)),		      \
44      [ELF_T_SHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Shdr)),		      \
45      [ELF_T_SYM]	= sizeof (ElfW2(LIBELFBITS, Ext_Sym)),		      \
46      [ELF_T_REL]	= sizeof (ElfW2(LIBELFBITS, Ext_Rel)),		      \
47      [ELF_T_RELA]	= sizeof (ElfW2(LIBELFBITS, Ext_Rela)),		      \
48      [ELF_T_PHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Phdr)),		      \
49      [ELF_T_DYN]	= sizeof (ElfW2(LIBELFBITS, Ext_Dyn)),		      \
50      [ELF_T_VDEF]	= sizeof (ElfW2(LIBELFBITS, Ext_Verdef)),	      \
51      [ELF_T_VDAUX]	= sizeof (ElfW2(LIBELFBITS, Ext_Verdaux)),	      \
52      [ELF_T_VNEED]	= sizeof (ElfW2(LIBELFBITS, Ext_Verneed)),	      \
53      [ELF_T_VNAUX]	= sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)),	      \
54      [ELF_T_NHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)),		      \
55      [ELF_T_SYMINFO]	= sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)),	      \
56      [ELF_T_MOVE]	= sizeof (ElfW2(LIBELFBITS, Ext_Move))
57      TYPE_SIZES (32)
58    },
59    [ELFCLASS64 - 1] = {
60      TYPE_SIZES (64)
61    }
62  }
63};
64
65
66size_t
67gelf_fsize (elf, type, count, version)
68     Elf *elf;
69     Elf_Type type;
70     size_t count;
71     unsigned int version;
72{
73  /* We do not have differences between file and memory sizes.  Better
74     not since otherwise `mmap' would not work.  */
75  if (elf == NULL)
76    return 0;
77
78  if (version == EV_NONE || version >= EV_NUM)
79    {
80      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
81      return 0;
82    }
83
84  if (type >= ELF_T_NUM)
85    {
86      __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
87      return 0;
88    }
89
90#if EV_NUM != 2
91  return count * __libelf_type_sizes[version - 1][elf->class - 1][type];
92#else
93  return count * __libelf_type_sizes[0][elf->class - 1][type];
94#endif
95}
96INTDEF(gelf_fsize)
97