Home | History | Annotate | Download | only in libelf
      1 /* Transformation functions for ELF data types.
      2    Copyright (C) 1998, 1999, 2000, 2002, 2004 Red Hat, Inc.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 1998.
      4 
      5    This program is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation, version 2.
      8 
      9    This program is distributed in the hope that it will be useful,
     10    but WITHOUT ANY WARRANTY; without even the implied warranty of
     11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12    GNU General Public License for more details.
     13 
     14    You should have received a copy of the GNU General Public License
     15    along with this program; if not, write to the Free Software Foundation,
     16    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
     17 
     18 #ifdef HAVE_CONFIG_H
     19 # include <config.h>
     20 #endif
     21 
     22 //#include <byteswap.h>
     23 #include <stdint.h>
     24 #include <string.h>
     25 
     26 #include "libelfP.h"
     27 
     28 #ifndef LIBELFBITS
     29 # define LIBELFBITS	32
     30 #endif
     31 
     32 
     33 /* Well, what shall I say.  Nothing to do here.  */
     34 #define elf_cvt_Byte(dest, src, n) \
     35   (__builtin_constant_p (n) && (n) == 1					      \
     36    ? (void) (*((char *) (dest)) = *((char *) (src)))			      \
     37    : Elf32_cvt_Byte (dest, src, n))
     38 static void
     39 (elf_cvt_Byte) (void *dest, const void *src, size_t n, int encode)
     40 {
     41   memmove (dest, src, n);
     42 }
     43 
     44 
     45 /* We'll optimize the definition of the conversion functions here a
     46    bit.  We need only functions for 16, 32, and 64 bits.  The
     47    functions referenced in the table will be aliases for one of these
     48    functions.  Which one is decided by the ELFxx_FSZ_type.  */
     49 #define LEN2_SWAP(Src)  bswap_16 (*((uint16_t *) Src))
     50 #define word2_t uint16_t
     51 
     52 #define LEN4_SWAP(Src)  bswap_32 (*((uint32_t *) Src))
     53 #define word4_t uint32_t
     54 
     55 #define LEN8_SWAP(Src)  bswap_64 (*((uint64_t *) Src))
     56 #define word8_t uint64_t
     57 
     58 
     59 /* Now define the conversion functions for the basic types.  We use here
     60    the fact that file and memory types are the same and that we have the
     61    ELFxx_FSZ_* macros.
     62 
     63    At the same time we define inline functions which we will use to
     64    convert the complex types.  */
     65 #define FUNDAMENTAL(NAME, Name, Bits) \
     66   INLINE2 (ELFW2(Bits,FSZ_##NAME), ElfW2(Bits,cvt_##Name), ElfW2(Bits,Name))
     67 #define INLINE2(Bytes, FName, TName) \
     68   INLINE3 (Bytes, FName, TName)
     69 #define INLINE3(Bytes, FName, TName) \
     70   static void FName (void *dest, const void *ptr, size_t len, int encode)     \
     71   {									      \
     72     size_t n = len / sizeof (TName);					      \
     73     if (dest < ptr)							      \
     74       {									      \
     75 	word##Bytes##_t *tdest = (word##Bytes##_t *) dest;		      \
     76         const word##Bytes##_t *tptr = (const word##Bytes##_t *) ptr;	      \
     77         while (n-- > 0)							      \
     78 	  {								      \
     79 	    *tdest++ = LEN##Bytes##_SWAP (tptr);			      \
     80 	    tptr++;							      \
     81 	  }								      \
     82       }									      \
     83     else								      \
     84       {									      \
     85 	word##Bytes##_t *tdest = (word##Bytes##_t *) dest + n;		      \
     86 	const word##Bytes##_t *tptr = (const word##Bytes##_t *) ptr + n;      \
     87 	while (n-- > 0)							      \
     88 	  {								      \
     89 	    --tptr;							      \
     90 	    *--tdest = LEN##Bytes##_SWAP (tptr);			      \
     91 	  }								      \
     92       }									      \
     93  }									      \
     94 									      \
     95   static inline void FName##1 (void *dest, const void *ptr)		      \
     96   {									      \
     97     *((word##Bytes##_t *) dest) =					      \
     98       LEN##Bytes##_SWAP ((((word##Bytes##_t *) ptr)));			      \
     99   }
    100 
    101 
    102 /* Now the tricky part: define the transformation functions for the
    103    complex types.  We will use the definitions of the types in
    104    abstract.h.  */
    105 #define START(Bits, Name, EName) \
    106   static void								      \
    107   ElfW2 (Bits, cvt_##Name) (void *dest, const void *src, size_t len,	      \
    108 			    int encode)					      \
    109   { ElfW2(Bits, Name) *tdest = (ElfW2(Bits, Name) *) dest;		      \
    110     ElfW2(Bits, Name) *tsrc = (ElfW2(Bits, Name) *) src;		      \
    111     size_t n = len / sizeof (ElfW2(Bits, Name));			      \
    112     for (; n > 0; ++tdest, ++tsrc, --n) {
    113 #define END(Bits, Name) } }
    114 #define TYPE_EXTRA(Code)
    115 #define TYPE_XLATE(Code) Code
    116 #define TYPE_NAME(Type, Name) TYPE_NAME2 (Type, Name)
    117 #define TYPE_NAME2(Type, Name) Type##1 (&tdest->Name, &tsrc->Name);
    118 #define TYPE(Name, Bits) TYPE2 (Name, Bits)
    119 #define TYPE2(Name, Bits) TYPE3 (Name##Bits)
    120 #define TYPE3(Name) Name (cvt_)
    121 
    122 /* Signal that we are generating conversion functions.  */
    123 #define GENERATE_CONVERSION
    124 
    125 /* First generate the 32-bit conversion functions.  */
    126 #define LIBELFBITS 32
    127 #include "gelf_xlate.h"
    128 
    129 /* Now generate the 64-bit conversion functions.  */
    130 #define LIBELFBITS 64
    131 #include "gelf_xlate.h"
    132 
    133 
    134 /* We have a few functions which we must create by hand since the sections
    135    do not contain records of only one type.  */
    136 #include "version_xlate.h"
    137 
    138 
    139 /* Now the externally visible table with the function pointers.  */
    140 const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
    141 {
    142   [EV_CURRENT - 1] = {
    143     [EV_CURRENT - 1] = {
    144       [ELFCLASS32 - 1] = {
    145 #define define_xfcts(Bits) \
    146 	[ELF_T_BYTE]	= elf_cvt_Byte,					      \
    147 	[ELF_T_ADDR]	= ElfW2(Bits, cvt_Addr),			      \
    148 	[ELF_T_DYN]	= ElfW2(Bits, cvt_Dyn),				      \
    149 	[ELF_T_EHDR]	= ElfW2(Bits, cvt_Ehdr),			      \
    150 	[ELF_T_HALF]	= ElfW2(Bits, cvt_Half),			      \
    151 	[ELF_T_OFF]	= ElfW2(Bits, cvt_Off),				      \
    152 	[ELF_T_PHDR]	= ElfW2(Bits, cvt_Phdr),			      \
    153 	[ELF_T_RELA]	= ElfW2(Bits, cvt_Rela),			      \
    154 	[ELF_T_REL]	= ElfW2(Bits, cvt_Rel),				      \
    155 	[ELF_T_SHDR]	= ElfW2(Bits, cvt_Shdr),			      \
    156 	[ELF_T_SWORD]	= ElfW2(Bits, cvt_Sword),			      \
    157 	[ELF_T_SYM]	= ElfW2(Bits, cvt_Sym),				      \
    158 	[ELF_T_WORD]	= ElfW2(Bits, cvt_Word),			      \
    159 	[ELF_T_XWORD]	= ElfW2(Bits, cvt_Xword),			      \
    160 	[ELF_T_SXWORD]	= ElfW2(Bits, cvt_Sxword),			      \
    161 	[ELF_T_VDEF]	= elf_cvt_Verdef,				      \
    162 	[ELF_T_VDAUX]	= elf_cvt_Verdef,				      \
    163 	[ELF_T_VNEED]	= elf_cvt_Verneed,				      \
    164 	[ELF_T_VNAUX]	= elf_cvt_Verneed,				      \
    165 	[ELF_T_NHDR]	= ElfW2(Bits, cvt_Nhdr),			      \
    166 	[ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo),			      \
    167 	[ELF_T_MOVE]	= ElfW2(Bits, cvt_Move),			      \
    168 	[ELF_T_LIB]	= ElfW2(Bits, cvt_Lib)
    169         define_xfcts (32)
    170       },
    171       [ELFCLASS64 - 1] = {
    172 	define_xfcts (64)
    173       }
    174     }
    175   }
    176 };
    177 /* For now we only handle the case where the memory representation is the
    178    same as the file representation.  Should this change we have to define
    179    separate functions.  For now reuse them.  */
    180 //strong_alias (__elf_xfctstom, __elf_xfctstof)
    181