1*f8fb3368SJohn Marino/*- 2*f8fb3368SJohn Marino * Copyright (c) 2006-2011 Joseph Koshy 3*f8fb3368SJohn Marino * All rights reserved. 4*f8fb3368SJohn Marino * 5*f8fb3368SJohn Marino * Redistribution and use in source and binary forms, with or without 6*f8fb3368SJohn Marino * modification, are permitted provided that the following conditions 7*f8fb3368SJohn Marino * are met: 8*f8fb3368SJohn Marino * 1. Redistributions of source code must retain the above copyright 9*f8fb3368SJohn Marino * notice, this list of conditions and the following disclaimer. 10*f8fb3368SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 11*f8fb3368SJohn Marino * notice, this list of conditions and the following disclaimer in the 12*f8fb3368SJohn Marino * documentation and/or other materials provided with the distribution. 13*f8fb3368SJohn Marino * 14*f8fb3368SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*f8fb3368SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*f8fb3368SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*f8fb3368SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*f8fb3368SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*f8fb3368SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*f8fb3368SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*f8fb3368SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*f8fb3368SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*f8fb3368SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*f8fb3368SJohn Marino * SUCH DAMAGE. 25*f8fb3368SJohn Marino */ 26*f8fb3368SJohn Marino 27*f8fb3368SJohn Marino#include <assert.h> 28*f8fb3368SJohn Marino#include <libelf.h> 29*f8fb3368SJohn Marino#include <string.h> 30*f8fb3368SJohn Marino 31*f8fb3368SJohn Marino#include "_libelf.h" 32*f8fb3368SJohn Marino 33*f8fb3368SJohn MarinoELFTC_VCSID("$Id: libelf_convert.m4 3174 2015-03-27 17:13:41Z emaste $"); 34*f8fb3368SJohn Marino 35*f8fb3368SJohn Marino/* WARNING: GENERATED FROM __file__. */ 36*f8fb3368SJohn Marino 37*f8fb3368SJohn Marinodivert(-1) 38*f8fb3368SJohn Marino 39*f8fb3368SJohn Marino# Generate conversion routines for converting between in-memory and 40*f8fb3368SJohn Marino# file representations of Elf data structures. 41*f8fb3368SJohn Marino# 42*f8fb3368SJohn Marino# These conversions use the type information defined in `elf_types.m4'. 43*f8fb3368SJohn Marino 44*f8fb3368SJohn Marinoinclude(SRCDIR`/elf_types.m4') 45*f8fb3368SJohn Marino 46*f8fb3368SJohn Marino# For the purposes of generating conversion code, ELF types may be 47*f8fb3368SJohn Marino# classified according to the following characteristics: 48*f8fb3368SJohn Marino# 49*f8fb3368SJohn Marino# 1. Whether the ELF type can be directly mapped to an integral C 50*f8fb3368SJohn Marino# language type. For example, the ELF_T_WORD type maps directly to 51*f8fb3368SJohn Marino# a 'uint32_t', but ELF_T_GNUHASH lacks a matching C type. 52*f8fb3368SJohn Marino# 53*f8fb3368SJohn Marino# 2. Whether the type has word size dependent variants. For example, 54*f8fb3368SJohn Marino# ELT_T_EHDR is represented using C types Elf32_Ehdr and El64_Ehdr, 55*f8fb3368SJohn Marino# and the ELF_T_ADDR and ELF_T_OFF types have integral C types that 56*f8fb3368SJohn Marino# can be 32- or 64- bit wide. 57*f8fb3368SJohn Marino# 58*f8fb3368SJohn Marino# 3. Whether the ELF types has a fixed representation or not. For 59*f8fb3368SJohn Marino# example, the ELF_T_SYM type has a fixed size file representation, 60*f8fb3368SJohn Marino# some types like ELF_T_NOTE and ELF_T_GNUHASH use a variable size 61*f8fb3368SJohn Marino# representation. 62*f8fb3368SJohn Marino# 63*f8fb3368SJohn Marino# We use m4 macros to generate conversion code for ELF types that have 64*f8fb3368SJohn Marino# a fixed size representation. Conversion functions for the remaining 65*f8fb3368SJohn Marino# types are coded by hand. 66*f8fb3368SJohn Marino# 67*f8fb3368SJohn Marino#* Handling File and Memory Representations 68*f8fb3368SJohn Marino# 69*f8fb3368SJohn Marino# `In-memory' representations of an Elf data structure use natural 70*f8fb3368SJohn Marino# alignments and native byte ordering. This allows pointer arithmetic 71*f8fb3368SJohn Marino# and casting to work as expected. On the other hand, the `file' 72*f8fb3368SJohn Marino# representation of an ELF data structure could possibly be packed 73*f8fb3368SJohn Marino# tighter than its `in-memory' representation, and could be of a 74*f8fb3368SJohn Marino# differing byte order. Reading ELF objects that are members of `ar' 75*f8fb3368SJohn Marino# archives present an additional complication: `ar' pads file data to 76*f8fb3368SJohn Marino# even addresses, so file data structures in an archive member 77*f8fb3368SJohn Marino# residing inside an `ar' archive could be at misaligned memory 78*f8fb3368SJohn Marino# addresses when brought into memory. 79*f8fb3368SJohn Marino# 80*f8fb3368SJohn Marino# In summary, casting the `char *' pointers that point to memory 81*f8fb3368SJohn Marino# representations (i.e., source pointers for the *_tof() functions and 82*f8fb3368SJohn Marino# the destination pointers for the *_tom() functions), is safe, as 83*f8fb3368SJohn Marino# these pointers should be correctly aligned for the memory type 84*f8fb3368SJohn Marino# already. However, pointers to file representations have to be 85*f8fb3368SJohn Marino# treated as being potentially unaligned and no casting can be done. 86*f8fb3368SJohn Marino 87*f8fb3368SJohn Marino# NOCVT(TYPE) -- Do not generate the cvt[] structure entry for TYPE 88*f8fb3368SJohn Marinodefine(`NOCVT',`define(`NOCVT_'$1,1)') 89*f8fb3368SJohn Marino 90*f8fb3368SJohn Marino# NOFUNC(TYPE) -- Do not generate a conversion function for TYPE 91*f8fb3368SJohn Marinodefine(`NOFUNC',`define(`NOFUNC_'$1,1)') 92*f8fb3368SJohn Marino 93*f8fb3368SJohn Marino# IGNORE(TYPE) -- Completely ignore the type. 94*f8fb3368SJohn Marinodefine(`IGNORE',`NOCVT($1)NOFUNC($1)') 95*f8fb3368SJohn Marino 96*f8fb3368SJohn Marino# Mark ELF types that should not be processed by the M4 macros below. 97*f8fb3368SJohn Marino 98*f8fb3368SJohn Marino# Types for which we use functions with non-standard names. 99*f8fb3368SJohn MarinoIGNORE(`BYTE') # Uses a wrapper around memcpy(). 100*f8fb3368SJohn MarinoIGNORE(`NOTE') # Not a fixed size type. 101*f8fb3368SJohn Marino 102*f8fb3368SJohn Marino# Types for which we supply hand-coded functions. 103*f8fb3368SJohn MarinoNOFUNC(`GNUHASH') # A type with complex internal structure. 104*f8fb3368SJohn MarinoNOFUNC(`VDEF') # See MAKE_VERSION_CONVERTERS below. 105*f8fb3368SJohn MarinoNOFUNC(`VNEED') # .. 106*f8fb3368SJohn Marino 107*f8fb3368SJohn Marino# Unimplemented types. 108*f8fb3368SJohn MarinoIGNORE(`MOVEP') 109*f8fb3368SJohn Marino 110*f8fb3368SJohn Marino# ELF types that don't exist in a 32-bit world. 111*f8fb3368SJohn MarinoNOFUNC(`XWORD32') 112*f8fb3368SJohn MarinoNOFUNC(`SXWORD32') 113*f8fb3368SJohn Marino 114*f8fb3368SJohn Marino# `Primitive' ELF types are those that are an alias for an integral 115*f8fb3368SJohn Marino# type. As they have no internal structure, they can be copied using 116*f8fb3368SJohn Marino# a `memcpy()', and byteswapped in straightforward way. 117*f8fb3368SJohn Marino# 118*f8fb3368SJohn Marino# Mark all ELF types that directly map to integral C types. 119*f8fb3368SJohn Marinodefine(`PRIM_ADDR', 1) 120*f8fb3368SJohn Marinodefine(`PRIM_BYTE', 1) 121*f8fb3368SJohn Marinodefine(`PRIM_HALF', 1) 122*f8fb3368SJohn Marinodefine(`PRIM_LWORD', 1) 123*f8fb3368SJohn Marinodefine(`PRIM_OFF', 1) 124*f8fb3368SJohn Marinodefine(`PRIM_SWORD', 1) 125*f8fb3368SJohn Marinodefine(`PRIM_SXWORD', 1) 126*f8fb3368SJohn Marinodefine(`PRIM_WORD', 1) 127*f8fb3368SJohn Marinodefine(`PRIM_XWORD', 1) 128*f8fb3368SJohn Marino 129*f8fb3368SJohn Marino# Note the primitive types that are size-dependent. 130*f8fb3368SJohn Marinodefine(`SIZEDEP_ADDR', 1) 131*f8fb3368SJohn Marinodefine(`SIZEDEP_OFF', 1) 132*f8fb3368SJohn Marino 133*f8fb3368SJohn Marino# Generate conversion functions for primitive types. 134*f8fb3368SJohn Marino# 135*f8fb3368SJohn Marino# Macro use: MAKEPRIMFUNCS(ELFTYPE,CTYPE,TYPESIZE,SYMSIZE) 136*f8fb3368SJohn Marino# `$1': Name of the ELF type. 137*f8fb3368SJohn Marino# `$2': C structure name suffix. 138*f8fb3368SJohn Marino# `$3': ELF class specifier for types, one of [`32', `64']. 139*f8fb3368SJohn Marino# `$4': Additional ELF class specifier, one of [`', `32', `64']. 140*f8fb3368SJohn Marino# 141*f8fb3368SJohn Marino# Generates a pair of conversion functions. 142*f8fb3368SJohn Marinodefine(`MAKEPRIMFUNCS',` 143*f8fb3368SJohn Marinostatic int 144*f8fb3368SJohn Marino_libelf_cvt_$1$4_tof(unsigned char *dst, size_t dsz, unsigned char *src, 145*f8fb3368SJohn Marino size_t count, int byteswap) 146*f8fb3368SJohn Marino{ 147*f8fb3368SJohn Marino Elf$3_$2 t, *s = (Elf$3_$2 *) (uintptr_t) src; 148*f8fb3368SJohn Marino size_t c; 149*f8fb3368SJohn Marino 150*f8fb3368SJohn Marino (void) dsz; 151*f8fb3368SJohn Marino 152*f8fb3368SJohn Marino if (!byteswap) { 153*f8fb3368SJohn Marino (void) memcpy(dst, src, count * sizeof(*s)); 154*f8fb3368SJohn Marino return (1); 155*f8fb3368SJohn Marino } 156*f8fb3368SJohn Marino 157*f8fb3368SJohn Marino for (c = 0; c < count; c++) { 158*f8fb3368SJohn Marino t = *s++; 159*f8fb3368SJohn Marino SWAP_$1$4(t); 160*f8fb3368SJohn Marino WRITE_$1$4(dst,t); 161*f8fb3368SJohn Marino } 162*f8fb3368SJohn Marino 163*f8fb3368SJohn Marino return (1); 164*f8fb3368SJohn Marino} 165*f8fb3368SJohn Marino 166*f8fb3368SJohn Marinostatic int 167*f8fb3368SJohn Marino_libelf_cvt_$1$4_tom(unsigned char *dst, size_t dsz, unsigned char *src, 168*f8fb3368SJohn Marino size_t count, int byteswap) 169*f8fb3368SJohn Marino{ 170*f8fb3368SJohn Marino Elf$3_$2 t, *d = (Elf$3_$2 *) (uintptr_t) dst; 171*f8fb3368SJohn Marino size_t c; 172*f8fb3368SJohn Marino 173*f8fb3368SJohn Marino if (dsz < count * sizeof(Elf$3_$2)) 174*f8fb3368SJohn Marino return (0); 175*f8fb3368SJohn Marino 176*f8fb3368SJohn Marino if (!byteswap) { 177*f8fb3368SJohn Marino (void) memcpy(dst, src, count * sizeof(*d)); 178*f8fb3368SJohn Marino return (1); 179*f8fb3368SJohn Marino } 180*f8fb3368SJohn Marino 181*f8fb3368SJohn Marino for (c = 0; c < count; c++) { 182*f8fb3368SJohn Marino READ_$1$4(src,t); 183*f8fb3368SJohn Marino SWAP_$1$4(t); 184*f8fb3368SJohn Marino *d++ = t; 185*f8fb3368SJohn Marino } 186*f8fb3368SJohn Marino 187*f8fb3368SJohn Marino return (1); 188*f8fb3368SJohn Marino} 189*f8fb3368SJohn Marino') 190*f8fb3368SJohn Marino 191*f8fb3368SJohn Marino# 192*f8fb3368SJohn Marino# Handling composite ELF types 193*f8fb3368SJohn Marino# 194*f8fb3368SJohn Marino 195*f8fb3368SJohn Marino# SWAP_FIELD(FIELDNAME,ELFTYPE) -- Generate code to swap one field. 196*f8fb3368SJohn Marinodefine(`SWAP_FIELD', 197*f8fb3368SJohn Marino `ifdef(`SIZEDEP_'$2, 198*f8fb3368SJohn Marino `SWAP_$2'SZ()`(t.$1); 199*f8fb3368SJohn Marino ', 200*f8fb3368SJohn Marino `SWAP_$2(t.$1); 201*f8fb3368SJohn Marino ')') 202*f8fb3368SJohn Marino 203*f8fb3368SJohn Marino# SWAP_MEMBERS(STRUCT) -- Iterate over a structure definition. 204*f8fb3368SJohn Marinodefine(`SWAP_MEMBERS', 205*f8fb3368SJohn Marino `ifelse($#,1,`/**/', 206*f8fb3368SJohn Marino `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')') 207*f8fb3368SJohn Marino 208*f8fb3368SJohn Marino# SWAP_STRUCT(CTYPE,SIZE) -- Generate code to swap an ELF structure. 209*f8fb3368SJohn Marinodefine(`SWAP_STRUCT', 210*f8fb3368SJohn Marino `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */ 211*f8fb3368SJohn Marino SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') 212*f8fb3368SJohn Marino 213*f8fb3368SJohn Marino# WRITE_FIELD(ELFTYPE,FIELDNAME) -- Generate code to write one field. 214*f8fb3368SJohn Marinodefine(`WRITE_FIELD', 215*f8fb3368SJohn Marino `ifdef(`SIZEDEP_'$2, 216*f8fb3368SJohn Marino `WRITE_$2'SZ()`(dst,t.$1); 217*f8fb3368SJohn Marino ', 218*f8fb3368SJohn Marino `WRITE_$2(dst,t.$1); 219*f8fb3368SJohn Marino ')') 220*f8fb3368SJohn Marino 221*f8fb3368SJohn Marino# WRITE_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition. 222*f8fb3368SJohn Marinodefine(`WRITE_MEMBERS', 223*f8fb3368SJohn Marino `ifelse($#,1,`/**/', 224*f8fb3368SJohn Marino `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')') 225*f8fb3368SJohn Marino 226*f8fb3368SJohn Marino# WRITE_STRUCT(CTYPE,SIZE) -- Generate code to write out an ELF structure. 227*f8fb3368SJohn Marinodefine(`WRITE_STRUCT', 228*f8fb3368SJohn Marino `pushdef(`SZ',$2)/* Write an Elf$2_$1 */ 229*f8fb3368SJohn Marino WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') 230*f8fb3368SJohn Marino 231*f8fb3368SJohn Marino# READ_FIELD(ELFTYPE,CTYPE) -- Generate code to read one field. 232*f8fb3368SJohn Marinodefine(`READ_FIELD', 233*f8fb3368SJohn Marino `ifdef(`SIZEDEP_'$2, 234*f8fb3368SJohn Marino `READ_$2'SZ()`(s,t.$1); 235*f8fb3368SJohn Marino ', 236*f8fb3368SJohn Marino `READ_$2(s,t.$1); 237*f8fb3368SJohn Marino ')') 238*f8fb3368SJohn Marino 239*f8fb3368SJohn Marino# READ_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition. 240*f8fb3368SJohn Marinodefine(`READ_MEMBERS', 241*f8fb3368SJohn Marino `ifelse($#,1,`/**/', 242*f8fb3368SJohn Marino `READ_FIELD($1)READ_MEMBERS(shift($@))')') 243*f8fb3368SJohn Marino 244*f8fb3368SJohn Marino# READ_STRUCT(CTYPE,SIZE) -- Generate code to read an ELF structure. 245*f8fb3368SJohn Marinodefine(`READ_STRUCT', 246*f8fb3368SJohn Marino `pushdef(`SZ',$2)/* Read an Elf$2_$1 */ 247*f8fb3368SJohn Marino READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') 248*f8fb3368SJohn Marino 249*f8fb3368SJohn Marino 250*f8fb3368SJohn Marino# MAKECOMPFUNCS -- Generate converters for composite ELF structures. 251*f8fb3368SJohn Marino# 252*f8fb3368SJohn Marino# When converting data to file representation, the source pointer will 253*f8fb3368SJohn Marino# be naturally aligned for a data structure's in-memory 254*f8fb3368SJohn Marino# representation. When converting data to memory, the destination 255*f8fb3368SJohn Marino# pointer will be similarly aligned. 256*f8fb3368SJohn Marino# 257*f8fb3368SJohn Marino# For in-place conversions, when converting to file representations, 258*f8fb3368SJohn Marino# the source buffer is large enough to hold `file' data. When 259*f8fb3368SJohn Marino# converting from file to memory, we need to be careful to work 260*f8fb3368SJohn Marino# `backwards', to avoid overwriting unconverted data. 261*f8fb3368SJohn Marino# 262*f8fb3368SJohn Marino# Macro use: 263*f8fb3368SJohn Marino# `$1': Name of the ELF type. 264*f8fb3368SJohn Marino# `$2': C structure name suffix. 265*f8fb3368SJohn Marino# `$3': ELF class specifier, one of [`', `32', `64'] 266*f8fb3368SJohn Marinodefine(`MAKECOMPFUNCS', `ifdef(`NOFUNC_'$1$3,`',` 267*f8fb3368SJohn Marinostatic int 268*f8fb3368SJohn Marino_libelf_cvt_$1$3_tof(unsigned char *dst, size_t dsz, unsigned char *src, 269*f8fb3368SJohn Marino size_t count, int byteswap) 270*f8fb3368SJohn Marino{ 271*f8fb3368SJohn Marino Elf$3_$2 t, *s; 272*f8fb3368SJohn Marino size_t c; 273*f8fb3368SJohn Marino 274*f8fb3368SJohn Marino (void) dsz; 275*f8fb3368SJohn Marino 276*f8fb3368SJohn Marino s = (Elf$3_$2 *) (uintptr_t) src; 277*f8fb3368SJohn Marino for (c = 0; c < count; c++) { 278*f8fb3368SJohn Marino t = *s++; 279*f8fb3368SJohn Marino if (byteswap) { 280*f8fb3368SJohn Marino SWAP_STRUCT($2,$3) 281*f8fb3368SJohn Marino } 282*f8fb3368SJohn Marino WRITE_STRUCT($2,$3) 283*f8fb3368SJohn Marino } 284*f8fb3368SJohn Marino 285*f8fb3368SJohn Marino return (1); 286*f8fb3368SJohn Marino} 287*f8fb3368SJohn Marino 288*f8fb3368SJohn Marinostatic int 289*f8fb3368SJohn Marino_libelf_cvt_$1$3_tom(unsigned char *dst, size_t dsz, unsigned char *src, 290*f8fb3368SJohn Marino size_t count, int byteswap) 291*f8fb3368SJohn Marino{ 292*f8fb3368SJohn Marino Elf$3_$2 t, *d; 293*f8fb3368SJohn Marino unsigned char *s,*s0; 294*f8fb3368SJohn Marino size_t fsz; 295*f8fb3368SJohn Marino 296*f8fb3368SJohn Marino fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT); 297*f8fb3368SJohn Marino d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1); 298*f8fb3368SJohn Marino s0 = src + (count - 1) * fsz; 299*f8fb3368SJohn Marino 300*f8fb3368SJohn Marino if (dsz < count * sizeof(Elf$3_$2)) 301*f8fb3368SJohn Marino return (0); 302*f8fb3368SJohn Marino 303*f8fb3368SJohn Marino while (count--) { 304*f8fb3368SJohn Marino s = s0; 305*f8fb3368SJohn Marino READ_STRUCT($2,$3) 306*f8fb3368SJohn Marino if (byteswap) { 307*f8fb3368SJohn Marino SWAP_STRUCT($2,$3) 308*f8fb3368SJohn Marino } 309*f8fb3368SJohn Marino *d-- = t; s0 -= fsz; 310*f8fb3368SJohn Marino } 311*f8fb3368SJohn Marino 312*f8fb3368SJohn Marino return (1); 313*f8fb3368SJohn Marino} 314*f8fb3368SJohn Marino')') 315*f8fb3368SJohn Marino 316*f8fb3368SJohn Marino# MAKE_TYPE_CONVERTER(ELFTYPE,CTYPE) 317*f8fb3368SJohn Marino# 318*f8fb3368SJohn Marino# Make type convertor functions from the type definition 319*f8fb3368SJohn Marino# of the ELF type: 320*f8fb3368SJohn Marino# - Skip convertors marked as `NOFUNC'. 321*f8fb3368SJohn Marino# - Invoke `MAKEPRIMFUNCS' or `MAKECOMPFUNCS' as appropriate. 322*f8fb3368SJohn Marinodefine(`MAKE_TYPE_CONVERTER', 323*f8fb3368SJohn Marino `ifdef(`NOFUNC_'$1,`', 324*f8fb3368SJohn Marino `ifdef(`PRIM_'$1, 325*f8fb3368SJohn Marino `ifdef(`SIZEDEP_'$1, 326*f8fb3368SJohn Marino `MAKEPRIMFUNCS($1,$2,32,32)dnl 327*f8fb3368SJohn Marino MAKEPRIMFUNCS($1,$2,64,64)', 328*f8fb3368SJohn Marino `MAKEPRIMFUNCS($1,$2,64)')', 329*f8fb3368SJohn Marino `MAKECOMPFUNCS($1,$2,32)dnl 330*f8fb3368SJohn Marino MAKECOMPFUNCS($1,$2,64)')')') 331*f8fb3368SJohn Marino 332*f8fb3368SJohn Marino# MAKE_TYPE_CONVERTERS(ELFTYPELIST) -- Generate conversion functions. 333*f8fb3368SJohn Marinodefine(`MAKE_TYPE_CONVERTERS', 334*f8fb3368SJohn Marino `ifelse($#,1,`', 335*f8fb3368SJohn Marino `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')') 336*f8fb3368SJohn Marino 337*f8fb3368SJohn Marino 338*f8fb3368SJohn Marino# 339*f8fb3368SJohn Marino# Macros to generate entries for the table of convertors. 340*f8fb3368SJohn Marino# 341*f8fb3368SJohn Marino 342*f8fb3368SJohn Marino# CONV(ELFTYPE,SIZE,DIRECTION) 343*f8fb3368SJohn Marino# 344*f8fb3368SJohn Marino# Generate the name of a convertor function. 345*f8fb3368SJohn Marinodefine(`CONV', 346*f8fb3368SJohn Marino `ifdef(`NOFUNC_'$1$2, 347*f8fb3368SJohn Marino `.$3$2 = NULL', 348*f8fb3368SJohn Marino `ifdef(`PRIM_'$1, 349*f8fb3368SJohn Marino `ifdef(`SIZEDEP_'$1, 350*f8fb3368SJohn Marino `.$3$2 = _libelf_cvt_$1$2_$3', 351*f8fb3368SJohn Marino `.$3$2 = _libelf_cvt_$1_$3')', 352*f8fb3368SJohn Marino `.$3$2 = _libelf_cvt_$1$2_$3')')') 353*f8fb3368SJohn Marino 354*f8fb3368SJohn Marino# CONVERTER_NAME(ELFTYPE) 355*f8fb3368SJohn Marino# 356*f8fb3368SJohn Marino# Generate the contents of one `struct cvt' instance. 357*f8fb3368SJohn Marinodefine(`CONVERTER_NAME', 358*f8fb3368SJohn Marino `ifdef(`NOCVT_'$1,`', 359*f8fb3368SJohn Marino ` [ELF_T_$1] = { 360*f8fb3368SJohn Marino CONV($1,32,tof), 361*f8fb3368SJohn Marino CONV($1,32,tom), 362*f8fb3368SJohn Marino CONV($1,64,tof), 363*f8fb3368SJohn Marino CONV($1,64,tom) 364*f8fb3368SJohn Marino }, 365*f8fb3368SJohn Marino 366*f8fb3368SJohn Marino')') 367*f8fb3368SJohn Marino 368*f8fb3368SJohn Marino# CONVERTER_NAMES(ELFTYPELIST) 369*f8fb3368SJohn Marino# 370*f8fb3368SJohn Marino# Generate the `struct cvt[]' array. 371*f8fb3368SJohn Marinodefine(`CONVERTER_NAMES', 372*f8fb3368SJohn Marino `ifelse($#,1,`', 373*f8fb3368SJohn Marino `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')') 374*f8fb3368SJohn Marino 375*f8fb3368SJohn Marino# 376*f8fb3368SJohn Marino# Handling ELF version sections. 377*f8fb3368SJohn Marino# 378*f8fb3368SJohn Marino 379*f8fb3368SJohn Marino# _FSZ(FIELD,BASETYPE) - return the file size for a field. 380*f8fb3368SJohn Marinodefine(`_FSZ', 381*f8fb3368SJohn Marino `ifelse($2,`HALF',2, 382*f8fb3368SJohn Marino $2,`WORD',4)') 383*f8fb3368SJohn Marino 384*f8fb3368SJohn Marino# FSZ(STRUCT) - determine the file size of a structure. 385*f8fb3368SJohn Marinodefine(`FSZ', 386*f8fb3368SJohn Marino `ifelse($#,1,0, 387*f8fb3368SJohn Marino `eval(_FSZ($1) + FSZ(shift($@)))')') 388*f8fb3368SJohn Marino 389*f8fb3368SJohn Marino# MAKE_VERSION_CONVERTERS(TYPE,BASE,AUX,PFX) -- Generate conversion 390*f8fb3368SJohn Marino# functions for versioning structures. 391*f8fb3368SJohn Marinodefine(`MAKE_VERSION_CONVERTERS', 392*f8fb3368SJohn Marino `MAKE_VERSION_CONVERTER($1,$2,$3,$4,32) 393*f8fb3368SJohn Marino MAKE_VERSION_CONVERTER($1,$2,$3,$4,64)') 394*f8fb3368SJohn Marino 395*f8fb3368SJohn Marino# MAKE_VERSION_CONVERTOR(TYPE,CBASE,CAUX,PFX,SIZE) -- Generate a 396*f8fb3368SJohn Marino# conversion function. 397*f8fb3368SJohn Marinodefine(`MAKE_VERSION_CONVERTER',` 398*f8fb3368SJohn Marinostatic int 399*f8fb3368SJohn Marino_libelf_cvt_$1$5_tof(unsigned char *dst, size_t dsz, unsigned char *src, 400*f8fb3368SJohn Marino size_t count, int byteswap) 401*f8fb3368SJohn Marino{ 402*f8fb3368SJohn Marino Elf$5_$2 t; 403*f8fb3368SJohn Marino Elf$5_$3 a; 404*f8fb3368SJohn Marino const size_t verfsz = FSZ(Elf$5_$2_DEF); 405*f8fb3368SJohn Marino const size_t auxfsz = FSZ(Elf$5_$3_DEF); 406*f8fb3368SJohn Marino const size_t vermsz = sizeof(Elf$5_$2); 407*f8fb3368SJohn Marino const size_t auxmsz = sizeof(Elf$5_$3); 408*f8fb3368SJohn Marino unsigned char * const dstend = dst + dsz; 409*f8fb3368SJohn Marino unsigned char * const srcend = src + count; 410*f8fb3368SJohn Marino unsigned char *dtmp, *dstaux, *srcaux; 411*f8fb3368SJohn Marino Elf$5_Word aux, anext, cnt, vnext; 412*f8fb3368SJohn Marino 413*f8fb3368SJohn Marino for (dtmp = dst, vnext = ~0U; 414*f8fb3368SJohn Marino vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; 415*f8fb3368SJohn Marino dtmp += vnext, src += vnext) { 416*f8fb3368SJohn Marino 417*f8fb3368SJohn Marino /* Read in an Elf$5_$2 structure. */ 418*f8fb3368SJohn Marino t = *((Elf$5_$2 *) (uintptr_t) src); 419*f8fb3368SJohn Marino 420*f8fb3368SJohn Marino aux = t.$4_aux; 421*f8fb3368SJohn Marino cnt = t.$4_cnt; 422*f8fb3368SJohn Marino vnext = t.$4_next; 423*f8fb3368SJohn Marino 424*f8fb3368SJohn Marino if (byteswap) { 425*f8fb3368SJohn Marino SWAP_STRUCT($2, $5) 426*f8fb3368SJohn Marino } 427*f8fb3368SJohn Marino 428*f8fb3368SJohn Marino dst = dtmp; 429*f8fb3368SJohn Marino WRITE_STRUCT($2, $5) 430*f8fb3368SJohn Marino 431*f8fb3368SJohn Marino if (aux < verfsz) 432*f8fb3368SJohn Marino return (0); 433*f8fb3368SJohn Marino 434*f8fb3368SJohn Marino /* Process AUX entries. */ 435*f8fb3368SJohn Marino for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux; 436*f8fb3368SJohn Marino cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && 437*f8fb3368SJohn Marino srcaux + auxmsz <= srcend; 438*f8fb3368SJohn Marino dstaux += anext, srcaux += anext, cnt--) { 439*f8fb3368SJohn Marino 440*f8fb3368SJohn Marino /* Read in an Elf$5_$3 structure. */ 441*f8fb3368SJohn Marino a = *((Elf$5_$3 *) (uintptr_t) srcaux); 442*f8fb3368SJohn Marino anext = a.$4a_next; 443*f8fb3368SJohn Marino 444*f8fb3368SJohn Marino if (byteswap) { 445*f8fb3368SJohn Marino pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t') 446*f8fb3368SJohn Marino } 447*f8fb3368SJohn Marino 448*f8fb3368SJohn Marino dst = dstaux; 449*f8fb3368SJohn Marino pushdef(`t',`a')WRITE_STRUCT($3, $5)popdef(`t') 450*f8fb3368SJohn Marino } 451*f8fb3368SJohn Marino 452*f8fb3368SJohn Marino if (anext || cnt) 453*f8fb3368SJohn Marino return (0); 454*f8fb3368SJohn Marino } 455*f8fb3368SJohn Marino 456*f8fb3368SJohn Marino if (vnext) 457*f8fb3368SJohn Marino return (0); 458*f8fb3368SJohn Marino 459*f8fb3368SJohn Marino return (1); 460*f8fb3368SJohn Marino} 461*f8fb3368SJohn Marino 462*f8fb3368SJohn Marinostatic int 463*f8fb3368SJohn Marino_libelf_cvt_$1$5_tom(unsigned char *dst, size_t dsz, unsigned char *src, 464*f8fb3368SJohn Marino size_t count, int byteswap) 465*f8fb3368SJohn Marino{ 466*f8fb3368SJohn Marino Elf$5_$2 t, *dp; 467*f8fb3368SJohn Marino Elf$5_$3 a, *ap; 468*f8fb3368SJohn Marino const size_t verfsz = FSZ(Elf$5_$2_DEF); 469*f8fb3368SJohn Marino const size_t auxfsz = FSZ(Elf$5_$3_DEF); 470*f8fb3368SJohn Marino const size_t vermsz = sizeof(Elf$5_$2); 471*f8fb3368SJohn Marino const size_t auxmsz = sizeof(Elf$5_$3); 472*f8fb3368SJohn Marino unsigned char * const dstend = dst + dsz; 473*f8fb3368SJohn Marino unsigned char * const srcend = src + count; 474*f8fb3368SJohn Marino unsigned char *dstaux, *s, *srcaux, *stmp; 475*f8fb3368SJohn Marino Elf$5_Word aux, anext, cnt, vnext; 476*f8fb3368SJohn Marino 477*f8fb3368SJohn Marino for (stmp = src, vnext = ~0U; 478*f8fb3368SJohn Marino vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; 479*f8fb3368SJohn Marino stmp += vnext, dst += vnext) { 480*f8fb3368SJohn Marino 481*f8fb3368SJohn Marino /* Read in a $1 structure. */ 482*f8fb3368SJohn Marino s = stmp; 483*f8fb3368SJohn Marino READ_STRUCT($2, $5) 484*f8fb3368SJohn Marino if (byteswap) { 485*f8fb3368SJohn Marino SWAP_STRUCT($2, $5) 486*f8fb3368SJohn Marino } 487*f8fb3368SJohn Marino 488*f8fb3368SJohn Marino dp = (Elf$5_$2 *) (uintptr_t) dst; 489*f8fb3368SJohn Marino *dp = t; 490*f8fb3368SJohn Marino 491*f8fb3368SJohn Marino aux = t.$4_aux; 492*f8fb3368SJohn Marino cnt = t.$4_cnt; 493*f8fb3368SJohn Marino vnext = t.$4_next; 494*f8fb3368SJohn Marino 495*f8fb3368SJohn Marino if (aux < vermsz) 496*f8fb3368SJohn Marino return (0); 497*f8fb3368SJohn Marino 498*f8fb3368SJohn Marino /* Process AUX entries. */ 499*f8fb3368SJohn Marino for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; 500*f8fb3368SJohn Marino cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && 501*f8fb3368SJohn Marino srcaux + auxfsz <= srcend; 502*f8fb3368SJohn Marino dstaux += anext, srcaux += anext, cnt--) { 503*f8fb3368SJohn Marino 504*f8fb3368SJohn Marino s = srcaux; 505*f8fb3368SJohn Marino pushdef(`t',`a')READ_STRUCT($3, $5)popdef(`t') 506*f8fb3368SJohn Marino 507*f8fb3368SJohn Marino if (byteswap) { 508*f8fb3368SJohn Marino pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t') 509*f8fb3368SJohn Marino } 510*f8fb3368SJohn Marino 511*f8fb3368SJohn Marino anext = a.$4a_next; 512*f8fb3368SJohn Marino 513*f8fb3368SJohn Marino ap = ((Elf$5_$3 *) (uintptr_t) dstaux); 514*f8fb3368SJohn Marino *ap = a; 515*f8fb3368SJohn Marino } 516*f8fb3368SJohn Marino 517*f8fb3368SJohn Marino if (anext || cnt) 518*f8fb3368SJohn Marino return (0); 519*f8fb3368SJohn Marino } 520*f8fb3368SJohn Marino 521*f8fb3368SJohn Marino if (vnext) 522*f8fb3368SJohn Marino return (0); 523*f8fb3368SJohn Marino 524*f8fb3368SJohn Marino return (1); 525*f8fb3368SJohn Marino}') 526*f8fb3368SJohn Marino 527*f8fb3368SJohn Marinodivert(0) 528*f8fb3368SJohn Marino 529*f8fb3368SJohn Marino/* 530*f8fb3368SJohn Marino * C macros to byte swap integral quantities. 531*f8fb3368SJohn Marino */ 532*f8fb3368SJohn Marino 533*f8fb3368SJohn Marino#define SWAP_BYTE(X) do { (void) (X); } while (0) 534*f8fb3368SJohn Marino#define SWAP_IDENT(X) do { (void) (X); } while (0) 535*f8fb3368SJohn Marino#define SWAP_HALF(X) do { \ 536*f8fb3368SJohn Marino uint16_t _x = (uint16_t) (X); \ 537*f8fb3368SJohn Marino uint32_t _t = _x & 0xFFU; \ 538*f8fb3368SJohn Marino _t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU; \ 539*f8fb3368SJohn Marino (X) = (uint16_t) _t; \ 540*f8fb3368SJohn Marino } while (0) 541*f8fb3368SJohn Marino#define _SWAP_WORD(X, T) do { \ 542*f8fb3368SJohn Marino uint32_t _x = (uint32_t) (X); \ 543*f8fb3368SJohn Marino uint32_t _t = _x & 0xFF; \ 544*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 545*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 546*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 547*f8fb3368SJohn Marino (X) = (T) _t; \ 548*f8fb3368SJohn Marino } while (0) 549*f8fb3368SJohn Marino#define SWAP_ADDR32(X) _SWAP_WORD(X, Elf32_Addr) 550*f8fb3368SJohn Marino#define SWAP_OFF32(X) _SWAP_WORD(X, Elf32_Off) 551*f8fb3368SJohn Marino#define SWAP_SWORD(X) _SWAP_WORD(X, Elf32_Sword) 552*f8fb3368SJohn Marino#define SWAP_WORD(X) _SWAP_WORD(X, Elf32_Word) 553*f8fb3368SJohn Marino#define _SWAP_WORD64(X, T) do { \ 554*f8fb3368SJohn Marino uint64_t _x = (uint64_t) (X); \ 555*f8fb3368SJohn Marino uint64_t _t = _x & 0xFF; \ 556*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 557*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 558*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 559*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 560*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 561*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 562*f8fb3368SJohn Marino _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 563*f8fb3368SJohn Marino (X) = (T) _t; \ 564*f8fb3368SJohn Marino } while (0) 565*f8fb3368SJohn Marino#define SWAP_ADDR64(X) _SWAP_WORD64(X, Elf64_Addr) 566*f8fb3368SJohn Marino#define SWAP_LWORD(X) _SWAP_WORD64(X, Elf64_Lword) 567*f8fb3368SJohn Marino#define SWAP_OFF64(X) _SWAP_WORD64(X, Elf64_Off) 568*f8fb3368SJohn Marino#define SWAP_SXWORD(X) _SWAP_WORD64(X, Elf64_Sxword) 569*f8fb3368SJohn Marino#define SWAP_XWORD(X) _SWAP_WORD64(X, Elf64_Xword) 570*f8fb3368SJohn Marino 571*f8fb3368SJohn Marino/* 572*f8fb3368SJohn Marino * C macros to write out various integral values. 573*f8fb3368SJohn Marino * 574*f8fb3368SJohn Marino * Note: 575*f8fb3368SJohn Marino * - The destination pointer could be unaligned. 576*f8fb3368SJohn Marino * - Values are written out in native byte order. 577*f8fb3368SJohn Marino * - The destination pointer is incremented after the write. 578*f8fb3368SJohn Marino */ 579*f8fb3368SJohn Marino#define WRITE_BYTE(P,X) do { \ 580*f8fb3368SJohn Marino unsigned char *const _p = (unsigned char *) (P); \ 581*f8fb3368SJohn Marino _p[0] = (unsigned char) (X); \ 582*f8fb3368SJohn Marino (P) = _p + 1; \ 583*f8fb3368SJohn Marino } while (0) 584*f8fb3368SJohn Marino#define WRITE_HALF(P,X) do { \ 585*f8fb3368SJohn Marino uint16_t _t = (X); \ 586*f8fb3368SJohn Marino unsigned char *const _p = (unsigned char *) (P); \ 587*f8fb3368SJohn Marino const unsigned char *const _q = (unsigned char *) &_t; \ 588*f8fb3368SJohn Marino _p[0] = _q[0]; \ 589*f8fb3368SJohn Marino _p[1] = _q[1]; \ 590*f8fb3368SJohn Marino (P) = _p + 2; \ 591*f8fb3368SJohn Marino } while (0) 592*f8fb3368SJohn Marino#define WRITE_WORD(P,X) do { \ 593*f8fb3368SJohn Marino uint32_t _t = (uint32_t) (X); \ 594*f8fb3368SJohn Marino unsigned char *const _p = (unsigned char *) (P); \ 595*f8fb3368SJohn Marino const unsigned char *const _q = (unsigned char *) &_t; \ 596*f8fb3368SJohn Marino _p[0] = _q[0]; \ 597*f8fb3368SJohn Marino _p[1] = _q[1]; \ 598*f8fb3368SJohn Marino _p[2] = _q[2]; \ 599*f8fb3368SJohn Marino _p[3] = _q[3]; \ 600*f8fb3368SJohn Marino (P) = _p + 4; \ 601*f8fb3368SJohn Marino } while (0) 602*f8fb3368SJohn Marino#define WRITE_ADDR32(P,X) WRITE_WORD(P,X) 603*f8fb3368SJohn Marino#define WRITE_OFF32(P,X) WRITE_WORD(P,X) 604*f8fb3368SJohn Marino#define WRITE_SWORD(P,X) WRITE_WORD(P,X) 605*f8fb3368SJohn Marino#define WRITE_WORD64(P,X) do { \ 606*f8fb3368SJohn Marino uint64_t _t = (uint64_t) (X); \ 607*f8fb3368SJohn Marino unsigned char *const _p = (unsigned char *) (P); \ 608*f8fb3368SJohn Marino const unsigned char *const _q = (unsigned char *) &_t; \ 609*f8fb3368SJohn Marino _p[0] = _q[0]; \ 610*f8fb3368SJohn Marino _p[1] = _q[1]; \ 611*f8fb3368SJohn Marino _p[2] = _q[2]; \ 612*f8fb3368SJohn Marino _p[3] = _q[3]; \ 613*f8fb3368SJohn Marino _p[4] = _q[4]; \ 614*f8fb3368SJohn Marino _p[5] = _q[5]; \ 615*f8fb3368SJohn Marino _p[6] = _q[6]; \ 616*f8fb3368SJohn Marino _p[7] = _q[7]; \ 617*f8fb3368SJohn Marino (P) = _p + 8; \ 618*f8fb3368SJohn Marino } while (0) 619*f8fb3368SJohn Marino#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) 620*f8fb3368SJohn Marino#define WRITE_LWORD(P,X) WRITE_WORD64(P,X) 621*f8fb3368SJohn Marino#define WRITE_OFF64(P,X) WRITE_WORD64(P,X) 622*f8fb3368SJohn Marino#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) 623*f8fb3368SJohn Marino#define WRITE_XWORD(P,X) WRITE_WORD64(P,X) 624*f8fb3368SJohn Marino#define WRITE_IDENT(P,X) do { \ 625*f8fb3368SJohn Marino (void) memcpy((P), (X), sizeof((X))); \ 626*f8fb3368SJohn Marino (P) = (P) + EI_NIDENT; \ 627*f8fb3368SJohn Marino } while (0) 628*f8fb3368SJohn Marino 629*f8fb3368SJohn Marino/* 630*f8fb3368SJohn Marino * C macros to read in various integral values. 631*f8fb3368SJohn Marino * 632*f8fb3368SJohn Marino * Note: 633*f8fb3368SJohn Marino * - The source pointer could be unaligned. 634*f8fb3368SJohn Marino * - Values are read in native byte order. 635*f8fb3368SJohn Marino * - The source pointer is incremented appropriately. 636*f8fb3368SJohn Marino */ 637*f8fb3368SJohn Marino 638*f8fb3368SJohn Marino#define READ_BYTE(P,X) do { \ 639*f8fb3368SJohn Marino const unsigned char *const _p = \ 640*f8fb3368SJohn Marino (const unsigned char *) (P); \ 641*f8fb3368SJohn Marino (X) = _p[0]; \ 642*f8fb3368SJohn Marino (P) = (P) + 1; \ 643*f8fb3368SJohn Marino } while (0) 644*f8fb3368SJohn Marino#define READ_HALF(P,X) do { \ 645*f8fb3368SJohn Marino uint16_t _t; \ 646*f8fb3368SJohn Marino unsigned char *const _q = (unsigned char *) &_t; \ 647*f8fb3368SJohn Marino const unsigned char *const _p = \ 648*f8fb3368SJohn Marino (const unsigned char *) (P); \ 649*f8fb3368SJohn Marino _q[0] = _p[0]; \ 650*f8fb3368SJohn Marino _q[1] = _p[1]; \ 651*f8fb3368SJohn Marino (P) = (P) + 2; \ 652*f8fb3368SJohn Marino (X) = _t; \ 653*f8fb3368SJohn Marino } while (0) 654*f8fb3368SJohn Marino#define _READ_WORD(P,X,T) do { \ 655*f8fb3368SJohn Marino uint32_t _t; \ 656*f8fb3368SJohn Marino unsigned char *const _q = (unsigned char *) &_t; \ 657*f8fb3368SJohn Marino const unsigned char *const _p = \ 658*f8fb3368SJohn Marino (const unsigned char *) (P); \ 659*f8fb3368SJohn Marino _q[0] = _p[0]; \ 660*f8fb3368SJohn Marino _q[1] = _p[1]; \ 661*f8fb3368SJohn Marino _q[2] = _p[2]; \ 662*f8fb3368SJohn Marino _q[3] = _p[3]; \ 663*f8fb3368SJohn Marino (P) = (P) + 4; \ 664*f8fb3368SJohn Marino (X) = (T) _t; \ 665*f8fb3368SJohn Marino } while (0) 666*f8fb3368SJohn Marino#define READ_ADDR32(P,X) _READ_WORD(P, X, Elf32_Addr) 667*f8fb3368SJohn Marino#define READ_OFF32(P,X) _READ_WORD(P, X, Elf32_Off) 668*f8fb3368SJohn Marino#define READ_SWORD(P,X) _READ_WORD(P, X, Elf32_Sword) 669*f8fb3368SJohn Marino#define READ_WORD(P,X) _READ_WORD(P, X, Elf32_Word) 670*f8fb3368SJohn Marino#define _READ_WORD64(P,X,T) do { \ 671*f8fb3368SJohn Marino uint64_t _t; \ 672*f8fb3368SJohn Marino unsigned char *const _q = (unsigned char *) &_t; \ 673*f8fb3368SJohn Marino const unsigned char *const _p = \ 674*f8fb3368SJohn Marino (const unsigned char *) (P); \ 675*f8fb3368SJohn Marino _q[0] = _p[0]; \ 676*f8fb3368SJohn Marino _q[1] = _p[1]; \ 677*f8fb3368SJohn Marino _q[2] = _p[2]; \ 678*f8fb3368SJohn Marino _q[3] = _p[3]; \ 679*f8fb3368SJohn Marino _q[4] = _p[4]; \ 680*f8fb3368SJohn Marino _q[5] = _p[5]; \ 681*f8fb3368SJohn Marino _q[6] = _p[6]; \ 682*f8fb3368SJohn Marino _q[7] = _p[7]; \ 683*f8fb3368SJohn Marino (P) = (P) + 8; \ 684*f8fb3368SJohn Marino (X) = (T) _t; \ 685*f8fb3368SJohn Marino } while (0) 686*f8fb3368SJohn Marino#define READ_ADDR64(P,X) _READ_WORD64(P, X, Elf64_Addr) 687*f8fb3368SJohn Marino#define READ_LWORD(P,X) _READ_WORD64(P, X, Elf64_Lword) 688*f8fb3368SJohn Marino#define READ_OFF64(P,X) _READ_WORD64(P, X, Elf64_Off) 689*f8fb3368SJohn Marino#define READ_SXWORD(P,X) _READ_WORD64(P, X, Elf64_Sxword) 690*f8fb3368SJohn Marino#define READ_XWORD(P,X) _READ_WORD64(P, X, Elf64_Xword) 691*f8fb3368SJohn Marino#define READ_IDENT(P,X) do { \ 692*f8fb3368SJohn Marino (void) memcpy((X), (P), sizeof((X))); \ 693*f8fb3368SJohn Marino (P) = (P) + EI_NIDENT; \ 694*f8fb3368SJohn Marino } while (0) 695*f8fb3368SJohn Marino 696*f8fb3368SJohn Marino#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) 697*f8fb3368SJohn Marino 698*f8fb3368SJohn Marino/*[*/ 699*f8fb3368SJohn MarinoMAKE_TYPE_CONVERTERS(ELF_TYPE_LIST) 700*f8fb3368SJohn MarinoMAKE_VERSION_CONVERTERS(VDEF,Verdef,Verdaux,vd) 701*f8fb3368SJohn MarinoMAKE_VERSION_CONVERTERS(VNEED,Verneed,Vernaux,vn) 702*f8fb3368SJohn Marino/*]*/ 703*f8fb3368SJohn Marino 704*f8fb3368SJohn Marino/* 705*f8fb3368SJohn Marino * Sections of type ELF_T_BYTE are never byteswapped, consequently a 706*f8fb3368SJohn Marino * simple memcpy suffices for both directions of conversion. 707*f8fb3368SJohn Marino */ 708*f8fb3368SJohn Marino 709*f8fb3368SJohn Marinostatic int 710*f8fb3368SJohn Marino_libelf_cvt_BYTE_tox(unsigned char *dst, size_t dsz, unsigned char *src, 711*f8fb3368SJohn Marino size_t count, int byteswap) 712*f8fb3368SJohn Marino{ 713*f8fb3368SJohn Marino (void) byteswap; 714*f8fb3368SJohn Marino if (dsz < count) 715*f8fb3368SJohn Marino return (0); 716*f8fb3368SJohn Marino if (dst != src) 717*f8fb3368SJohn Marino (void) memcpy(dst, src, count); 718*f8fb3368SJohn Marino return (1); 719*f8fb3368SJohn Marino} 720*f8fb3368SJohn Marino 721*f8fb3368SJohn Marino/* 722*f8fb3368SJohn Marino * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit 723*f8fb3368SJohn Marino * words. Bloom filter data comes next, followed by hash buckets and the 724*f8fb3368SJohn Marino * hash chain. 725*f8fb3368SJohn Marino * 726*f8fb3368SJohn Marino * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit 727*f8fb3368SJohn Marino * wide on ELFCLASS32 objects. The other objects in this section are 32 728*f8fb3368SJohn Marino * bits wide. 729*f8fb3368SJohn Marino * 730*f8fb3368SJohn Marino * Argument `srcsz' denotes the number of bytes to be converted. In the 731*f8fb3368SJohn Marino * 32-bit case we need to translate `srcsz' to a count of 32-bit words. 732*f8fb3368SJohn Marino */ 733*f8fb3368SJohn Marino 734*f8fb3368SJohn Marinostatic int 735*f8fb3368SJohn Marino_libelf_cvt_GNUHASH32_tom(unsigned char *dst, size_t dsz, unsigned char *src, 736*f8fb3368SJohn Marino size_t srcsz, int byteswap) 737*f8fb3368SJohn Marino{ 738*f8fb3368SJohn Marino return (_libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t), 739*f8fb3368SJohn Marino byteswap)); 740*f8fb3368SJohn Marino} 741*f8fb3368SJohn Marino 742*f8fb3368SJohn Marinostatic int 743*f8fb3368SJohn Marino_libelf_cvt_GNUHASH32_tof(unsigned char *dst, size_t dsz, unsigned char *src, 744*f8fb3368SJohn Marino size_t srcsz, int byteswap) 745*f8fb3368SJohn Marino{ 746*f8fb3368SJohn Marino return (_libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t), 747*f8fb3368SJohn Marino byteswap)); 748*f8fb3368SJohn Marino} 749*f8fb3368SJohn Marino 750*f8fb3368SJohn Marinostatic int 751*f8fb3368SJohn Marino_libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 752*f8fb3368SJohn Marino size_t srcsz, int byteswap) 753*f8fb3368SJohn Marino{ 754*f8fb3368SJohn Marino size_t sz; 755*f8fb3368SJohn Marino uint64_t t64, *bloom64; 756*f8fb3368SJohn Marino Elf_GNU_Hash_Header *gh; 757*f8fb3368SJohn Marino uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; 758*f8fb3368SJohn Marino uint32_t *buckets, *chains; 759*f8fb3368SJohn Marino 760*f8fb3368SJohn Marino sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ 761*f8fb3368SJohn Marino if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) 762*f8fb3368SJohn Marino return (0); 763*f8fb3368SJohn Marino 764*f8fb3368SJohn Marino /* Read in the section header and byteswap if needed. */ 765*f8fb3368SJohn Marino READ_WORD(src, nbuckets); 766*f8fb3368SJohn Marino READ_WORD(src, symndx); 767*f8fb3368SJohn Marino READ_WORD(src, maskwords); 768*f8fb3368SJohn Marino READ_WORD(src, shift2); 769*f8fb3368SJohn Marino 770*f8fb3368SJohn Marino srcsz -= sz; 771*f8fb3368SJohn Marino 772*f8fb3368SJohn Marino if (byteswap) { 773*f8fb3368SJohn Marino SWAP_WORD(nbuckets); 774*f8fb3368SJohn Marino SWAP_WORD(symndx); 775*f8fb3368SJohn Marino SWAP_WORD(maskwords); 776*f8fb3368SJohn Marino SWAP_WORD(shift2); 777*f8fb3368SJohn Marino } 778*f8fb3368SJohn Marino 779*f8fb3368SJohn Marino /* Check source buffer and destination buffer sizes. */ 780*f8fb3368SJohn Marino sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); 781*f8fb3368SJohn Marino if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) 782*f8fb3368SJohn Marino return (0); 783*f8fb3368SJohn Marino 784*f8fb3368SJohn Marino gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; 785*f8fb3368SJohn Marino gh->gh_nbuckets = nbuckets; 786*f8fb3368SJohn Marino gh->gh_symndx = symndx; 787*f8fb3368SJohn Marino gh->gh_maskwords = maskwords; 788*f8fb3368SJohn Marino gh->gh_shift2 = shift2; 789*f8fb3368SJohn Marino 790*f8fb3368SJohn Marino dsz -= sizeof(Elf_GNU_Hash_Header); 791*f8fb3368SJohn Marino dst += sizeof(Elf_GNU_Hash_Header); 792*f8fb3368SJohn Marino 793*f8fb3368SJohn Marino bloom64 = (uint64_t *) (uintptr_t) dst; 794*f8fb3368SJohn Marino 795*f8fb3368SJohn Marino /* Copy bloom filter data. */ 796*f8fb3368SJohn Marino for (n = 0; n < maskwords; n++) { 797*f8fb3368SJohn Marino READ_XWORD(src, t64); 798*f8fb3368SJohn Marino if (byteswap) 799*f8fb3368SJohn Marino SWAP_XWORD(t64); 800*f8fb3368SJohn Marino bloom64[n] = t64; 801*f8fb3368SJohn Marino } 802*f8fb3368SJohn Marino 803*f8fb3368SJohn Marino /* The hash buckets follows the bloom filter. */ 804*f8fb3368SJohn Marino dst += maskwords * sizeof(uint64_t); 805*f8fb3368SJohn Marino buckets = (uint32_t *) (uintptr_t) dst; 806*f8fb3368SJohn Marino 807*f8fb3368SJohn Marino for (n = 0; n < nbuckets; n++) { 808*f8fb3368SJohn Marino READ_WORD(src, t32); 809*f8fb3368SJohn Marino if (byteswap) 810*f8fb3368SJohn Marino SWAP_WORD(t32); 811*f8fb3368SJohn Marino buckets[n] = t32; 812*f8fb3368SJohn Marino } 813*f8fb3368SJohn Marino 814*f8fb3368SJohn Marino dst += nbuckets * sizeof(uint32_t); 815*f8fb3368SJohn Marino 816*f8fb3368SJohn Marino /* The hash chain follows the hash buckets. */ 817*f8fb3368SJohn Marino dsz -= sz; 818*f8fb3368SJohn Marino srcsz -= sz; 819*f8fb3368SJohn Marino 820*f8fb3368SJohn Marino if (dsz < srcsz) /* Destination lacks space. */ 821*f8fb3368SJohn Marino return (0); 822*f8fb3368SJohn Marino 823*f8fb3368SJohn Marino nchains = srcsz / sizeof(uint32_t); 824*f8fb3368SJohn Marino chains = (uint32_t *) (uintptr_t) dst; 825*f8fb3368SJohn Marino 826*f8fb3368SJohn Marino for (n = 0; n < nchains; n++) { 827*f8fb3368SJohn Marino READ_WORD(src, t32); 828*f8fb3368SJohn Marino if (byteswap) 829*f8fb3368SJohn Marino SWAP_WORD(t32); 830*f8fb3368SJohn Marino *chains++ = t32; 831*f8fb3368SJohn Marino } 832*f8fb3368SJohn Marino 833*f8fb3368SJohn Marino return (1); 834*f8fb3368SJohn Marino} 835*f8fb3368SJohn Marino 836*f8fb3368SJohn Marinostatic int 837*f8fb3368SJohn Marino_libelf_cvt_GNUHASH64_tof(unsigned char *dst, size_t dsz, unsigned char *src, 838*f8fb3368SJohn Marino size_t srcsz, int byteswap) 839*f8fb3368SJohn Marino{ 840*f8fb3368SJohn Marino uint32_t *s32; 841*f8fb3368SJohn Marino size_t sz, hdrsz; 842*f8fb3368SJohn Marino uint64_t *s64, t64; 843*f8fb3368SJohn Marino Elf_GNU_Hash_Header *gh; 844*f8fb3368SJohn Marino uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32; 845*f8fb3368SJohn Marino 846*f8fb3368SJohn Marino hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */ 847*f8fb3368SJohn Marino if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header)) 848*f8fb3368SJohn Marino return (0); 849*f8fb3368SJohn Marino 850*f8fb3368SJohn Marino gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; 851*f8fb3368SJohn Marino 852*f8fb3368SJohn Marino t0 = nbuckets = gh->gh_nbuckets; 853*f8fb3368SJohn Marino t1 = gh->gh_symndx; 854*f8fb3368SJohn Marino t2 = maskwords = gh->gh_maskwords; 855*f8fb3368SJohn Marino t3 = gh->gh_shift2; 856*f8fb3368SJohn Marino 857*f8fb3368SJohn Marino src += sizeof(Elf_GNU_Hash_Header); 858*f8fb3368SJohn Marino srcsz -= sizeof(Elf_GNU_Hash_Header); 859*f8fb3368SJohn Marino dsz -= hdrsz; 860*f8fb3368SJohn Marino 861*f8fb3368SJohn Marino sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * 862*f8fb3368SJohn Marino sizeof(uint64_t); 863*f8fb3368SJohn Marino 864*f8fb3368SJohn Marino if (srcsz < sz || dsz < sz) 865*f8fb3368SJohn Marino return (0); 866*f8fb3368SJohn Marino 867*f8fb3368SJohn Marino /* Write out the header. */ 868*f8fb3368SJohn Marino if (byteswap) { 869*f8fb3368SJohn Marino SWAP_WORD(t0); 870*f8fb3368SJohn Marino SWAP_WORD(t1); 871*f8fb3368SJohn Marino SWAP_WORD(t2); 872*f8fb3368SJohn Marino SWAP_WORD(t3); 873*f8fb3368SJohn Marino } 874*f8fb3368SJohn Marino 875*f8fb3368SJohn Marino WRITE_WORD(dst, t0); 876*f8fb3368SJohn Marino WRITE_WORD(dst, t1); 877*f8fb3368SJohn Marino WRITE_WORD(dst, t2); 878*f8fb3368SJohn Marino WRITE_WORD(dst, t3); 879*f8fb3368SJohn Marino 880*f8fb3368SJohn Marino /* Copy the bloom filter and the hash table. */ 881*f8fb3368SJohn Marino s64 = (uint64_t *) (uintptr_t) src; 882*f8fb3368SJohn Marino for (n = 0; n < maskwords; n++) { 883*f8fb3368SJohn Marino t64 = *s64++; 884*f8fb3368SJohn Marino if (byteswap) 885*f8fb3368SJohn Marino SWAP_XWORD(t64); 886*f8fb3368SJohn Marino WRITE_WORD64(dst, t64); 887*f8fb3368SJohn Marino } 888*f8fb3368SJohn Marino 889*f8fb3368SJohn Marino s32 = (uint32_t *) s64; 890*f8fb3368SJohn Marino for (n = 0; n < nbuckets; n++) { 891*f8fb3368SJohn Marino t32 = *s32++; 892*f8fb3368SJohn Marino if (byteswap) 893*f8fb3368SJohn Marino SWAP_WORD(t32); 894*f8fb3368SJohn Marino WRITE_WORD(dst, t32); 895*f8fb3368SJohn Marino } 896*f8fb3368SJohn Marino 897*f8fb3368SJohn Marino srcsz -= sz; 898*f8fb3368SJohn Marino dsz -= sz; 899*f8fb3368SJohn Marino 900*f8fb3368SJohn Marino /* Copy out the hash chains. */ 901*f8fb3368SJohn Marino if (dsz < srcsz) 902*f8fb3368SJohn Marino return (0); 903*f8fb3368SJohn Marino 904*f8fb3368SJohn Marino nchains = srcsz / sizeof(uint32_t); 905*f8fb3368SJohn Marino for (n = 0; n < nchains; n++) { 906*f8fb3368SJohn Marino t32 = *s32++; 907*f8fb3368SJohn Marino if (byteswap) 908*f8fb3368SJohn Marino SWAP_WORD(t32); 909*f8fb3368SJohn Marino WRITE_WORD(dst, t32); 910*f8fb3368SJohn Marino } 911*f8fb3368SJohn Marino 912*f8fb3368SJohn Marino return (1); 913*f8fb3368SJohn Marino} 914*f8fb3368SJohn Marino 915*f8fb3368SJohn Marino/* 916*f8fb3368SJohn Marino * Elf_Note structures comprise a fixed size header followed by variable 917*f8fb3368SJohn Marino * length strings. The fixed size header needs to be byte swapped, but 918*f8fb3368SJohn Marino * not the strings. 919*f8fb3368SJohn Marino * 920*f8fb3368SJohn Marino * Argument `count' denotes the total number of bytes to be converted. 921*f8fb3368SJohn Marino * The destination buffer needs to be at least `count' bytes in size. 922*f8fb3368SJohn Marino */ 923*f8fb3368SJohn Marinostatic int 924*f8fb3368SJohn Marino_libelf_cvt_NOTE_tom(unsigned char *dst, size_t dsz, unsigned char *src, 925*f8fb3368SJohn Marino size_t count, int byteswap) 926*f8fb3368SJohn Marino{ 927*f8fb3368SJohn Marino uint32_t namesz, descsz, type; 928*f8fb3368SJohn Marino Elf_Note *en; 929*f8fb3368SJohn Marino size_t sz, hdrsz; 930*f8fb3368SJohn Marino 931*f8fb3368SJohn Marino if (dsz < count) /* Destination buffer is too small. */ 932*f8fb3368SJohn Marino return (0); 933*f8fb3368SJohn Marino 934*f8fb3368SJohn Marino hdrsz = 3 * sizeof(uint32_t); 935*f8fb3368SJohn Marino if (count < hdrsz) /* Source too small. */ 936*f8fb3368SJohn Marino return (0); 937*f8fb3368SJohn Marino 938*f8fb3368SJohn Marino if (!byteswap) { 939*f8fb3368SJohn Marino (void) memcpy(dst, src, count); 940*f8fb3368SJohn Marino return (1); 941*f8fb3368SJohn Marino } 942*f8fb3368SJohn Marino 943*f8fb3368SJohn Marino /* Process all notes in the section. */ 944*f8fb3368SJohn Marino while (count > hdrsz) { 945*f8fb3368SJohn Marino /* Read the note header. */ 946*f8fb3368SJohn Marino READ_WORD(src, namesz); 947*f8fb3368SJohn Marino READ_WORD(src, descsz); 948*f8fb3368SJohn Marino READ_WORD(src, type); 949*f8fb3368SJohn Marino 950*f8fb3368SJohn Marino /* Translate. */ 951*f8fb3368SJohn Marino SWAP_WORD(namesz); 952*f8fb3368SJohn Marino SWAP_WORD(descsz); 953*f8fb3368SJohn Marino SWAP_WORD(type); 954*f8fb3368SJohn Marino 955*f8fb3368SJohn Marino /* Copy out the translated note header. */ 956*f8fb3368SJohn Marino en = (Elf_Note *) (uintptr_t) dst; 957*f8fb3368SJohn Marino en->n_namesz = namesz; 958*f8fb3368SJohn Marino en->n_descsz = descsz; 959*f8fb3368SJohn Marino en->n_type = type; 960*f8fb3368SJohn Marino 961*f8fb3368SJohn Marino dsz -= sizeof(Elf_Note); 962*f8fb3368SJohn Marino dst += sizeof(Elf_Note); 963*f8fb3368SJohn Marino count -= hdrsz; 964*f8fb3368SJohn Marino 965*f8fb3368SJohn Marino ROUNDUP2(namesz, 4U); 966*f8fb3368SJohn Marino ROUNDUP2(descsz, 4U); 967*f8fb3368SJohn Marino 968*f8fb3368SJohn Marino sz = namesz + descsz; 969*f8fb3368SJohn Marino 970*f8fb3368SJohn Marino if (count < sz || dsz < sz) /* Buffers are too small. */ 971*f8fb3368SJohn Marino return (0); 972*f8fb3368SJohn Marino 973*f8fb3368SJohn Marino (void) memcpy(dst, src, sz); 974*f8fb3368SJohn Marino 975*f8fb3368SJohn Marino src += sz; 976*f8fb3368SJohn Marino dst += sz; 977*f8fb3368SJohn Marino 978*f8fb3368SJohn Marino count -= sz; 979*f8fb3368SJohn Marino dsz -= sz; 980*f8fb3368SJohn Marino } 981*f8fb3368SJohn Marino 982*f8fb3368SJohn Marino return (1); 983*f8fb3368SJohn Marino} 984*f8fb3368SJohn Marino 985*f8fb3368SJohn Marinostatic int 986*f8fb3368SJohn Marino_libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src, 987*f8fb3368SJohn Marino size_t count, int byteswap) 988*f8fb3368SJohn Marino{ 989*f8fb3368SJohn Marino uint32_t namesz, descsz, type; 990*f8fb3368SJohn Marino Elf_Note *en; 991*f8fb3368SJohn Marino size_t sz; 992*f8fb3368SJohn Marino 993*f8fb3368SJohn Marino if (dsz < count) 994*f8fb3368SJohn Marino return (0); 995*f8fb3368SJohn Marino 996*f8fb3368SJohn Marino if (!byteswap) { 997*f8fb3368SJohn Marino (void) memcpy(dst, src, count); 998*f8fb3368SJohn Marino return (1); 999*f8fb3368SJohn Marino } 1000*f8fb3368SJohn Marino 1001*f8fb3368SJohn Marino while (count > sizeof(Elf_Note)) { 1002*f8fb3368SJohn Marino 1003*f8fb3368SJohn Marino en = (Elf_Note *) (uintptr_t) src; 1004*f8fb3368SJohn Marino namesz = en->n_namesz; 1005*f8fb3368SJohn Marino descsz = en->n_descsz; 1006*f8fb3368SJohn Marino type = en->n_type; 1007*f8fb3368SJohn Marino 1008*f8fb3368SJohn Marino sz = namesz; 1009*f8fb3368SJohn Marino ROUNDUP2(sz, 4U); 1010*f8fb3368SJohn Marino sz += descsz; 1011*f8fb3368SJohn Marino ROUNDUP2(sz, 4U); 1012*f8fb3368SJohn Marino 1013*f8fb3368SJohn Marino SWAP_WORD(namesz); 1014*f8fb3368SJohn Marino SWAP_WORD(descsz); 1015*f8fb3368SJohn Marino SWAP_WORD(type); 1016*f8fb3368SJohn Marino 1017*f8fb3368SJohn Marino WRITE_WORD(dst, namesz); 1018*f8fb3368SJohn Marino WRITE_WORD(dst, descsz); 1019*f8fb3368SJohn Marino WRITE_WORD(dst, type); 1020*f8fb3368SJohn Marino 1021*f8fb3368SJohn Marino src += sizeof(Elf_Note); 1022*f8fb3368SJohn Marino 1023*f8fb3368SJohn Marino if (count < sz) 1024*f8fb3368SJohn Marino sz = count; 1025*f8fb3368SJohn Marino 1026*f8fb3368SJohn Marino (void) memcpy(dst, src, sz); 1027*f8fb3368SJohn Marino 1028*f8fb3368SJohn Marino src += sz; 1029*f8fb3368SJohn Marino dst += sz; 1030*f8fb3368SJohn Marino count -= sz; 1031*f8fb3368SJohn Marino } 1032*f8fb3368SJohn Marino 1033*f8fb3368SJohn Marino return (1); 1034*f8fb3368SJohn Marino} 1035*f8fb3368SJohn Marino 1036*f8fb3368SJohn Marinostruct converters { 1037*f8fb3368SJohn Marino int (*tof32)(unsigned char *dst, size_t dsz, unsigned char *src, 1038*f8fb3368SJohn Marino size_t cnt, int byteswap); 1039*f8fb3368SJohn Marino int (*tom32)(unsigned char *dst, size_t dsz, unsigned char *src, 1040*f8fb3368SJohn Marino size_t cnt, int byteswap); 1041*f8fb3368SJohn Marino int (*tof64)(unsigned char *dst, size_t dsz, unsigned char *src, 1042*f8fb3368SJohn Marino size_t cnt, int byteswap); 1043*f8fb3368SJohn Marino int (*tom64)(unsigned char *dst, size_t dsz, unsigned char *src, 1044*f8fb3368SJohn Marino size_t cnt, int byteswap); 1045*f8fb3368SJohn Marino}; 1046*f8fb3368SJohn Marino 1047*f8fb3368SJohn Marino 1048*f8fb3368SJohn Marinostatic struct converters cvt[ELF_T_NUM] = { 1049*f8fb3368SJohn Marino /*[*/ 1050*f8fb3368SJohn MarinoCONVERTER_NAMES(ELF_TYPE_LIST) 1051*f8fb3368SJohn Marino /*]*/ 1052*f8fb3368SJohn Marino 1053*f8fb3368SJohn Marino /* 1054*f8fb3368SJohn Marino * Types that need hand-coded converters follow. 1055*f8fb3368SJohn Marino */ 1056*f8fb3368SJohn Marino 1057*f8fb3368SJohn Marino [ELF_T_BYTE] = { 1058*f8fb3368SJohn Marino .tof32 = _libelf_cvt_BYTE_tox, 1059*f8fb3368SJohn Marino .tom32 = _libelf_cvt_BYTE_tox, 1060*f8fb3368SJohn Marino .tof64 = _libelf_cvt_BYTE_tox, 1061*f8fb3368SJohn Marino .tom64 = _libelf_cvt_BYTE_tox 1062*f8fb3368SJohn Marino }, 1063*f8fb3368SJohn Marino 1064*f8fb3368SJohn Marino [ELF_T_NOTE] = { 1065*f8fb3368SJohn Marino .tof32 = _libelf_cvt_NOTE_tof, 1066*f8fb3368SJohn Marino .tom32 = _libelf_cvt_NOTE_tom, 1067*f8fb3368SJohn Marino .tof64 = _libelf_cvt_NOTE_tof, 1068*f8fb3368SJohn Marino .tom64 = _libelf_cvt_NOTE_tom 1069*f8fb3368SJohn Marino } 1070*f8fb3368SJohn Marino}; 1071*f8fb3368SJohn Marino 1072*f8fb3368SJohn Marinoint (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) 1073*f8fb3368SJohn Marino (unsigned char *_dst, size_t dsz, unsigned char *_src, size_t _cnt, 1074*f8fb3368SJohn Marino int _byteswap) 1075*f8fb3368SJohn Marino{ 1076*f8fb3368SJohn Marino assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); 1077*f8fb3368SJohn Marino assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); 1078*f8fb3368SJohn Marino 1079*f8fb3368SJohn Marino if (t >= ELF_T_NUM || 1080*f8fb3368SJohn Marino (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) || 1081*f8fb3368SJohn Marino (direction != ELF_TOFILE && direction != ELF_TOMEMORY)) 1082*f8fb3368SJohn Marino return (NULL); 1083*f8fb3368SJohn Marino 1084*f8fb3368SJohn Marino return ((elfclass == ELFCLASS32) ? 1085*f8fb3368SJohn Marino (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : 1086*f8fb3368SJohn Marino (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); 1087*f8fb3368SJohn Marino} 1088