libelf_fsize.m4 revision 260697
1169691Skan/*-
2169691Skan * Copyright (c) 2006,2008-2011 Joseph Koshy
3169691Skan * All rights reserved.
4169691Skan *
5169691Skan * Redistribution and use in source and binary forms, with or without
6169691Skan * modification, are permitted provided that the following conditions
7169691Skan * are met:
8169691Skan * 1. Redistributions of source code must retain the above copyright
9169691Skan *    notice, this list of conditions and the following disclaimer.
10169691Skan * 2. Redistributions in binary form must reproduce the above copyright
11169691Skan *    notice, this list of conditions and the following disclaimer in the
12169691Skan *    documentation and/or other materials provided with the distribution.
13169691Skan *
14169691Skan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15169691Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16169691Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17169691Skan * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18169691Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19169691Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20169691Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21169691Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22169691Skan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23169691Skan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24169691Skan * SUCH DAMAGE.
25169691Skan */
26169691Skan
27169691Skan#include <libelf.h>
28169691Skan
29169691Skan#include "_libelf.h"
30169691Skan
31169691SkanELFTC_VCSID("$Id: libelf_fsize.m4 2225 2011-11-26 18:55:54Z jkoshy $");
32169691Skan
33169691Skan/* WARNING: GENERATED FROM __file__. */
34169691Skan
35169691Skan/*
36169691Skan * Create an array of file sizes from the elf_type definitions
37169691Skan */
38169691Skan
39169691Skandivert(-1)
40169691Skaninclude(SRCDIR`/elf_types.m4')
41169691Skan
42169691Skan/*
43169691Skan * Translations from structure definitions to the size of their file
44169691Skan * representations.
45169691Skan */
46169691Skan
47169691Skan/* `Basic' types. */
48169691Skandefine(`BYTE_SIZE',	1)
49169691Skandefine(`IDENT_SIZE',	`EI_NIDENT')
50169691Skan
51169691Skan/* Types that have variable length. */
52169691Skandefine(`GNUHASH_SIZE',	1)
53169691Skandefine(`NOTE_SIZE',	1)
54169691Skandefine(`VDEF_SIZE',	1)
55169691Skandefine(`VNEED_SIZE',	1)
56169691Skan
57169691Skan/* Currently unimplemented types. */
58169691Skandefine(`MOVEP_SIZE',	0)
59169691Skan
60169691Skan/* Overrides for 32 bit types that do not exist. */
61169691Skandefine(`XWORD_SIZE32',	0)
62169691Skandefine(`SXWORD_SIZE32',	0)
63169691Skan
64169691Skan/*
65169691Skan * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively.
66169691Skan */
67169691Skan
68169691Skandefine(`FSZ32',`_FSZ32($1_DEF)')
69169691Skandefine(`_FSZ32',
70169691Skan  `ifelse($#,1,0,
71169691Skan    `_BSZ32($1)+_FSZ32(shift($@))')')
72169691Skandefine(`_BSZ32',`$2_SIZE32')
73169691Skan
74169691Skandefine(`FSZ64',`_FSZ64($1_DEF)')
75169691Skandefine(`_FSZ64',
76169691Skan  `ifelse($#,1,0,
77169691Skan    `_BSZ64($1)+_FSZ64(shift($@))')')
78169691Skandefine(`_BSZ64',`$2_SIZE64')
79169691Skan
80169691Skan/*
81169691Skan * DEFINE_ELF_FSIZES(TYPE,NAME)
82169691Skan *
83169691Skan * Shorthand for defining  for 32 and 64 versions
84169691Skan * of elf type TYPE.
85169691Skan *
86169691Skan * If TYPE`'_SIZE is defined, use its value for both 32 bit and 64 bit
87169691Skan * sizes.
88169691Skan *
89169691Skan * Otherwise, look for a explicit 32/64 bit size definition for TYPE,
90169691Skan * TYPE`'_SIZE32 or TYPE`'_SIZE64. If this definition is present, there
91169691Skan * is nothing further to do.
92169691Skan *
93169691Skan * Otherwise, if an Elf{32,64}_`'NAME structure definition is known,
94169691Skan * compute an expression that adds up the sizes of the structure's
95169691Skan * constituents.
96169691Skan *
97169691Skan * If such a structure definition is not known, treat TYPE as a primitive
98169691Skan * (i.e., integral) type and use sizeof(Elf{32,64}_`'NAME) to get its
99169691Skan * file representation size.
100169691Skan */
101169691Skan
102169691Skandefine(`DEFINE_ELF_FSIZE',
103169691Skan  `ifdef($1`_SIZE',
104169691Skan    `define($1_SIZE32,$1_SIZE)
105169691Skan     define($1_SIZE64,$1_SIZE)',
106169691Skan    `ifdef($1`_SIZE32',`',
107169691Skan      `ifdef(`Elf32_'$2`_DEF',
108169691Skan        `define($1_SIZE32,FSZ32(Elf32_$2))',
109169691Skan        `define($1_SIZE32,`sizeof(Elf32_'$2`)')')')
110169691Skan     ifdef($1`_SIZE64',`',
111169691Skan      `ifdef(`Elf64_'$2`_DEF',
112169691Skan        `define($1_SIZE64,FSZ64(Elf64_$2))',
113169691Skan        `define($1_SIZE64,`sizeof(Elf64_'$2`)')')')')')
114169691Skan
115169691Skandefine(`DEFINE_ELF_FSIZES',
116169691Skan  `ifelse($#,1,`',
117169691Skan    `DEFINE_ELF_FSIZE($1)
118169691Skan     DEFINE_ELF_FSIZES(shift($@))')')
119169691Skan
120169691SkanDEFINE_ELF_FSIZES(ELF_TYPE_LIST)
121169691SkanDEFINE_ELF_FSIZE(`IDENT',`')	# `IDENT' is a pseudo type
122169691Skan
123169691Skandefine(`FSIZE',
124169691Skan  `[ELF_T_$1] = { .fsz32 = $1_SIZE32, .fsz64 = $1_SIZE64 },
125169691Skan')
126169691Skandefine(`FSIZES',
127169691Skan  `ifelse($#,1,`',
128169691Skan    `FSIZE($1)
129169691SkanFSIZES(shift($@))')')
130169691Skan
131169691Skandivert(0)
132169691Skan
133169691Skanstruct fsize {
134169691Skan	size_t fsz32;
135169691Skan	size_t fsz64;
136169691Skan};
137169691Skan
138169691Skanstatic struct fsize fsize[ELF_T_NUM] = {
139169691SkanFSIZES(ELF_TYPE_LIST)
140};
141
142size_t
143_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c)
144{
145	size_t sz;
146
147	sz = 0;
148	if (v != EV_CURRENT)
149		LIBELF_SET_ERROR(VERSION, 0);
150	else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST)
151		LIBELF_SET_ERROR(ARGUMENT, 0);
152	else {
153		sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32;
154		if (sz == 0)
155			LIBELF_SET_ERROR(UNIMPL, 0);
156	}
157
158	return (sz*c);
159}
160