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