libelf_convert.m4 revision 4484
14484Sbinkertn@umich.edu/*- 24484Sbinkertn@umich.edu * Copyright (c) 2006 Joseph Koshy 34484Sbinkertn@umich.edu * All rights reserved. 44484Sbinkertn@umich.edu * 54484Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without 64484Sbinkertn@umich.edu * modification, are permitted provided that the following conditions 74484Sbinkertn@umich.edu * are met: 84484Sbinkertn@umich.edu * 1. Redistributions of source code must retain the above copyright 94484Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer. 104484Sbinkertn@umich.edu * 2. Redistributions in binary form must reproduce the above copyright 114484Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the 124484Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution. 134484Sbinkertn@umich.edu * 144484Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 154484Sbinkertn@umich.edu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 164484Sbinkertn@umich.edu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 174484Sbinkertn@umich.edu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 184484Sbinkertn@umich.edu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 194484Sbinkertn@umich.edu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 204484Sbinkertn@umich.edu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 214484Sbinkertn@umich.edu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 224484Sbinkertn@umich.edu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 234484Sbinkertn@umich.edu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 244484Sbinkertn@umich.edu * SUCH DAMAGE. 254484Sbinkertn@umich.edu */ 264484Sbinkertn@umich.edu 274484Sbinkertn@umich.edu#include <sys/types.h> 284484Sbinkertn@umich.edu 294484Sbinkertn@umich.edu#include <assert.h> 304484Sbinkertn@umich.edu#include <string.h> 314484Sbinkertn@umich.edu 324484Sbinkertn@umich.edu#include "elf32.h" 334484Sbinkertn@umich.edu#include "elf64.h" 344484Sbinkertn@umich.edu#include "libelf.h" 354484Sbinkertn@umich.edu#include "_libelf.h" 364484Sbinkertn@umich.edu 374484Sbinkertn@umich.edu/* WARNING: GENERATED FROM __file__. */ 384484Sbinkertn@umich.edu 394484Sbinkertn@umich.edu/* 404484Sbinkertn@umich.edu * Macros to swap various integral quantities. 414484Sbinkertn@umich.edu */ 424484Sbinkertn@umich.edu 434484Sbinkertn@umich.edu#define SWAP_HALF(X) do { \ 444484Sbinkertn@umich.edu uint16_t _x = (uint16_t) (X); \ 454484Sbinkertn@umich.edu uint16_t _t = _x & 0xFF; \ 464484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 474484Sbinkertn@umich.edu (X) = _t; \ 484484Sbinkertn@umich.edu } while (0) 494484Sbinkertn@umich.edu#define SWAP_WORD(X) do { \ 504484Sbinkertn@umich.edu uint32_t _x = (uint32_t) (X); \ 514484Sbinkertn@umich.edu uint32_t _t = _x & 0xFF; \ 524484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 534484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 544484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 554484Sbinkertn@umich.edu (X) = _t; \ 564484Sbinkertn@umich.edu } while (0) 574484Sbinkertn@umich.edu#define SWAP_ADDR32(X) SWAP_WORD(X) 584484Sbinkertn@umich.edu#define SWAP_OFF32(X) SWAP_WORD(X) 594484Sbinkertn@umich.edu#define SWAP_SWORD(X) SWAP_WORD(X) 604484Sbinkertn@umich.edu#define SWAP_WORD64(X) do { \ 614484Sbinkertn@umich.edu uint64_t _x = (uint64_t) (X); \ 624484Sbinkertn@umich.edu uint64_t _t = _x & 0xFF; \ 634484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 644484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 654484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 664484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 674484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 684484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 694484Sbinkertn@umich.edu _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 704484Sbinkertn@umich.edu (X) = _t; \ 714484Sbinkertn@umich.edu } while (0) 724484Sbinkertn@umich.edu#define SWAP_ADDR64(X) SWAP_WORD64(X) 734484Sbinkertn@umich.edu#define SWAP_LWORD(X) SWAP_WORD64(X) 744484Sbinkertn@umich.edu#define SWAP_OFF64(X) SWAP_WORD64(X) 754484Sbinkertn@umich.edu#define SWAP_SXWORD(X) SWAP_WORD64(X) 764484Sbinkertn@umich.edu#define SWAP_XWORD(X) SWAP_WORD64(X) 774484Sbinkertn@umich.edu 784484Sbinkertn@umich.edu/* 794484Sbinkertn@umich.edu * Write out various integral values. The destination pointer could 804484Sbinkertn@umich.edu * be unaligned. Values are written out in native byte order. The 814484Sbinkertn@umich.edu * destination pointer is incremented after the write. 824484Sbinkertn@umich.edu */ 834484Sbinkertn@umich.edu#define WRITE_BYTE(P,X) do { \ 844484Sbinkertn@umich.edu unsigned char *const _p = (unsigned char *) (P); \ 854484Sbinkertn@umich.edu _p[0] = (unsigned char) (X); \ 864484Sbinkertn@umich.edu (P) = _p + 1; \ 874484Sbinkertn@umich.edu } while (0) 884484Sbinkertn@umich.edu#define WRITE_HALF(P,X) do { \ 894484Sbinkertn@umich.edu uint16_t _t = (X); \ 904484Sbinkertn@umich.edu unsigned char *const _p = (unsigned char *) (P); \ 914484Sbinkertn@umich.edu unsigned const char *const _q = (unsigned char *) &_t; \ 924484Sbinkertn@umich.edu _p[0] = _q[0]; \ 934484Sbinkertn@umich.edu _p[1] = _q[1]; \ 944484Sbinkertn@umich.edu (P) = _p + 2; \ 954484Sbinkertn@umich.edu } while (0) 964484Sbinkertn@umich.edu#define WRITE_WORD(P,X) do { \ 974484Sbinkertn@umich.edu uint32_t _t = (X); \ 984484Sbinkertn@umich.edu unsigned char *const _p = (unsigned char *) (P); \ 994484Sbinkertn@umich.edu unsigned const char *const _q = (unsigned char *) &_t; \ 1004484Sbinkertn@umich.edu _p[0] = _q[0]; \ 1014484Sbinkertn@umich.edu _p[1] = _q[1]; \ 1024484Sbinkertn@umich.edu _p[2] = _q[2]; \ 1034484Sbinkertn@umich.edu _p[3] = _q[3]; \ 1044484Sbinkertn@umich.edu (P) = _p + 4; \ 1054484Sbinkertn@umich.edu } while (0) 1064484Sbinkertn@umich.edu#define WRITE_ADDR32(P,X) WRITE_WORD(P,X) 1074484Sbinkertn@umich.edu#define WRITE_OFF32(P,X) WRITE_WORD(P,X) 1084484Sbinkertn@umich.edu#define WRITE_SWORD(P,X) WRITE_WORD(P,X) 1094484Sbinkertn@umich.edu#define WRITE_WORD64(P,X) do { \ 1104484Sbinkertn@umich.edu uint64_t _t = (X); \ 1114484Sbinkertn@umich.edu unsigned char *const _p = (unsigned char *) (P); \ 1124484Sbinkertn@umich.edu unsigned const char *const _q = (unsigned char *) &_t; \ 1134484Sbinkertn@umich.edu _p[0] = _q[0]; \ 1144484Sbinkertn@umich.edu _p[1] = _q[1]; \ 1154484Sbinkertn@umich.edu _p[2] = _q[2]; \ 1164484Sbinkertn@umich.edu _p[3] = _q[3]; \ 1174484Sbinkertn@umich.edu _p[4] = _q[4]; \ 1184484Sbinkertn@umich.edu _p[5] = _q[5]; \ 1194484Sbinkertn@umich.edu _p[6] = _q[6]; \ 1204484Sbinkertn@umich.edu _p[7] = _q[7]; \ 1214484Sbinkertn@umich.edu (P) = _p + 8; \ 1224484Sbinkertn@umich.edu } while (0) 1234484Sbinkertn@umich.edu#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) 1244484Sbinkertn@umich.edu#define WRITE_LWORD(P,X) WRITE_WORD64(P,X) 1254484Sbinkertn@umich.edu#define WRITE_OFF64(P,X) WRITE_WORD64(P,X) 1264484Sbinkertn@umich.edu#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) 1274484Sbinkertn@umich.edu#define WRITE_XWORD(P,X) WRITE_WORD64(P,X) 1284484Sbinkertn@umich.edu#define WRITE_IDENT(P,X) do { \ 1294484Sbinkertn@umich.edu (void) memcpy((P), (X), sizeof((X))); \ 1304484Sbinkertn@umich.edu (P) = (P) + EI_NIDENT; \ 1314484Sbinkertn@umich.edu } while (0) 1324484Sbinkertn@umich.edu 1334484Sbinkertn@umich.edu/* 1344484Sbinkertn@umich.edu * Read in various integral values. The source pointer could be 1354484Sbinkertn@umich.edu * unaligned. Values are read in in native byte order. The source 1364484Sbinkertn@umich.edu * pointer is incremented appropriately. 1374484Sbinkertn@umich.edu */ 1384484Sbinkertn@umich.edu 1394484Sbinkertn@umich.edu#define READ_BYTE(P,X) do { \ 1404484Sbinkertn@umich.edu const unsigned char *const _p = \ 1414484Sbinkertn@umich.edu (const unsigned char *) (P); \ 1424484Sbinkertn@umich.edu (X) = _p[0]; \ 1434484Sbinkertn@umich.edu (P) = (P) + 1; \ 1444484Sbinkertn@umich.edu } while (0) 1454484Sbinkertn@umich.edu#define READ_HALF(P,X) do { \ 1464484Sbinkertn@umich.edu uint16_t _t; \ 1474484Sbinkertn@umich.edu unsigned char *const _q = (unsigned char *) &_t; \ 1484484Sbinkertn@umich.edu const unsigned char *const _p = \ 1494484Sbinkertn@umich.edu (const unsigned char *) (P); \ 1504484Sbinkertn@umich.edu _q[0] = _p[0]; \ 1514484Sbinkertn@umich.edu _q[1] = _p[1]; \ 1524484Sbinkertn@umich.edu (P) = (P) + 2; \ 1534484Sbinkertn@umich.edu (X) = _t; \ 1544484Sbinkertn@umich.edu } while (0) 1554484Sbinkertn@umich.edu#define READ_WORD(P,X) do { \ 1564484Sbinkertn@umich.edu uint32_t _t; \ 1574484Sbinkertn@umich.edu unsigned char *const _q = (unsigned char *) &_t; \ 1584484Sbinkertn@umich.edu const unsigned char *const _p = \ 1594484Sbinkertn@umich.edu (const unsigned char *) (P); \ 1604484Sbinkertn@umich.edu _q[0] = _p[0]; \ 1614484Sbinkertn@umich.edu _q[1] = _p[1]; \ 1624484Sbinkertn@umich.edu _q[2] = _p[2]; \ 1634484Sbinkertn@umich.edu _q[3] = _p[3]; \ 1644484Sbinkertn@umich.edu (P) = (P) + 4; \ 1654484Sbinkertn@umich.edu (X) = _t; \ 1664484Sbinkertn@umich.edu } while (0) 1674484Sbinkertn@umich.edu#define READ_ADDR32(P,X) READ_WORD(P,X) 1684484Sbinkertn@umich.edu#define READ_OFF32(P,X) READ_WORD(P,X) 1694484Sbinkertn@umich.edu#define READ_SWORD(P,X) READ_WORD(P,X) 1704484Sbinkertn@umich.edu#define READ_WORD64(P,X) do { \ 1714484Sbinkertn@umich.edu uint64_t _t; \ 1724484Sbinkertn@umich.edu unsigned char *const _q = (unsigned char *) &_t; \ 1734484Sbinkertn@umich.edu const unsigned char *const _p = \ 1744484Sbinkertn@umich.edu (const unsigned char *) (P); \ 1754484Sbinkertn@umich.edu _q[0] = _p[0]; \ 1764484Sbinkertn@umich.edu _q[1] = _p[1]; \ 1774484Sbinkertn@umich.edu _q[2] = _p[2]; \ 1784484Sbinkertn@umich.edu _q[3] = _p[3]; \ 1794484Sbinkertn@umich.edu _q[4] = _p[4]; \ 1804484Sbinkertn@umich.edu _q[5] = _p[5]; \ 1814484Sbinkertn@umich.edu _q[6] = _p[6]; \ 1824484Sbinkertn@umich.edu _q[7] = _p[7]; \ 1834484Sbinkertn@umich.edu (P) = (P) + 8; \ 1844484Sbinkertn@umich.edu (X) = _t; \ 1854484Sbinkertn@umich.edu } while (0) 1864484Sbinkertn@umich.edu#define READ_ADDR64(P,X) READ_WORD64(P,X) 1874484Sbinkertn@umich.edu#define READ_LWORD(P,X) READ_WORD64(P,X) 1884484Sbinkertn@umich.edu#define READ_OFF64(P,X) READ_WORD64(P,X) 1894484Sbinkertn@umich.edu#define READ_SXWORD(P,X) READ_WORD64(P,X) 1904484Sbinkertn@umich.edu#define READ_XWORD(P,X) READ_WORD64(P,X) 1914484Sbinkertn@umich.edu#define READ_IDENT(P,X) do { \ 1924484Sbinkertn@umich.edu (void) memcpy((X), (P), sizeof((X))); \ 1934484Sbinkertn@umich.edu (P) = (P) + EI_NIDENT; \ 1944484Sbinkertn@umich.edu } while (0) 1954484Sbinkertn@umich.edu 1964484Sbinkertn@umich.edu#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) 1974484Sbinkertn@umich.edu 1984484Sbinkertn@umich.edudivert(-1) 1994484Sbinkertn@umich.edu 2004484Sbinkertn@umich.edu/* 2014484Sbinkertn@umich.edu * Generate conversion routines for converting between in-memory and 2024484Sbinkertn@umich.edu * file representations of Elf data structures. 2034484Sbinkertn@umich.edu * 2044484Sbinkertn@umich.edu * `In-memory' representations of an Elf data structure use natural 2054484Sbinkertn@umich.edu * alignments and native byte ordering. This allows arithmetic and 2064484Sbinkertn@umich.edu * casting to work as expected. On the other hand the `file' 2074484Sbinkertn@umich.edu * representation of an ELF data structure could be packed tighter 2084484Sbinkertn@umich.edu * than its `in-memory' representation, and could be of a differing 2094484Sbinkertn@umich.edu * byte order. An additional complication is that `ar' only pads data 2104484Sbinkertn@umich.edu * to even addresses and so ELF archive member data being read from 2114484Sbinkertn@umich.edu * inside an `ar' archive could end up at misaligned memory addresses. 2124484Sbinkertn@umich.edu * 2134484Sbinkertn@umich.edu * Consequently, casting the `char *' pointers that point to memory 2144484Sbinkertn@umich.edu * representations (i.e., source pointers for the *_tof() functions 2154484Sbinkertn@umich.edu * and the destination pointers for the *_tom() functions), is safe, 2164484Sbinkertn@umich.edu * as these pointers should be correctly aligned for the memory type 2174484Sbinkertn@umich.edu * already. However, pointers to file representations have to be 2184484Sbinkertn@umich.edu * treated as being potentially unaligned and no casting can be done. 2194484Sbinkertn@umich.edu */ 2204484Sbinkertn@umich.edu 2214484Sbinkertn@umich.eduinclude(SRCDIR`/elf_types.m4') 2224484Sbinkertn@umich.edu 2234484Sbinkertn@umich.edu/* 2244484Sbinkertn@umich.edu * `IGNORE'_* flags turn off generation of template code. 2254484Sbinkertn@umich.edu */ 2264484Sbinkertn@umich.edu 2274484Sbinkertn@umich.edudefine(`IGNORE', 2284484Sbinkertn@umich.edu `define(IGNORE_$1`'32, 1) 2294484Sbinkertn@umich.edu define(IGNORE_$1`'64, 1)') 2304484Sbinkertn@umich.edu 2314484Sbinkertn@umich.eduIGNORE(MOVEP) 2324484Sbinkertn@umich.eduIGNORE(NOTE) 2334484Sbinkertn@umich.edu 2344484Sbinkertn@umich.edudefine(IGNORE_BYTE, 1) /* 'lator, leave 'em bytes alone */ 2354484Sbinkertn@umich.edudefine(IGNORE_NOTE, 1) 2364484Sbinkertn@umich.edudefine(IGNORE_SXWORD32, 1) 2374484Sbinkertn@umich.edudefine(IGNORE_XWORD32, 1) 2384484Sbinkertn@umich.edu 2394484Sbinkertn@umich.edu/* 2404484Sbinkertn@umich.edu * `BASE'_XXX flags cause class agnostic template functions 2414484Sbinkertn@umich.edu * to be generated. 2424484Sbinkertn@umich.edu */ 2434484Sbinkertn@umich.edu 2444484Sbinkertn@umich.edudefine(`BASE_BYTE', 1) 2454484Sbinkertn@umich.edudefine(`BASE_HALF', 1) 2464484Sbinkertn@umich.edudefine(`BASE_NOTE', 1) 2474484Sbinkertn@umich.edudefine(`BASE_WORD', 1) 2484484Sbinkertn@umich.edudefine(`BASE_LWORD', 1) 2494484Sbinkertn@umich.edudefine(`BASE_SWORD', 1) 2504484Sbinkertn@umich.edudefine(`BASE_XWORD', 1) 2514484Sbinkertn@umich.edudefine(`BASE_SXWORD', 1) 2524484Sbinkertn@umich.edu 2534484Sbinkertn@umich.edu/* 2544484Sbinkertn@umich.edu * `SIZEDEP'_XXX flags cause 32/64 bit variants to be generated 2554484Sbinkertn@umich.edu * for each primitive type. 2564484Sbinkertn@umich.edu */ 2574484Sbinkertn@umich.edu 2584484Sbinkertn@umich.edudefine(`SIZEDEP_ADDR', 1) 2594484Sbinkertn@umich.edudefine(`SIZEDEP_OFF', 1) 2604484Sbinkertn@umich.edu 2614484Sbinkertn@umich.edu/* 2624484Sbinkertn@umich.edu * `Primitive' ELF types are those that are an alias for an integral 2634484Sbinkertn@umich.edu * type. They have no internal structure. These can be copied using 2644484Sbinkertn@umich.edu * a `memcpy()', and byteswapped in straightforward way. 2654484Sbinkertn@umich.edu * 2664484Sbinkertn@umich.edu * Macro use: 2674484Sbinkertn@umich.edu * `$1': Name of the ELF type. 2684484Sbinkertn@umich.edu * `$2': C structure name suffix 2694484Sbinkertn@umich.edu * `$3': ELF class specifier for symbols, one of [`', `32', `64'] 2704484Sbinkertn@umich.edu * `$4': ELF class specifier for types, one of [`32', `64'] 2714484Sbinkertn@umich.edu */ 2724484Sbinkertn@umich.edudefine(`MAKEPRIM_TO_F',` 2734484Sbinkertn@umich.edustatic void 2744484Sbinkertn@umich.edulibelf_cvt_$1$3_tof(char *dst, char *src, size_t count, int byteswap) 2754484Sbinkertn@umich.edu{ 2764484Sbinkertn@umich.edu Elf$4_$2 t, *s = (Elf$4_$2 *) (uintptr_t) src; 2774484Sbinkertn@umich.edu size_t c; 2784484Sbinkertn@umich.edu 2794484Sbinkertn@umich.edu if (dst == src && !byteswap) 2804484Sbinkertn@umich.edu return; 2814484Sbinkertn@umich.edu 2824484Sbinkertn@umich.edu if (!byteswap) { 2834484Sbinkertn@umich.edu (void) memcpy(dst, src, count * sizeof(*s)); 2844484Sbinkertn@umich.edu return; 2854484Sbinkertn@umich.edu } 2864484Sbinkertn@umich.edu 2874484Sbinkertn@umich.edu for (c = 0; c < count; c++) { 2884484Sbinkertn@umich.edu t = *s++; 2894484Sbinkertn@umich.edu SWAP_$1$3(t); 2904484Sbinkertn@umich.edu WRITE_$1$3(dst,t); 2914484Sbinkertn@umich.edu } 2924484Sbinkertn@umich.edu} 2934484Sbinkertn@umich.edu') 2944484Sbinkertn@umich.edu 2954484Sbinkertn@umich.edudefine(`MAKEPRIM_TO_M',` 2964484Sbinkertn@umich.edustatic void 2974484Sbinkertn@umich.edulibelf_cvt_$1$3_tom(char *dst, char *src, size_t count, int byteswap) 2984484Sbinkertn@umich.edu{ 2994484Sbinkertn@umich.edu Elf$4_$2 t, *d = (Elf$4_$2 *) (uintptr_t) dst; 3004484Sbinkertn@umich.edu size_t c; 3014484Sbinkertn@umich.edu 3024484Sbinkertn@umich.edu if (dst == src && !byteswap) 3034484Sbinkertn@umich.edu return; 3044484Sbinkertn@umich.edu 3054484Sbinkertn@umich.edu if (!byteswap) { 3064484Sbinkertn@umich.edu (void) memcpy(dst, src, count * sizeof(*d)); 3074484Sbinkertn@umich.edu return; 3084484Sbinkertn@umich.edu } 3094484Sbinkertn@umich.edu 3104484Sbinkertn@umich.edu for (c = 0; c < count; c++) { 3114484Sbinkertn@umich.edu READ_$1$3(src,t); 3124484Sbinkertn@umich.edu SWAP_$1$3(t); 3134484Sbinkertn@umich.edu *d++ = t; 3144484Sbinkertn@umich.edu } 3154484Sbinkertn@umich.edu} 3164484Sbinkertn@umich.edu') 3174484Sbinkertn@umich.edu 3184484Sbinkertn@umich.edudefine(`SWAP_FIELD', 3194484Sbinkertn@umich.edu `ifdef(`IGNORE_'$2,`', 3204484Sbinkertn@umich.edu `ifelse(BASE_$2,1, 3214484Sbinkertn@umich.edu `SWAP_$2(t.$1); 3224484Sbinkertn@umich.edu ', 3234484Sbinkertn@umich.edu `ifelse($2,BYTE,`', 3244484Sbinkertn@umich.edu `ifelse($2,IDENT,`', 3254484Sbinkertn@umich.edu `SWAP_$2'SZ()`(t.$1); 3264484Sbinkertn@umich.edu ')')')')') 3274484Sbinkertn@umich.edudefine(`SWAP_MEMBERS', 3284484Sbinkertn@umich.edu `ifelse($#,1,`/**/', 3294484Sbinkertn@umich.edu `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')') 3304484Sbinkertn@umich.edu 3314484Sbinkertn@umich.edudefine(`SWAP_STRUCT', 3324484Sbinkertn@umich.edu `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */ 3334484Sbinkertn@umich.edu SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') 3344484Sbinkertn@umich.edu 3354484Sbinkertn@umich.edudefine(`WRITE_FIELD', 3364484Sbinkertn@umich.edu `ifelse(BASE_$2,1, 3374484Sbinkertn@umich.edu `WRITE_$2(dst,t.$1); 3384484Sbinkertn@umich.edu ', 3394484Sbinkertn@umich.edu `ifelse($2,IDENT, 3404484Sbinkertn@umich.edu `WRITE_$2(dst,t.$1); 3414484Sbinkertn@umich.edu ', 3424484Sbinkertn@umich.edu `WRITE_$2'SZ()`(dst,t.$1); 3434484Sbinkertn@umich.edu ')')') 3444484Sbinkertn@umich.edudefine(`WRITE_MEMBERS', 3454484Sbinkertn@umich.edu `ifelse($#,1,`/**/', 3464484Sbinkertn@umich.edu `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')') 3474484Sbinkertn@umich.edu 3484484Sbinkertn@umich.edudefine(`WRITE_STRUCT', 3494484Sbinkertn@umich.edu `pushdef(`SZ',$2)/* Write an Elf$2_$1 */ 3504484Sbinkertn@umich.edu WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') 3514484Sbinkertn@umich.edu 3524484Sbinkertn@umich.edudefine(`READ_FIELD', 3534484Sbinkertn@umich.edu `ifelse(BASE_$2,1, 3544484Sbinkertn@umich.edu `READ_$2(s,t.$1); 3554484Sbinkertn@umich.edu ', 3564484Sbinkertn@umich.edu `ifelse($2,IDENT, 3574484Sbinkertn@umich.edu `READ_$2(s,t.$1); 3584484Sbinkertn@umich.edu ', 3594484Sbinkertn@umich.edu `READ_$2'SZ()`(s,t.$1); 3604484Sbinkertn@umich.edu ')')') 3614484Sbinkertn@umich.edu 3624484Sbinkertn@umich.edudefine(`READ_MEMBERS', 3634484Sbinkertn@umich.edu `ifelse($#,1,`/**/', 3644484Sbinkertn@umich.edu `READ_FIELD($1)READ_MEMBERS(shift($@))')') 3654484Sbinkertn@umich.edu 3664484Sbinkertn@umich.edudefine(`READ_STRUCT', 3674484Sbinkertn@umich.edu `pushdef(`SZ',$2)/* Read an Elf$2_$1 */ 3684484Sbinkertn@umich.edu READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') 3694484Sbinkertn@umich.edu 3704484Sbinkertn@umich.edu/* 3714484Sbinkertn@umich.edu * Converters for non-integral ELF data structures. 3724484Sbinkertn@umich.edu * 3734484Sbinkertn@umich.edu * When converting data to file representation, the source pointer 3744484Sbinkertn@umich.edu * will be naturally aligned for a data structure's in-memory 3754484Sbinkertn@umich.edu * representation. When converting data to memory, the destination 3764484Sbinkertn@umich.edu * pointer will be similarly aligned. 3774484Sbinkertn@umich.edu * 3784484Sbinkertn@umich.edu * For in-place conversions, when converting to file representations, 3794484Sbinkertn@umich.edu * the source buffer is large enough to hold `file' data. When 3804484Sbinkertn@umich.edu * converting from file to memory, we need to be careful to work 3814484Sbinkertn@umich.edu * `backwards', to avoid overwriting unconverted data. 3824484Sbinkertn@umich.edu * 3834484Sbinkertn@umich.edu * Macro use: 3844484Sbinkertn@umich.edu * `$1': Name of the ELF type. 3854484Sbinkertn@umich.edu * `$2': C structure name suffix. 3864484Sbinkertn@umich.edu * `$3': ELF class specifier, one of [`', `32', `64'] 3874484Sbinkertn@umich.edu */ 3884484Sbinkertn@umich.edu 3894484Sbinkertn@umich.edudefine(`MAKE_TO_F', 3904484Sbinkertn@umich.edu `ifdef(`IGNORE_'$1$3,`',` 3914484Sbinkertn@umich.edustatic void 3924484Sbinkertn@umich.edulibelf_cvt$3_$1_tof(char *dst, char *src, size_t count, int byteswap) 3934484Sbinkertn@umich.edu{ 3944484Sbinkertn@umich.edu Elf$3_$2 t, *s; 3954484Sbinkertn@umich.edu size_t c; 3964484Sbinkertn@umich.edu 3974484Sbinkertn@umich.edu s = (Elf$3_$2 *) (uintptr_t) src; 3984484Sbinkertn@umich.edu for (c = 0; c < count; c++) { 3994484Sbinkertn@umich.edu t = *s++; 4004484Sbinkertn@umich.edu if (byteswap) { 4014484Sbinkertn@umich.edu SWAP_STRUCT($2,$3) 4024484Sbinkertn@umich.edu } 4034484Sbinkertn@umich.edu WRITE_STRUCT($2,$3) 4044484Sbinkertn@umich.edu } 4054484Sbinkertn@umich.edu} 4064484Sbinkertn@umich.edu')') 4074484Sbinkertn@umich.edu 4084484Sbinkertn@umich.edudefine(`MAKE_TO_M', 4094484Sbinkertn@umich.edu `ifdef(`IGNORE_'$1$3,`',` 4104484Sbinkertn@umich.edustatic void 4114484Sbinkertn@umich.edulibelf_cvt$3_$1_tom(char *dst, char *src, size_t count, int byteswap) 4124484Sbinkertn@umich.edu{ 4134484Sbinkertn@umich.edu Elf$3_$2 t, *d; 4144484Sbinkertn@umich.edu unsigned char *s,*s0; 4154484Sbinkertn@umich.edu size_t fsz; 4164484Sbinkertn@umich.edu 4174484Sbinkertn@umich.edu fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT); 4184484Sbinkertn@umich.edu d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1); 4194484Sbinkertn@umich.edu s0 = (unsigned char *) src + (count - 1) * fsz; 4204484Sbinkertn@umich.edu 4214484Sbinkertn@umich.edu while (count--) { 4224484Sbinkertn@umich.edu s = s0; 4234484Sbinkertn@umich.edu READ_STRUCT($2,$3) 4244484Sbinkertn@umich.edu if (byteswap) { 4254484Sbinkertn@umich.edu SWAP_STRUCT($2,$3) 4264484Sbinkertn@umich.edu } 4274484Sbinkertn@umich.edu *d-- = t; s0 -= fsz; 4284484Sbinkertn@umich.edu } 4294484Sbinkertn@umich.edu} 4304484Sbinkertn@umich.edu')') 4314484Sbinkertn@umich.edu 4324484Sbinkertn@umich.edu/* 4334484Sbinkertn@umich.edu * Make type convertor functions from the type definition 4344484Sbinkertn@umich.edu * of the ELF type: 4354484Sbinkertn@umich.edu * - if the type is a base (i.e., `primitive') type: 4364484Sbinkertn@umich.edu * - if it is marked as to be ignored (i.e., `IGNORE_'TYPE) 4374484Sbinkertn@umich.edu * is defined, we skip the code generation step. 4384484Sbinkertn@umich.edu * - if the type is declared as `SIZEDEP', then 32 and 64 bit 4394484Sbinkertn@umich.edu * variants of the conversion functions are generated. 4404484Sbinkertn@umich.edu * - otherwise a 32 bit variant is generated. 4414484Sbinkertn@umich.edu * - if the type is a structure type, we generate 32 and 64 bit 4424484Sbinkertn@umich.edu * variants of the conversion functions. 4434484Sbinkertn@umich.edu */ 4444484Sbinkertn@umich.edu 4454484Sbinkertn@umich.edudefine(`MAKE_TYPE_CONVERTER', 4464484Sbinkertn@umich.edu `ifdef(`BASE'_$1, 4474484Sbinkertn@umich.edu `ifdef(`IGNORE_'$1,`', 4484484Sbinkertn@umich.edu `MAKEPRIM_TO_F($1,$2,`',64) 4494484Sbinkertn@umich.edu MAKEPRIM_TO_M($1,$2,`',64)')', 4504484Sbinkertn@umich.edu `ifdef(`SIZEDEP_'$1, 4514484Sbinkertn@umich.edu `MAKEPRIM_TO_F($1,$2,32,32)dnl 4524484Sbinkertn@umich.edu MAKEPRIM_TO_M($1,$2,32,32)dnl 4534484Sbinkertn@umich.edu MAKEPRIM_TO_F($1,$2,64,64)dnl 4544484Sbinkertn@umich.edu MAKEPRIM_TO_M($1,$2,64,64)', 4554484Sbinkertn@umich.edu `MAKE_TO_F($1,$2,32)dnl 4564484Sbinkertn@umich.edu MAKE_TO_F($1,$2,64)dnl 4574484Sbinkertn@umich.edu MAKE_TO_M($1,$2,32)dnl 4584484Sbinkertn@umich.edu MAKE_TO_M($1,$2,64)')') 4594484Sbinkertn@umich.edu') 4604484Sbinkertn@umich.edu 4614484Sbinkertn@umich.edudefine(`MAKE_TYPE_CONVERTERS', 4624484Sbinkertn@umich.edu `ifelse($#,1,`', 4634484Sbinkertn@umich.edu `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')') 4644484Sbinkertn@umich.edu 4654484Sbinkertn@umich.edudivert(0) 4664484Sbinkertn@umich.edu 4674484Sbinkertn@umich.edu/* 4684484Sbinkertn@umich.edu * Sections of type ELF_T_BYTE are never byteswapped, consequently a 4694484Sbinkertn@umich.edu * simple memcpy suffices for both directions of conversion. 4704484Sbinkertn@umich.edu */ 4714484Sbinkertn@umich.edu 4724484Sbinkertn@umich.edustatic void 4734484Sbinkertn@umich.edulibelf_cvt_BYTE_tox(char *dst, char *src, size_t count, int byteswap) 4744484Sbinkertn@umich.edu{ 4754484Sbinkertn@umich.edu (void) byteswap; 4764484Sbinkertn@umich.edu if (dst != src) 4774484Sbinkertn@umich.edu (void) memcpy(dst, src, count); 4784484Sbinkertn@umich.edu} 4794484Sbinkertn@umich.edu 4804484Sbinkertn@umich.edu/* 4814484Sbinkertn@umich.edu * Elf_Note structures comprise a fixed size header followed by variable 4824484Sbinkertn@umich.edu * length strings. The fixed size header needs to be byte swapped, but 4834484Sbinkertn@umich.edu * not the strings. 4844484Sbinkertn@umich.edu * 4854484Sbinkertn@umich.edu * Argument `count' denotes the total number of bytes to be converted. 4864484Sbinkertn@umich.edu */ 4874484Sbinkertn@umich.edustatic void 4884484Sbinkertn@umich.edulibelf_cvt_NOTE_tom(char *dst, char *src, size_t count, int byteswap) 4894484Sbinkertn@umich.edu{ 4904484Sbinkertn@umich.edu uint32_t namesz, descsz, type; 4914484Sbinkertn@umich.edu Elf_Note *en; 4924484Sbinkertn@umich.edu size_t sz; 4934484Sbinkertn@umich.edu 4944484Sbinkertn@umich.edu if (dst == src && !byteswap) 4954484Sbinkertn@umich.edu return; 4964484Sbinkertn@umich.edu 4974484Sbinkertn@umich.edu if (!byteswap) { 4984484Sbinkertn@umich.edu (void) memcpy(dst, src, count); 4994484Sbinkertn@umich.edu return; 5004484Sbinkertn@umich.edu } 5014484Sbinkertn@umich.edu 5024484Sbinkertn@umich.edu while (count > sizeof(Elf_Note)) { 5034484Sbinkertn@umich.edu 5044484Sbinkertn@umich.edu READ_WORD(src, namesz); 5054484Sbinkertn@umich.edu READ_WORD(src, descsz); 5064484Sbinkertn@umich.edu READ_WORD(src, type); 5074484Sbinkertn@umich.edu 5084484Sbinkertn@umich.edu if (byteswap) { 5094484Sbinkertn@umich.edu SWAP_WORD(namesz); 5104484Sbinkertn@umich.edu SWAP_WORD(descsz); 5114484Sbinkertn@umich.edu SWAP_WORD(type); 5124484Sbinkertn@umich.edu } 5134484Sbinkertn@umich.edu 5144484Sbinkertn@umich.edu en = (Elf_Note *) (uintptr_t) dst; 5154484Sbinkertn@umich.edu en->n_namesz = namesz; 5164484Sbinkertn@umich.edu en->n_descsz = descsz; 5174484Sbinkertn@umich.edu en->n_type = type; 5184484Sbinkertn@umich.edu 5194484Sbinkertn@umich.edu dst += sizeof(Elf_Note); 5204484Sbinkertn@umich.edu 5214484Sbinkertn@umich.edu ROUNDUP2(namesz, 4); 5224484Sbinkertn@umich.edu ROUNDUP2(descsz, 4); 5234484Sbinkertn@umich.edu 5244484Sbinkertn@umich.edu sz = namesz + descsz; 5254484Sbinkertn@umich.edu 5264484Sbinkertn@umich.edu if (count < sz) 5274484Sbinkertn@umich.edu sz = count; 5284484Sbinkertn@umich.edu 5294484Sbinkertn@umich.edu (void) memcpy(dst, src, sz); 5304484Sbinkertn@umich.edu 5314484Sbinkertn@umich.edu src += sz; 5324484Sbinkertn@umich.edu dst += sz; 5334484Sbinkertn@umich.edu count -= sz; 5344484Sbinkertn@umich.edu } 5354484Sbinkertn@umich.edu} 5364484Sbinkertn@umich.edu 5374484Sbinkertn@umich.edustatic void 5384484Sbinkertn@umich.edulibelf_cvt_NOTE_tof(char *dst, char *src, size_t count, int byteswap) 5394484Sbinkertn@umich.edu{ 5404484Sbinkertn@umich.edu uint32_t namesz, descsz, type; 5414484Sbinkertn@umich.edu Elf_Note *en; 5424484Sbinkertn@umich.edu size_t sz; 5434484Sbinkertn@umich.edu 5444484Sbinkertn@umich.edu if (dst == src && !byteswap) 5454484Sbinkertn@umich.edu return; 5464484Sbinkertn@umich.edu 5474484Sbinkertn@umich.edu if (!byteswap) { 5484484Sbinkertn@umich.edu (void) memcpy(dst, src, count); 5494484Sbinkertn@umich.edu return; 5504484Sbinkertn@umich.edu } 5514484Sbinkertn@umich.edu 5524484Sbinkertn@umich.edu while (count > sizeof(Elf_Note)) { 5534484Sbinkertn@umich.edu 5544484Sbinkertn@umich.edu en = (Elf_Note *) (uintptr_t) src; 5554484Sbinkertn@umich.edu namesz = en->n_namesz; 5564484Sbinkertn@umich.edu descsz = en->n_descsz; 5574484Sbinkertn@umich.edu type = en->n_type; 5584484Sbinkertn@umich.edu 5594484Sbinkertn@umich.edu if (byteswap) { 5604484Sbinkertn@umich.edu SWAP_WORD(namesz); 5614484Sbinkertn@umich.edu SWAP_WORD(descsz); 5624484Sbinkertn@umich.edu SWAP_WORD(type); 5634484Sbinkertn@umich.edu } 5644484Sbinkertn@umich.edu 5654484Sbinkertn@umich.edu 5664484Sbinkertn@umich.edu WRITE_WORD(dst, namesz); 5674484Sbinkertn@umich.edu WRITE_WORD(dst, descsz); 5684484Sbinkertn@umich.edu WRITE_WORD(dst, type); 5694484Sbinkertn@umich.edu 5704484Sbinkertn@umich.edu src += sizeof(Elf_Note); 5714484Sbinkertn@umich.edu 5724484Sbinkertn@umich.edu ROUNDUP2(namesz, 4); 5734484Sbinkertn@umich.edu ROUNDUP2(descsz, 4); 5744484Sbinkertn@umich.edu 5754484Sbinkertn@umich.edu sz = namesz + descsz; 5764484Sbinkertn@umich.edu 5774484Sbinkertn@umich.edu if (count < sz) 5784484Sbinkertn@umich.edu sz = count; 5794484Sbinkertn@umich.edu 5804484Sbinkertn@umich.edu (void) memcpy(dst, src, sz); 5814484Sbinkertn@umich.edu 5824484Sbinkertn@umich.edu src += sz; 5834484Sbinkertn@umich.edu dst += sz; 5844484Sbinkertn@umich.edu count -= sz; 5854484Sbinkertn@umich.edu } 5864484Sbinkertn@umich.edu} 5874484Sbinkertn@umich.edu 5884484Sbinkertn@umich.eduMAKE_TYPE_CONVERTERS(ELF_TYPE_LIST) 5894484Sbinkertn@umich.edu 5904484Sbinkertn@umich.edustruct converters { 5914484Sbinkertn@umich.edu void (*tof32)(char *dst, char *src, size_t cnt, int byteswap); 5924484Sbinkertn@umich.edu void (*tom32)(char *dst, char *src, size_t cnt, int byteswap); 5934484Sbinkertn@umich.edu void (*tof64)(char *dst, char *src, size_t cnt, int byteswap); 5944484Sbinkertn@umich.edu void (*tom64)(char *dst, char *src, size_t cnt, int byteswap); 5954484Sbinkertn@umich.edu}; 5964484Sbinkertn@umich.edu 5974484Sbinkertn@umich.edudivert(-1) 5984484Sbinkertn@umich.edudefine(`CONV', 5994484Sbinkertn@umich.edu `ifdef(`IGNORE_'$1$2, 6004484Sbinkertn@umich.edu `.$3$2 = NULL', 6014484Sbinkertn@umich.edu `ifdef(`BASE_'$1, 6024484Sbinkertn@umich.edu `ifdef(`IGNORE_'$1, 6034484Sbinkertn@umich.edu `.$3$2 = NULL', 6044484Sbinkertn@umich.edu `.$3$2 = libelf_cvt_$1_$3')', 6054484Sbinkertn@umich.edu `ifdef(`SIZEDEP_'$1, 6064484Sbinkertn@umich.edu `.$3$2 = libelf_cvt_$1$2_$3', 6074484Sbinkertn@umich.edu `.$3$2 = libelf_cvt$2_$1_$3')')')') 6084484Sbinkertn@umich.edu 6094484Sbinkertn@umich.edudefine(`CONVERTER_NAME', 6104484Sbinkertn@umich.edu `[ELF_T_$1] = { 6114484Sbinkertn@umich.edu CONV($1,32,tof), CONV($1,32,tom), 6124484Sbinkertn@umich.edu CONV($1,64,tof), CONV($1,64,tom) },')') 6134484Sbinkertn@umich.edu 6144484Sbinkertn@umich.edudefine(`CONVERTER_NAMES', 6154484Sbinkertn@umich.edu `ifelse($#,1,`', 6164484Sbinkertn@umich.edu `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')') 6174484Sbinkertn@umich.edu 6184484Sbinkertn@umich.eduundefine(`IGNORE_BYTE32') 6194484Sbinkertn@umich.eduundefine(`IGNORE_BYTE64') 6204484Sbinkertn@umich.edudivert(0) 6214484Sbinkertn@umich.edu 6224484Sbinkertn@umich.edustatic struct converters cvt[ELF_T_NUM] = { 6234484Sbinkertn@umich.eduCONVERTER_NAMES(ELF_TYPE_LIST) 6244484Sbinkertn@umich.edu 6254484Sbinkertn@umich.edu /* 6264484Sbinkertn@umich.edu * Types that needs hand-coded converters follow. 6274484Sbinkertn@umich.edu */ 6284484Sbinkertn@umich.edu 6294484Sbinkertn@umich.edu [ELF_T_BYTE] = { 6304484Sbinkertn@umich.edu .tof32 = libelf_cvt_BYTE_tox, 6314484Sbinkertn@umich.edu .tom32 = libelf_cvt_BYTE_tox, 6324484Sbinkertn@umich.edu .tof64 = libelf_cvt_BYTE_tox, 6334484Sbinkertn@umich.edu .tom64 = libelf_cvt_BYTE_tox 6344484Sbinkertn@umich.edu }, 6354484Sbinkertn@umich.edu [ELF_T_NOTE] = { 6364484Sbinkertn@umich.edu .tof32 = libelf_cvt_NOTE_tof, 6374484Sbinkertn@umich.edu .tom32 = libelf_cvt_NOTE_tom, 6384484Sbinkertn@umich.edu .tof64 = libelf_cvt_NOTE_tof, 6394484Sbinkertn@umich.edu .tom64 = libelf_cvt_NOTE_tom 6404484Sbinkertn@umich.edu } 6414484Sbinkertn@umich.edu}; 6424484Sbinkertn@umich.edu 6434484Sbinkertn@umich.eduvoid (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) 6444484Sbinkertn@umich.edu (char *_dst, char *_src, size_t _cnt, int _byteswap) 6454484Sbinkertn@umich.edu{ 6464484Sbinkertn@umich.edu assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); 6474484Sbinkertn@umich.edu assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); 6484484Sbinkertn@umich.edu 6494484Sbinkertn@umich.edu if (t >= ELF_T_NUM || 6504484Sbinkertn@umich.edu (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) || 6514484Sbinkertn@umich.edu (direction != ELF_TOFILE && direction != ELF_TOMEMORY)) 6524484Sbinkertn@umich.edu return (NULL); 6534484Sbinkertn@umich.edu 6544484Sbinkertn@umich.edu return ((elfclass == ELFCLASS32) ? 6554484Sbinkertn@umich.edu (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : 6564484Sbinkertn@umich.edu (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); 6574484Sbinkertn@umich.edu} 658