| /*- |
| * Copyright (c) 2006 Joseph Koshy |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * |
| * $FreeBSD: src/lib/libelf/libelf_fsize.m4,v 1.2 2006/12/18 05:40:01 jkoshy Exp $ |
| */ |
| |
| #include "libelf.h" |
| #include "_libelf.h" |
| |
| /* |
| * Create an array of file sizes from the elf_type definitions |
| */ |
| |
| divert(-1) |
| include(SRCDIR`/elf_types.m4') |
| |
| /* |
| * Translations from structure definitions to the size of their file |
| * representations. |
| */ |
| |
| /* `Basic' types */ |
| define(`BYTE_SIZE', 1) |
| define(`IDENT_SIZE', `EI_NIDENT') |
| define(`NOTE_SIZE', 1) /* Elf_Note structures have variable length. */ |
| |
| /* Currently unimplemented types */ |
| define(`MOVEP_SIZE', 0) |
| |
| /* Overrides for 32 bit types that do not exist */ |
| define(`XWORD_SIZE32', 0) |
| define(`SXWORD_SIZE32', 0) |
| |
| /* |
| * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively. |
| */ |
| |
| define(`FSZ32',`_FSZ32($1_DEF)') |
| define(`_FSZ32', |
| `ifelse($#,1,0, |
| `_BSZ32($1)+_FSZ32(shift($@))')') |
| define(`_BSZ32',`$2_SIZE32') |
| |
| define(`FSZ64',`_FSZ64($1_DEF)') |
| define(`_FSZ64', |
| `ifelse($#,1,0, |
| `_BSZ64($1)+_FSZ64(shift($@))')') |
| define(`_BSZ64',`$2_SIZE64') |
| |
| /* |
| * DEFINE_ELF_FSIZES(TYPE,NAME) |
| * |
| * Shorthand for defining for 32 and 64 versions |
| * of elf type TYPE. |
| * |
| * If TYPE`'_SIZE is defined, use its value for both 32 bit and 64 bit |
| * sizes. |
| * |
| * Otherwise, look for a explicit 32/64 bit size definition for TYPE, |
| * TYPE`'_SIZE32 or TYPE`'_SIZE64. If this definition is present, there |
| * is nothing further to do. |
| * |
| * Otherwise, if an Elf{32,64}_`'NAME structure definition is known, |
| * compute an expression that adds up the sizes of the structure's |
| * constituents. |
| * |
| * If such a structure definition is not known, treat TYPE as a primitive |
| * (i.e., integral) type and use sizeof(Elf{32,64}_`'NAME) to get its |
| * file representation size. |
| */ |
| |
| define(`DEFINE_ELF_FSIZE', |
| `ifdef($1`_SIZE', |
| `define($1_SIZE32,$1_SIZE) |
| define($1_SIZE64,$1_SIZE)', |
| `ifdef($1`_SIZE32',`', |
| `ifdef(`Elf32_'$2`_DEF', |
| `define($1_SIZE32,FSZ32(Elf32_$2))', |
| `define($1_SIZE32,`sizeof(Elf32_'$2`)')')') |
| ifdef($1`_SIZE64',`', |
| `ifdef(`Elf64_'$2`_DEF', |
| `define($1_SIZE64,FSZ64(Elf64_$2))', |
| `define($1_SIZE64,`sizeof(Elf64_'$2`)')')')')') |
| |
| define(`DEFINE_ELF_FSIZES', |
| `ifelse($#,1,`', |
| `DEFINE_ELF_FSIZE($1) |
| DEFINE_ELF_FSIZES(shift($@))')') |
| |
| DEFINE_ELF_FSIZES(ELF_TYPE_LIST) |
| DEFINE_ELF_FSIZE(`IDENT',`') # `IDENT' is a pseudo type |
| |
| define(`FSIZE', |
| `[ELF_T_$1] = { .fsz32 = $1_SIZE32, .fsz64 = $1_SIZE64 },') |
| define(`FSIZES', |
| `ifelse($#,1,`', |
| `FSIZE($1) |
| FSIZES(shift($@))')') |
| |
| divert(0) |
| |
| struct fsize { |
| size_t fsz32; |
| size_t fsz64; |
| }; |
| |
| static struct fsize fsize[ELF_T_NUM] = { |
| FSIZES(ELF_TYPE_LIST) |
| }; |
| |
| size_t |
| _libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) |
| { |
| size_t sz; |
| |
| sz = 0; |
| if (v != EV_CURRENT) |
| LIBELF_SET_ERROR(VERSION, 0); |
| else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) |
| LIBELF_SET_ERROR(ARGUMENT, 0); |
| else { |
| sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; |
| if (sz == 0) |
| LIBELF_SET_ERROR(UNIMPL, 0); |
| } |
| |
| return (sz*c); |
| } |
| |