Branch data Line data Source code
1 : : /* Return the size of an object file type.
2 : : Copyright (C) 1998-2010, 2015 Red Hat, Inc.
3 : : Copyright (C) 2025 Mark J. Wielaard <mark@klomp.org>
4 : : This file is part of elfutils.
5 : : Written by Ulrich Drepper <drepper@redhat.com>, 1998.
6 : :
7 : : This file is free software; you can redistribute it and/or modify
8 : : it under the terms of either
9 : :
10 : : * the GNU Lesser General Public License as published by the Free
11 : : Software Foundation; either version 3 of the License, or (at
12 : : your option) any later version
13 : :
14 : : or
15 : :
16 : : * the GNU General Public License as published by the Free
17 : : Software Foundation; either version 2 of the License, or (at
18 : : your option) any later version
19 : :
20 : : or both in parallel, as here.
21 : :
22 : : elfutils is distributed in the hope that it will be useful, but
23 : : WITHOUT ANY WARRANTY; without even the implied warranty of
24 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 : : General Public License for more details.
26 : :
27 : : You should have received copies of the GNU General Public License and
28 : : the GNU Lesser General Public License along with this program. If
29 : : not, see <http://www.gnu.org/licenses/>. */
30 : :
31 : : #ifdef HAVE_CONFIG_H
32 : : # include <config.h>
33 : : #endif
34 : :
35 : : #include <gelf.h>
36 : : #include <stddef.h>
37 : :
38 : : #include "libelfP.h"
39 : :
40 : :
41 : : /* These are the sizes for all the known types. */
42 : : const size_t __libelf_type_sizes[ELFCLASSNUM - 1][ELF_T_NUM] =
43 : : {
44 : : [ELFCLASS32 - 1] = {
45 : : #define TYPE_SIZES(LIBELFBITS) \
46 : : [ELF_T_ADDR] = ELFW2(LIBELFBITS, FSZ_ADDR), \
47 : : [ELF_T_OFF] = ELFW2(LIBELFBITS, FSZ_OFF), \
48 : : [ELF_T_BYTE] = 1, \
49 : : [ELF_T_HALF] = ELFW2(LIBELFBITS, FSZ_HALF), \
50 : : [ELF_T_WORD] = ELFW2(LIBELFBITS, FSZ_WORD), \
51 : : [ELF_T_SWORD] = ELFW2(LIBELFBITS, FSZ_SWORD), \
52 : : [ELF_T_XWORD] = ELFW2(LIBELFBITS, FSZ_XWORD), \
53 : : [ELF_T_SXWORD] = ELFW2(LIBELFBITS, FSZ_SXWORD), \
54 : : [ELF_T_EHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)), \
55 : : [ELF_T_SHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Shdr)), \
56 : : [ELF_T_SYM] = sizeof (ElfW2(LIBELFBITS, Ext_Sym)), \
57 : : [ELF_T_REL] = sizeof (ElfW2(LIBELFBITS, Ext_Rel)), \
58 : : [ELF_T_RELA] = sizeof (ElfW2(LIBELFBITS, Ext_Rela)), \
59 : : [ELF_T_PHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Phdr)), \
60 : : [ELF_T_DYN] = sizeof (ElfW2(LIBELFBITS, Ext_Dyn)), \
61 : : [ELF_T_VDEF] = sizeof (ElfW2(LIBELFBITS, Ext_Verdef)), \
62 : : [ELF_T_VDAUX] = sizeof (ElfW2(LIBELFBITS, Ext_Verdaux)), \
63 : : [ELF_T_VNEED] = sizeof (ElfW2(LIBELFBITS, Ext_Verneed)), \
64 : : [ELF_T_VNAUX] = sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)), \
65 : : [ELF_T_NHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)), \
66 : : /* Note the header size is the same, but padding is different. */ \
67 : : [ELF_T_NHDR8] = sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)), \
68 : : [ELF_T_SYMINFO] = sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)), \
69 : : [ELF_T_MOVE] = sizeof (ElfW2(LIBELFBITS, Ext_Move)), \
70 : : [ELF_T_LIB] = sizeof (ElfW2(LIBELFBITS, Ext_Lib)), \
71 : : [ELF_T_AUXV] = sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)), \
72 : : [ELF_T_CHDR] = sizeof (ElfW2(LIBELFBITS, Ext_Chdr)), \
73 : : [ELF_T_GNUHASH] = ELFW2(LIBELFBITS, FSZ_WORD), \
74 : : [ELF_T_RELR] = ELFW2(LIBELFBITS, FSZ_RELR)
75 : : TYPE_SIZES (32)
76 : : },
77 : : [ELFCLASS64 - 1] = {
78 : : TYPE_SIZES (64)
79 : : }
80 : : };
81 : :
82 : :
83 : : size_t
84 : 365672 : gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int version)
85 : : {
86 : : /* We do not have differences between file and memory sizes. Better
87 : : not since otherwise `mmap' would not work. */
88 [ - + ]: 365672 : if (elf == NULL)
89 : : return 0;
90 : :
91 [ - + ]: 365672 : if (version != EV_CURRENT)
92 : : {
93 : 0 : __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
94 : 0 : return 0;
95 : : }
96 : :
97 [ - + ]: 365672 : if (type >= ELF_T_NUM)
98 : : {
99 : 0 : __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
100 : 0 : return 0;
101 : : }
102 : :
103 : 365672 : return count * __libelf_type_sizes[elf->class - 1][type];
104 : : }
105 : : INTDEF(gelf_fsize)
106 : :
107 : :
108 : : #ifdef MAIN_CHECK
109 : : #include <inttypes.h>
110 : : #include <stdio.h>
111 : :
112 : : void
113 : 28 : test_fsize (Elf_Type type)
114 : : {
115 : 28 : printf ("Testing 0x%" PRIx32 ": ", type);
116 : :
117 : 28 : int fsize32 = __libelf_type_sizes[ELFCLASS32 - 1][type];
118 [ - + ]: 28 : if (fsize32 <= 0)
119 : : {
120 : 0 : printf ("Unhandled type %" PRIx32 " for ELFCLASS32\n", type);
121 : 0 : exit (-1);
122 : : }
123 : 28 : printf (" %d, ", fsize32);
124 : :
125 : 28 : int fsize64 = __libelf_type_sizes[ELFCLASS64 - 1][type];
126 [ - + ]: 28 : if (fsize64 <= 0)
127 : : {
128 : 0 : printf ("Unhandled type %" PRIx32 " for ELFCLASS64\n", type);
129 : 0 : exit (-1);
130 : : }
131 : 28 : printf ("%d\n", fsize64);
132 : :
133 : : /* In theory fsize for 32 bit could of course be larger than fsize
134 : : for 64 bit. But if so, better adjust this testcase and
135 : : explain. */
136 [ - + ]: 28 : if (fsize32 > fsize64)
137 : : {
138 : 0 : printf ("fsize32 %d > fsize64 %d\n", fsize32, fsize64);
139 : 0 : exit(-1);
140 : : }
141 : 28 : }
142 : :
143 : : int
144 : 1 : main (void)
145 : : {
146 [ + + ]: 29 : for (Elf_Type type = 0; type < ELF_T_NUM; type++)
147 : 28 : test_fsize (type);
148 : 1 : return 0;
149 : : }
150 : : #endif
|