summaryrefslogtreecommitdiffstats
path: root/linkers/elftoolchain/libelf/libelf_convert.m4
diff options
context:
space:
mode:
Diffstat (limited to 'linkers/elftoolchain/libelf/libelf_convert.m4')
-rw-r--r--linkers/elftoolchain/libelf/libelf_convert.m41086
1 files changed, 0 insertions, 1086 deletions
diff --git a/linkers/elftoolchain/libelf/libelf_convert.m4 b/linkers/elftoolchain/libelf/libelf_convert.m4
deleted file mode 100644
index 9b1679a..0000000
--- a/linkers/elftoolchain/libelf/libelf_convert.m4
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*-
- * Copyright (c) 2006-2011 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.
- */
-
-#include <sys/cdefs.h>
-
-#include <assert.h>
-#include <libelf.h>
-#include <string.h>
-
-#include "_libelf.h"
-
-LIBELF_VCSID("$Id: libelf_convert.m4 1734 2011-08-16 09:55:07Z jkoshy $");
-
-/* WARNING: GENERATED FROM __file__. */
-
-divert(-1)
-
-# Generate conversion routines for converting between in-memory and
-# file representations of Elf data structures.
-#
-# These conversions use the type information defined in `elf_types.m4'.
-
-include(SRCDIR`/elf_types.m4')
-
-# For the purposes of generating conversion code, ELF types may be
-# classified according to the following characteristics:
-#
-# 1. Whether the ELF type can be directly mapped to an integral C
-# language type. For example, the ELF_T_WORD type maps directly to
-# a 'uint32_t', but ELF_T_GNUHASH lacks a matching C type.
-#
-# 2. Whether the type has word size dependent variants. For example,
-# ELT_T_EHDR is represented using C types Elf32_Ehdr and El64_Ehdr,
-# and the ELF_T_ADDR and ELF_T_OFF types have integral C types that
-# can be 32- or 64- bit wide.
-#
-# 3. Whether the ELF types has a fixed representation or not. For
-# example, the ELF_T_SYM type has a fixed size file representation,
-# some types like ELF_T_NOTE and ELF_T_GNUHASH use a variable size
-# representation.
-#
-# We use m4 macros to generate conversion code for ELF types that have
-# a fixed size representation. Conversion functions for the remaining
-# types are coded by hand.
-#
-#* Handling File and Memory Representations
-#
-# `In-memory' representations of an Elf data structure use natural
-# alignments and native byte ordering. This allows pointer arithmetic
-# and casting to work as expected. On the other hand, the `file'
-# representation of an ELF data structure could possibly be packed
-# tighter than its `in-memory' representation, and could be of a
-# differing byte order. Reading ELF objects that are members of `ar'
-# archives present an additional complication: `ar' pads file data to
-# even addresses, so file data structures in an archive member
-# residing inside an `ar' archive could be at misaligned memory
-# addresses when brought into memory.
-#
-# In summary, casting the `char *' pointers that point to memory
-# representations (i.e., source pointers for the *_tof() functions and
-# the destination pointers for the *_tom() functions), is safe, as
-# these pointers should be correctly aligned for the memory type
-# already. However, pointers to file representations have to be
-# treated as being potentially unaligned and no casting can be done.
-
-# NOCVT(TYPE) -- Do not generate the cvt[] structure entry for TYPE
-define(`NOCVT',`define(`NOCVT_'$1,1)')
-
-# NOFUNC(TYPE) -- Do not generate a conversion function for TYPE
-define(`NOFUNC',`define(`NOFUNC_'$1,1)')
-
-# IGNORE(TYPE) -- Completely ignore the type.
-define(`IGNORE',`NOCVT($1)NOFUNC($1)')
-
-# Mark ELF types that should not be processed by the M4 macros below.
-
-# Types for which we use functions with non-standard names.
-IGNORE(`BYTE') # Uses a wrapper around memcpy().
-IGNORE(`NOTE') # Not a fixed size type.
-
-# Types for which we supply hand-coded functions.
-NOFUNC(`GNUHASH') # A type with complex internal structure.
-NOFUNC(`VDEF') # See MAKE_VERSION_CONVERTERS below.
-NOFUNC(`VNEED') # ..
-
-# Unimplemented types.
-IGNORE(`MOVEP')
-
-# ELF types that don't exist in a 32-bit world.
-NOFUNC(`XWORD32')
-NOFUNC(`SXWORD32')
-
-# `Primitive' ELF types are those that are an alias for an integral
-# type. As they have no internal structure, they can be copied using
-# a `memcpy()', and byteswapped in straightforward way.
-#
-# Mark all ELF types that directly map to integral C types.
-define(`PRIM_ADDR', 1)
-define(`PRIM_BYTE', 1)
-define(`PRIM_HALF', 1)
-define(`PRIM_LWORD', 1)
-define(`PRIM_OFF', 1)
-define(`PRIM_SWORD', 1)
-define(`PRIM_SXWORD', 1)
-define(`PRIM_WORD', 1)
-define(`PRIM_XWORD', 1)
-
-# Note the primitive types that are size-dependent.
-define(`SIZEDEP_ADDR', 1)
-define(`SIZEDEP_OFF', 1)
-
-# Generate conversion functions for primitive types.
-#
-# Macro use: MAKEPRIMFUNCS(ELFTYPE,CTYPE,TYPESIZE,SYMSIZE)
-# `$1': Name of the ELF type.
-# `$2': C structure name suffix.
-# `$3': ELF class specifier for types, one of [`32', `64'].
-# `$4': Additional ELF class specifier, one of [`', `32', `64'].
-#
-# Generates a pair of conversion functions.
-define(`MAKEPRIMFUNCS',`
-static int
-libelf_cvt_$1$4_tof(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- Elf$3_$2 t, *s = (Elf$3_$2 *) (uintptr_t) src;
- size_t c;
-
- (void) dsz;
-
- if (!byteswap) {
- (void) memcpy(dst, src, count * sizeof(*s));
- return (1);
- }
-
- for (c = 0; c < count; c++) {
- t = *s++;
- SWAP_$1$4(t);
- WRITE_$1$4(dst,t);
- }
-
- return (1);
-}
-
-static int
-libelf_cvt_$1$4_tom(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- Elf$3_$2 t, *d = (Elf$3_$2 *) (uintptr_t) dst;
- size_t c;
-
- if (dsz < count * sizeof(Elf$3_$2))
- return (0);
-
- if (!byteswap) {
- (void) memcpy(dst, src, count * sizeof(*d));
- return (1);
- }
-
- for (c = 0; c < count; c++) {
- READ_$1$4(src,t);
- SWAP_$1$4(t);
- *d++ = t;
- }
-
- return (1);
-}
-')
-
-#
-# Handling composite ELF types
-#
-
-# SWAP_FIELD(FIELDNAME,ELFTYPE) -- Generate code to swap one field.
-define(`SWAP_FIELD',
- `ifdef(`SIZEDEP_'$2,
- `SWAP_$2'SZ()`(t.$1);
- ',
- `SWAP_$2(t.$1);
- ')')
-
-# SWAP_MEMBERS(STRUCT) -- Iterate over a structure definition.
-define(`SWAP_MEMBERS',
- `ifelse($#,1,`/**/',
- `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')')
-
-# SWAP_STRUCT(CTYPE,SIZE) -- Generate code to swap an ELF structure.
-define(`SWAP_STRUCT',
- `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */
- SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')')
-
-# WRITE_FIELD(ELFTYPE,FIELDNAME) -- Generate code to write one field.
-define(`WRITE_FIELD',
- `ifdef(`SIZEDEP_'$2,
- `WRITE_$2'SZ()`(dst,t.$1);
- ',
- `WRITE_$2(dst,t.$1);
- ')')
-
-# WRITE_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition.
-define(`WRITE_MEMBERS',
- `ifelse($#,1,`/**/',
- `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')')
-
-# WRITE_STRUCT(CTYPE,SIZE) -- Generate code to write out an ELF structure.
-define(`WRITE_STRUCT',
- `pushdef(`SZ',$2)/* Write an Elf$2_$1 */
- WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')')
-
-# READ_FIELD(ELFTYPE,CTYPE) -- Generate code to read one field.
-define(`READ_FIELD',
- `ifdef(`SIZEDEP_'$2,
- `READ_$2'SZ()`(s,t.$1);
- ',
- `READ_$2(s,t.$1);
- ')')
-
-# READ_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition.
-define(`READ_MEMBERS',
- `ifelse($#,1,`/**/',
- `READ_FIELD($1)READ_MEMBERS(shift($@))')')
-
-# READ_STRUCT(CTYPE,SIZE) -- Generate code to read an ELF structure.
-define(`READ_STRUCT',
- `pushdef(`SZ',$2)/* Read an Elf$2_$1 */
- READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')')
-
-
-# MAKECOMPFUNCS -- Generate converters for composite ELF structures.
-#
-# When converting data to file representation, the source pointer will
-# be naturally aligned for a data structure's in-memory
-# representation. When converting data to memory, the destination
-# pointer will be similarly aligned.
-#
-# For in-place conversions, when converting to file representations,
-# the source buffer is large enough to hold `file' data. When
-# converting from file to memory, we need to be careful to work
-# `backwards', to avoid overwriting unconverted data.
-#
-# Macro use:
-# `$1': Name of the ELF type.
-# `$2': C structure name suffix.
-# `$3': ELF class specifier, one of [`', `32', `64']
-define(`MAKECOMPFUNCS', `ifdef(`NOFUNC_'$1$3,`',`
-static int
-libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- Elf$3_$2 t, *s;
- size_t c;
-
- (void) dsz;
-
- s = (Elf$3_$2 *) (uintptr_t) src;
- for (c = 0; c < count; c++) {
- t = *s++;
- if (byteswap) {
- SWAP_STRUCT($2,$3)
- }
- WRITE_STRUCT($2,$3)
- }
-
- return (1);
-}
-
-static int
-libelf_cvt_$1$3_tom(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- Elf$3_$2 t, *d;
- char *s,*s0;
- size_t fsz;
-
- fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT);
- d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1);
- s0 = (char *) src + (count - 1) * fsz;
-
- if (dsz < count * sizeof(Elf$3_$2))
- return (0);
-
- while (count--) {
- s = s0;
- READ_STRUCT($2,$3)
- if (byteswap) {
- SWAP_STRUCT($2,$3)
- }
- *d-- = t; s0 -= fsz;
- }
-
- return (1);
-}
-')')
-
-# MAKE_TYPE_CONVERTER(ELFTYPE,CTYPE)
-#
-# Make type convertor functions from the type definition
-# of the ELF type:
-# - Skip convertors marked as `NOFUNC'.
-# - Invoke `MAKEPRIMFUNCS' or `MAKECOMPFUNCS' as appropriate.
-define(`MAKE_TYPE_CONVERTER',
- `ifdef(`NOFUNC_'$1,`',
- `ifdef(`PRIM_'$1,
- `ifdef(`SIZEDEP_'$1,
- `MAKEPRIMFUNCS($1,$2,32,32)dnl
- MAKEPRIMFUNCS($1,$2,64,64)',
- `MAKEPRIMFUNCS($1,$2,64)')',
- `MAKECOMPFUNCS($1,$2,32)dnl
- MAKECOMPFUNCS($1,$2,64)')')')
-
-# MAKE_TYPE_CONVERTERS(ELFTYPELIST) -- Generate conversion functions.
-define(`MAKE_TYPE_CONVERTERS',
- `ifelse($#,1,`',
- `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')')
-
-
-#
-# Macros to generate entries for the table of convertors.
-#
-
-# CONV(ELFTYPE,SIZE,DIRECTION)
-#
-# Generate the name of a convertor function.
-define(`CONV',
- `ifdef(`NOFUNC_'$1$2,
- `.$3$2 = NULL',
- `ifdef(`PRIM_'$1,
- `ifdef(`SIZEDEP_'$1,
- `.$3$2 = libelf_cvt_$1$2_$3',
- `.$3$2 = libelf_cvt_$1_$3')',
- `.$3$2 = libelf_cvt_$1$2_$3')')')
-
-# CONVERTER_NAME(ELFTYPE)
-#
-# Generate the contents of one `struct cvt' instance.
-define(`CONVERTER_NAME',
- `ifdef(`NOCVT_'$1,`',
- ` [ELF_T_$1] = {
- CONV($1,32,tof),
- CONV($1,32,tom),
- CONV($1,64,tof),
- CONV($1,64,tom)
- },
-
-')')
-
-# CONVERTER_NAMES(ELFTYPELIST)
-#
-# Generate the `struct cvt[]' array.
-define(`CONVERTER_NAMES',
- `ifelse($#,1,`',
- `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')')
-
-#
-# Handling ELF version sections.
-#
-
-# _FSZ(FIELD,BASETYPE) - return the file size for a field.
-define(`_FSZ',
- `ifelse($2,`HALF',2,
- $2,`WORD',4)')
-
-# FSZ(STRUCT) - determine the file size of a structure.
-define(`FSZ',
- `ifelse($#,1,0,
- `eval(_FSZ($1) + FSZ(shift($@)))')')
-
-# MAKE_VERSION_CONVERTERS(TYPE,BASE,AUX,PFX) -- Generate conversion
-# functions for versioning structures.
-define(`MAKE_VERSION_CONVERTERS',
- `MAKE_VERSION_CONVERTER($1,$2,$3,$4,32)
- MAKE_VERSION_CONVERTER($1,$2,$3,$4,64)')
-
-# MAKE_VERSION_CONVERTOR(TYPE,CBASE,CAUX,PFX,SIZE) -- Generate a
-# conversion function.
-define(`MAKE_VERSION_CONVERTER',`
-static int
-libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- Elf$5_$2 t;
- Elf$5_$3 a;
- const size_t verfsz = FSZ(Elf$5_$2_DEF);
- const size_t auxfsz = FSZ(Elf$5_$3_DEF);
- const size_t vermsz = sizeof(Elf$5_$2);
- const size_t auxmsz = sizeof(Elf$5_$3);
- char * const dstend = dst + dsz;
- char * const srcend = src + count;
- char *dtmp, *dstaux, *srcaux;
- Elf$5_Word aux, anext, cnt, vnext;
-
- for (dtmp = dst, vnext = ~0;
- vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend;
- dtmp += vnext, src += vnext) {
-
- /* Read in an Elf$5_$2 structure. */
- t = *((Elf$5_$2 *) (uintptr_t) src);
-
- aux = t.$4_aux;
- cnt = t.$4_cnt;
- vnext = t.$4_next;
-
- if (byteswap) {
- SWAP_STRUCT($2, $5)
- }
-
- dst = dtmp;
- WRITE_STRUCT($2, $5)
-
- if (aux < verfsz)
- return (0);
-
- /* Process AUX entries. */
- for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux;
- cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend &&
- srcaux + auxmsz <= srcend;
- dstaux += anext, srcaux += anext, cnt--) {
-
- /* Read in an Elf$5_$3 structure. */
- a = *((Elf$5_$3 *) (uintptr_t) srcaux);
- anext = a.$4a_next;
-
- if (byteswap) {
- pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t')
- }
-
- dst = dstaux;
- pushdef(`t',`a')WRITE_STRUCT($3, $5)popdef(`t')
- }
-
- if (anext || cnt)
- return (0);
- }
-
- if (vnext)
- return (0);
-
- return (1);
-}
-
-static int
-libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- Elf$5_$2 t, *dp;
- Elf$5_$3 a, *ap;
- const size_t verfsz = FSZ(Elf$5_$2_DEF);
- const size_t auxfsz = FSZ(Elf$5_$3_DEF);
- const size_t vermsz = sizeof(Elf$5_$2);
- const size_t auxmsz = sizeof(Elf$5_$3);
- char * const dstend = dst + dsz;
- char * const srcend = src + count;
- char *dstaux, *s, *srcaux, *stmp;
- Elf$5_Word aux, anext, cnt, vnext;
-
- for (stmp = src, vnext = ~0;
- vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend;
- stmp += vnext, dst += vnext) {
-
- /* Read in a $1 structure. */
- s = stmp;
- READ_STRUCT($2, $5)
- if (byteswap) {
- SWAP_STRUCT($2, $5)
- }
-
- dp = (Elf$5_$2 *) (uintptr_t) dst;
- *dp = t;
-
- aux = t.$4_aux;
- cnt = t.$4_cnt;
- vnext = t.$4_next;
-
- if (aux < vermsz)
- return (0);
-
- /* Process AUX entries. */
- for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux;
- cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend &&
- srcaux + auxfsz <= srcend;
- dstaux += anext, srcaux += anext, cnt--) {
-
- s = srcaux;
- pushdef(`t',`a')READ_STRUCT($3, $5)popdef(`t')
-
- if (byteswap) {
- pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t')
- }
-
- anext = a.$4a_next;
-
- ap = ((Elf$5_$3 *) (uintptr_t) dstaux);
- *ap = a;
- }
-
- if (anext || cnt)
- return (0);
- }
-
- if (vnext)
- return (0);
-
- return (1);
-}')
-
-divert(0)
-
-/*
- * C macros to byte swap integral quantities.
- */
-
-#define SWAP_BYTE(X) do { (void) (X); } while (0)
-#define SWAP_IDENT(X) do { (void) (X); } while (0)
-#define SWAP_HALF(X) do { \
- uint16_t _x = (uint16_t) (X); \
- uint16_t _t = _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- (X) = _t; \
- } while (0)
-#define SWAP_WORD(X) do { \
- uint32_t _x = (uint32_t) (X); \
- uint32_t _t = _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- (X) = _t; \
- } while (0)
-#define SWAP_ADDR32(X) SWAP_WORD(X)
-#define SWAP_OFF32(X) SWAP_WORD(X)
-#define SWAP_SWORD(X) SWAP_WORD(X)
-#define SWAP_WORD64(X) do { \
- uint64_t _x = (uint64_t) (X); \
- uint64_t _t = _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
- (X) = _t; \
- } while (0)
-#define SWAP_ADDR64(X) SWAP_WORD64(X)
-#define SWAP_LWORD(X) SWAP_WORD64(X)
-#define SWAP_OFF64(X) SWAP_WORD64(X)
-#define SWAP_SXWORD(X) SWAP_WORD64(X)
-#define SWAP_XWORD(X) SWAP_WORD64(X)
-
-/*
- * C macros to write out various integral values.
- *
- * Note:
- * - The destination pointer could be unaligned.
- * - Values are written out in native byte order.
- * - The destination pointer is incremented after the write.
- */
-#define WRITE_BYTE(P,X) do { \
- char *const _p = (char *) (P); \
- _p[0] = (char) (X); \
- (P) = _p + 1; \
- } while (0)
-#define WRITE_HALF(P,X) do { \
- uint16_t _t = (X); \
- char *const _p = (char *) (P); \
- const char *const _q = (char *) &_t; \
- _p[0] = _q[0]; \
- _p[1] = _q[1]; \
- (P) = _p + 2; \
- } while (0)
-#define WRITE_WORD(P,X) do { \
- uint32_t _t = (X); \
- char *const _p = (char *) (P); \
- const char *const _q = (char *) &_t; \
- _p[0] = _q[0]; \
- _p[1] = _q[1]; \
- _p[2] = _q[2]; \
- _p[3] = _q[3]; \
- (P) = _p + 4; \
- } while (0)
-#define WRITE_ADDR32(P,X) WRITE_WORD(P,X)
-#define WRITE_OFF32(P,X) WRITE_WORD(P,X)
-#define WRITE_SWORD(P,X) WRITE_WORD(P,X)
-#define WRITE_WORD64(P,X) do { \
- uint64_t _t = (X); \
- char *const _p = (char *) (P); \
- const char *const _q = (char *) &_t; \
- _p[0] = _q[0]; \
- _p[1] = _q[1]; \
- _p[2] = _q[2]; \
- _p[3] = _q[3]; \
- _p[4] = _q[4]; \
- _p[5] = _q[5]; \
- _p[6] = _q[6]; \
- _p[7] = _q[7]; \
- (P) = _p + 8; \
- } while (0)
-#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X)
-#define WRITE_LWORD(P,X) WRITE_WORD64(P,X)
-#define WRITE_OFF64(P,X) WRITE_WORD64(P,X)
-#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X)
-#define WRITE_XWORD(P,X) WRITE_WORD64(P,X)
-#define WRITE_IDENT(P,X) do { \
- (void) memcpy((P), (X), sizeof((X))); \
- (P) = (P) + EI_NIDENT; \
- } while (0)
-
-/*
- * C macros to read in various integral values.
- *
- * Note:
- * - The source pointer could be unaligned.
- * - Values are read in native byte order.
- * - The source pointer is incremented appropriately.
- */
-
-#define READ_BYTE(P,X) do { \
- const char *const _p = \
- (const char *) (P); \
- (X) = _p[0]; \
- (P) = (P) + 1; \
- } while (0)
-#define READ_HALF(P,X) do { \
- uint16_t _t; \
- char *const _q = (char *) &_t; \
- const char *const _p = \
- (const char *) (P); \
- _q[0] = _p[0]; \
- _q[1] = _p[1]; \
- (P) = (P) + 2; \
- (X) = _t; \
- } while (0)
-#define READ_WORD(P,X) do { \
- uint32_t _t; \
- char *const _q = (char *) &_t; \
- const char *const _p = \
- (const char *) (P); \
- _q[0] = _p[0]; \
- _q[1] = _p[1]; \
- _q[2] = _p[2]; \
- _q[3] = _p[3]; \
- (P) = (P) + 4; \
- (X) = _t; \
- } while (0)
-#define READ_ADDR32(P,X) READ_WORD(P,X)
-#define READ_OFF32(P,X) READ_WORD(P,X)
-#define READ_SWORD(P,X) READ_WORD(P,X)
-#define READ_WORD64(P,X) do { \
- uint64_t _t; \
- char *const _q = (char *) &_t; \
- const char *const _p = \
- (const char *) (P); \
- _q[0] = _p[0]; \
- _q[1] = _p[1]; \
- _q[2] = _p[2]; \
- _q[3] = _p[3]; \
- _q[4] = _p[4]; \
- _q[5] = _p[5]; \
- _q[6] = _p[6]; \
- _q[7] = _p[7]; \
- (P) = (P) + 8; \
- (X) = _t; \
- } while (0)
-#define READ_ADDR64(P,X) READ_WORD64(P,X)
-#define READ_LWORD(P,X) READ_WORD64(P,X)
-#define READ_OFF64(P,X) READ_WORD64(P,X)
-#define READ_SXWORD(P,X) READ_WORD64(P,X)
-#define READ_XWORD(P,X) READ_WORD64(P,X)
-#define READ_IDENT(P,X) do { \
- (void) memcpy((X), (P), sizeof((X))); \
- (P) = (P) + EI_NIDENT; \
- } while (0)
-
-#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1))
-
-/*[*/
-MAKE_TYPE_CONVERTERS(ELF_TYPE_LIST)
-MAKE_VERSION_CONVERTERS(VDEF,Verdef,Verdaux,vd)
-MAKE_VERSION_CONVERTERS(VNEED,Verneed,Vernaux,vn)
-/*]*/
-
-/*
- * Sections of type ELF_T_BYTE are never byteswapped, consequently a
- * simple memcpy suffices for both directions of conversion.
- */
-
-static int
-libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- (void) byteswap;
- if (dsz < count)
- return (0);
- if (dst != src)
- (void) memcpy(dst, src, count);
- return (1);
-}
-
-/*
- * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit
- * words. Bloom filter data comes next, followed by hash buckets and the
- * hash chain.
- *
- * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit
- * wide on ELFCLASS32 objects. The other objects in this section are 32
- * bits wide.
- *
- * Argument `srcsz' denotes the number of bytes to be converted. In the
- * 32-bit case we need to translate `srcsz' to a count of 32-bit words.
- */
-
-static int
-libelf_cvt_GNUHASH32_tom(char *dst, size_t dsz, char *src, size_t srcsz,
- int byteswap)
-{
- return (libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t),
- byteswap));
-}
-
-static int
-libelf_cvt_GNUHASH32_tof(char *dst, size_t dsz, char *src, size_t srcsz,
- int byteswap)
-{
- return (libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t),
- byteswap));
-}
-
-static int
-libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz,
- int byteswap)
-{
- size_t sz;
- uint64_t t64, *bloom64;
- Elf_GNU_Hash_Header *gh;
- uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32;
- uint32_t *buckets, *chains;
-
- sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */
- if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz)
- return (0);
-
- /* Read in the section header and byteswap if needed. */
- READ_WORD(src, nbuckets);
- READ_WORD(src, symndx);
- READ_WORD(src, maskwords);
- READ_WORD(src, shift2);
-
- srcsz -= sz;
-
- if (byteswap) {
- SWAP_WORD(nbuckets);
- SWAP_WORD(symndx);
- SWAP_WORD(maskwords);
- SWAP_WORD(shift2);
- }
-
- /* Check source buffer and destination buffer sizes. */
- sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t);
- if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header))
- return (0);
-
- gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst;
- gh->gh_nbuckets = nbuckets;
- gh->gh_symndx = symndx;
- gh->gh_maskwords = maskwords;
- gh->gh_shift2 = shift2;
-
- dsz -= sizeof(Elf_GNU_Hash_Header);
- dst += sizeof(Elf_GNU_Hash_Header);
-
- bloom64 = (uint64_t *) (uintptr_t) dst;
-
- /* Copy bloom filter data. */
- for (n = 0; n < maskwords; n++) {
- READ_XWORD(src, t64);
- if (byteswap)
- SWAP_XWORD(t64);
- bloom64[n] = t64;
- }
-
- /* The hash buckets follows the bloom filter. */
- dst += maskwords * sizeof(uint64_t);
- buckets = (uint32_t *) (uintptr_t) dst;
-
- for (n = 0; n < nbuckets; n++) {
- READ_WORD(src, t32);
- if (byteswap)
- SWAP_WORD(t32);
- buckets[n] = t32;
- }
-
- dst += nbuckets * sizeof(uint32_t);
-
- /* The hash chain follows the hash buckets. */
- dsz -= sz;
- srcsz -= sz;
-
- if (dsz < srcsz) /* Destination lacks space. */
- return (0);
-
- nchains = srcsz / sizeof(uint32_t);
- chains = (uint32_t *) (uintptr_t) dst;
-
- for (n = 0; n < nchains; n++) {
- READ_WORD(src, t32);
- if (byteswap)
- SWAP_WORD(t32);
- *chains++ = t32;
- }
-
- return (1);
-}
-
-static int
-libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz,
- int byteswap)
-{
- uint32_t *s32;
- size_t sz, hdrsz;
- uint64_t *s64, t64;
- Elf_GNU_Hash_Header *gh;
- uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32;
-
- hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */
- if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header))
- return (0);
-
- gh = (Elf_GNU_Hash_Header *) (uintptr_t) src;
-
- t0 = nbuckets = gh->gh_nbuckets;
- t1 = gh->gh_symndx;
- t2 = maskwords = gh->gh_maskwords;
- t3 = gh->gh_shift2;
-
- src += sizeof(Elf_GNU_Hash_Header);
- srcsz -= sizeof(Elf_GNU_Hash_Header);
- dsz -= hdrsz;
-
- sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords *
- sizeof(uint64_t);
-
- if (srcsz < sz || dsz < sz)
- return (0);
-
- /* Write out the header. */
- if (byteswap) {
- SWAP_WORD(t0);
- SWAP_WORD(t1);
- SWAP_WORD(t2);
- SWAP_WORD(t3);
- }
-
- WRITE_WORD(dst, t0);
- WRITE_WORD(dst, t1);
- WRITE_WORD(dst, t2);
- WRITE_WORD(dst, t3);
-
- /* Copy the bloom filter and the hash table. */
- s64 = (uint64_t *) (uintptr_t) src;
- for (n = 0; n < maskwords; n++) {
- t64 = *s64++;
- if (byteswap)
- SWAP_XWORD(t64);
- WRITE_WORD64(dst, t64);
- }
-
- s32 = (uint32_t *) s64;
- for (n = 0; n < nbuckets; n++) {
- t32 = *s32++;
- if (byteswap)
- SWAP_WORD(t32);
- WRITE_WORD(dst, t32);
- }
-
- srcsz -= sz;
- dsz -= sz;
-
- /* Copy out the hash chains. */
- if (dsz < srcsz)
- return (0);
-
- nchains = srcsz / sizeof(uint32_t);
- for (n = 0; n < nchains; n++) {
- t32 = *s32++;
- if (byteswap)
- SWAP_WORD(t32);
- WRITE_WORD(dst, t32);
- }
-
- return (1);
-}
-
-/*
- * Elf_Note structures comprise a fixed size header followed by variable
- * length strings. The fixed size header needs to be byte swapped, but
- * not the strings.
- *
- * Argument `count' denotes the total number of bytes to be converted.
- * The destination buffer needs to be at least `count' bytes in size.
- */
-static int
-libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- uint32_t namesz, descsz, type;
- Elf_Note *en;
- size_t sz, hdrsz;
-
- if (dsz < count) /* Destination buffer is too small. */
- return (0);
-
- hdrsz = 3 * sizeof(uint32_t);
- if (count < hdrsz) /* Source too small. */
- return (0);
-
- if (!byteswap) {
- (void) memcpy(dst, src, count);
- return (1);
- }
-
- /* Process all notes in the section. */
- while (count > hdrsz) {
- /* Read the note header. */
- READ_WORD(src, namesz);
- READ_WORD(src, descsz);
- READ_WORD(src, type);
-
- /* Translate. */
- SWAP_WORD(namesz);
- SWAP_WORD(descsz);
- SWAP_WORD(type);
-
- /* Copy out the translated note header. */
- en = (Elf_Note *) (uintptr_t) dst;
- en->n_namesz = namesz;
- en->n_descsz = descsz;
- en->n_type = type;
-
- dsz -= sizeof(Elf_Note);
- dst += sizeof(Elf_Note);
- count -= hdrsz;
-
- ROUNDUP2(namesz, 4);
- ROUNDUP2(descsz, 4);
-
- sz = namesz + descsz;
-
- if (count < sz || dsz < sz) /* Buffers are too small. */
- return (0);
-
- (void) memcpy(dst, src, sz);
-
- src += sz;
- dst += sz;
-
- count -= sz;
- dsz -= sz;
- }
-
- return (1);
-}
-
-static int
-libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count,
- int byteswap)
-{
- uint32_t namesz, descsz, type;
- Elf_Note *en;
- size_t sz;
-
- if (dsz < count)
- return (0);
-
- if (!byteswap) {
- (void) memcpy(dst, src, count);
- return (1);
- }
-
- while (count > sizeof(Elf_Note)) {
-
- en = (Elf_Note *) (uintptr_t) src;
- namesz = en->n_namesz;
- descsz = en->n_descsz;
- type = en->n_type;
-
- SWAP_WORD(namesz);
- SWAP_WORD(descsz);
- SWAP_WORD(type);
-
- WRITE_WORD(dst, namesz);
- WRITE_WORD(dst, descsz);
- WRITE_WORD(dst, type);
-
- src += sizeof(Elf_Note);
-
- ROUNDUP2(namesz, 4);
- ROUNDUP2(descsz, 4);
-
- sz = namesz + descsz;
-
- if (count < sz)
- sz = count;
-
- (void) memcpy(dst, src, sz);
-
- src += sz;
- dst += sz;
- count -= sz;
- }
-
- return (1);
-}
-
-struct converters {
- int (*tof32)(char *dst, size_t dsz, char *src, size_t cnt,
- int byteswap);
- int (*tom32)(char *dst, size_t dsz, char *src, size_t cnt,
- int byteswap);
- int (*tof64)(char *dst, size_t dsz, char *src, size_t cnt,
- int byteswap);
- int (*tom64)(char *dst, size_t dsz, char *src, size_t cnt,
- int byteswap);
-};
-
-
-static struct converters cvt[ELF_T_NUM] = {
- /*[*/
-CONVERTER_NAMES(ELF_TYPE_LIST)
- /*]*/
-
- /*
- * Types that need hand-coded converters follow.
- */
-
- [ELF_T_BYTE] = {
- .tof32 = libelf_cvt_BYTE_tox,
- .tom32 = libelf_cvt_BYTE_tox,
- .tof64 = libelf_cvt_BYTE_tox,
- .tom64 = libelf_cvt_BYTE_tox
- },
-
- [ELF_T_NOTE] = {
- .tof32 = libelf_cvt_NOTE_tof,
- .tom32 = libelf_cvt_NOTE_tom,
- .tof64 = libelf_cvt_NOTE_tof,
- .tom64 = libelf_cvt_NOTE_tom
- }
-};
-
-int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass))
- (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap)
-{
- assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
- assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY);
-
- if (t >= ELF_T_NUM ||
- (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) ||
- (direction != ELF_TOFILE && direction != ELF_TOMEMORY))
- return (NULL);
-
- return ((elfclass == ELFCLASS32) ?
- (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) :
- (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64));
-}