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