1/*- 2 * Copyright (c) 2006 Joseph Koshy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: releng/10.2/lib/libelf/libelf_fsize.m4 210340 2010-07-21 10:39:29Z kaiw $ 27 */ 28 29#include <libelf.h> 30#include <osreldate.h> 31 32#include "_libelf.h" 33 34/* 35 * Create an array of file sizes from the elf_type definitions 36 */ 37 38divert(-1) 39include(SRCDIR`/elf_types.m4') 40 41/* 42 * Translations from structure definitions to the size of their file 43 * representations. 44 */ 45 46/* `Basic' types. */ 47define(`BYTE_SIZE', 1) 48define(`IDENT_SIZE', `EI_NIDENT') 49 50/* Types that have variable length. */ 51define(`GNUHASH_SIZE', 1) 52define(`NOTE_SIZE', 1) 53 54/* Currently unimplemented types. */ 55define(`MOVEP_SIZE', 0) 56 57/* Overrides for 32 bit types that do not exist. */ 58define(`XWORD_SIZE32', 0) 59define(`SXWORD_SIZE32', 0) 60 61/* 62 * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively. 63 */ 64 65define(`FSZ32',`_FSZ32($1_DEF)') 66define(`_FSZ32', 67 `ifelse($#,1,0, 68 `_BSZ32($1)+_FSZ32(shift($@))')') 69define(`_BSZ32',`$2_SIZE32') 70 71define(`FSZ64',`_FSZ64($1_DEF)') 72define(`_FSZ64', 73 `ifelse($#,1,0, 74 `_BSZ64($1)+_FSZ64(shift($@))')') 75define(`_BSZ64',`$2_SIZE64') 76 77/* 78 * DEFINE_ELF_FSIZES(TYPE,NAME) 79 * 80 * Shorthand for defining for 32 and 64 versions 81 * of elf type TYPE. 82 * 83 * If TYPE`'_SIZE is defined, use its value for both 32 bit and 64 bit 84 * sizes. 85 * 86 * Otherwise, look for a explicit 32/64 bit size definition for TYPE, 87 * TYPE`'_SIZE32 or TYPE`'_SIZE64. If this definition is present, there 88 * is nothing further to do. 89 * 90 * Otherwise, if an Elf{32,64}_`'NAME structure definition is known, 91 * compute an expression that adds up the sizes of the structure's 92 * constituents. 93 * 94 * If such a structure definition is not known, treat TYPE as a primitive 95 * (i.e., integral) type and use sizeof(Elf{32,64}_`'NAME) to get its 96 * file representation size. 97 */ 98 99define(`DEFINE_ELF_FSIZE', 100 `ifdef($1`_SIZE', 101 `define($1_SIZE32,$1_SIZE) 102 define($1_SIZE64,$1_SIZE)', 103 `ifdef($1`_SIZE32',`', 104 `ifdef(`Elf32_'$2`_DEF', 105 `define($1_SIZE32,FSZ32(Elf32_$2))', 106 `define($1_SIZE32,`sizeof(Elf32_'$2`)')')') 107 ifdef($1`_SIZE64',`', 108 `ifdef(`Elf64_'$2`_DEF', 109 `define($1_SIZE64,FSZ64(Elf64_$2))', 110 `define($1_SIZE64,`sizeof(Elf64_'$2`)')')')')') 111 112define(`DEFINE_ELF_FSIZES', 113 `ifelse($#,1,`', 114 `DEFINE_ELF_FSIZE($1) 115 DEFINE_ELF_FSIZES(shift($@))')') 116 117DEFINE_ELF_FSIZES(ELF_TYPE_LIST) 118DEFINE_ELF_FSIZE(`IDENT',`') # `IDENT' is a pseudo type 119 120define(`FSIZE', 121 `#if __FreeBSD_version >= $3 122 [ELF_T_$1] = { .fsz32 = $1_SIZE32, .fsz64 = $1_SIZE64 }, 123#endif') 124define(`FSIZES', 125 `ifelse($#,1,`', 126 `FSIZE($1) 127FSIZES(shift($@))')') 128 129divert(0) 130 131struct fsize { 132 size_t fsz32; 133 size_t fsz64; 134}; 135 136static struct fsize fsize[ELF_T_NUM] = { 137FSIZES(ELF_TYPE_LIST) 138}; 139 140size_t 141_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) 142{ 143 size_t sz; 144 145 sz = 0; 146 if (v != EV_CURRENT) 147 LIBELF_SET_ERROR(VERSION, 0); 148 else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) 149 LIBELF_SET_ERROR(ARGUMENT, 0); 150 else { 151 sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; 152 if (sz == 0) 153 LIBELF_SET_ERROR(UNIMPL, 0); 154 } 155 156 return (sz*c); 157} 158 159