Blame libelf/gelf_xlate.c

Packit 032894
/* Transformation functions for ELF data types.
Packit 032894
   Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007,2015 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifdef HAVE_CONFIG_H
Packit 032894
# include <config.h>
Packit 032894
#endif
Packit 032894
Packit 032894
#include <byteswap.h>
Packit 032894
#include <stdint.h>
Packit 032894
#include <string.h>
Packit 032894
#include <stdlib.h>
Packit 032894
Packit 032894
#include "libelfP.h"
Packit 032894
Packit 032894
#ifndef LIBELFBITS
Packit 032894
# define LIBELFBITS	32
Packit 032894
#endif
Packit 032894
Packit 032894
Packit 032894
/* Well, what shall I say.  Nothing to do here.  */
Packit 032894
#define elf_cvt_Byte(dest, src, n) \
Packit 032894
  (__builtin_constant_p (n) && (n) == 1					      \
Packit 032894
   ? (void) (*((char *) (dest)) = *((char *) (src)))			      \
Packit 032894
   : Elf32_cvt_Byte (dest, src, n))
Packit 032894
static void
Packit 032894
(elf_cvt_Byte) (void *dest, const void *src, size_t n,
Packit 032894
		int encode __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  if (n != 0)
Packit 032894
    memmove (dest, src, n);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
/* We'll optimize the definition of the conversion functions here a
Packit 032894
   bit.  We need only functions for 16, 32, and 64 bits.  The
Packit 032894
   functions referenced in the table will be aliases for one of these
Packit 032894
   functions.  Which one is decided by the ELFxx_FSZ_type.  */
Packit 032894
Packit 032894
#if ALLOW_UNALIGNED
Packit 032894
Packit 032894
#define FETCH(Bits, ptr)	(*(const uint##Bits##_t *) ptr)
Packit 032894
#define STORE(Bits, ptr, val)	(*(uint##Bits##_t *) ptr = val)
Packit 032894
Packit 032894
#else
Packit 032894
Packit 032894
union unaligned
Packit 032894
  {
Packit 032894
    uint16_t u16;
Packit 032894
    uint32_t u32;
Packit 032894
    uint64_t u64;
Packit 032894
  } attribute_packed;
Packit 032894
Packit 032894
#define FETCH(Bits, ptr)	(((const union unaligned *) ptr)->u##Bits)
Packit 032894
#define STORE(Bits, ptr, val)	(((union unaligned *) ptr)->u##Bits = val)
Packit 032894
Packit 032894
#endif
Packit 032894
Packit 032894
/* Now define the conversion functions for the basic types.  We use here
Packit 032894
   the fact that file and memory types are the same and that we have the
Packit 032894
   ELFxx_FSZ_* macros.
Packit 032894
Packit 032894
   At the same time we define inline functions which we will use to
Packit 032894
   convert the complex types.  */
Packit 032894
#define FUNDAMENTAL(NAME, Name, Bits) \
Packit 032894
  INLINE2 (ELFW2(Bits,FSZ_##NAME), ElfW2(Bits,cvt_##Name), ElfW2(Bits,Name))
Packit 032894
#define INLINE2(Bytes, FName, TName) \
Packit 032894
  INLINE3 (Bytes, FName, TName)
Packit 032894
#define INLINE3(Bytes, FName, TName)					      \
Packit 032894
  static inline void FName##1 (void *dest, const void *ptr)		      \
Packit 032894
  {									      \
Packit 032894
    switch (Bytes)							      \
Packit 032894
      {									      \
Packit 032894
      case 2: STORE (16, dest, bswap_16 (FETCH (16, ptr))); break;	      \
Packit 032894
      case 4: STORE (32, dest, bswap_32 (FETCH (32, ptr))); break;	      \
Packit 032894
      case 8: STORE (64, dest, bswap_64 (FETCH (64, ptr))); break;	      \
Packit 032894
      default:								      \
Packit 032894
	abort ();							      \
Packit 032894
      }									      \
Packit 032894
  }									      \
Packit 032894
									      \
Packit 032894
  static void FName (void *dest, const void *ptr, size_t len,		      \
Packit 032894
		     int encode __attribute__ ((unused)))		      \
Packit 032894
  {									      \
Packit 032894
    size_t n = len / sizeof (TName);					      \
Packit 032894
    if (dest < ptr)							      \
Packit 032894
      while (n-- > 0)							      \
Packit 032894
	{								      \
Packit 032894
	  FName##1 (dest, ptr);						      \
Packit 032894
	  dest += Bytes;						      \
Packit 032894
	  ptr += Bytes;							      \
Packit 032894
	}								      \
Packit 032894
    else								      \
Packit 032894
      {									      \
Packit 032894
	dest += len;							      \
Packit 032894
	ptr += len;							      \
Packit 032894
	while (n-- > 0)							      \
Packit 032894
	  {								      \
Packit 032894
	    ptr -= Bytes;						      \
Packit 032894
	    dest -= Bytes;						      \
Packit 032894
	    FName##1 (dest, ptr);					      \
Packit 032894
	  }								      \
Packit 032894
      }									      \
Packit 032894
  }
Packit 032894
Packit 032894
Packit 032894
/* Now the tricky part: define the transformation functions for the
Packit 032894
   complex types.  We will use the definitions of the types in
Packit 032894
   abstract.h.  */
Packit 032894
#define START(Bits, Name, EName) \
Packit 032894
  static void								      \
Packit 032894
  ElfW2 (Bits, cvt_##Name) (void *dest, const void *src, size_t len,	      \
Packit 032894
			    int encode __attribute__ ((unused)))	      \
Packit 032894
  { ElfW2(Bits, Name) *tdest = (ElfW2(Bits, Name) *) dest;		      \
Packit 032894
    ElfW2(Bits, Name) *tsrc = (ElfW2(Bits, Name) *) src;		      \
Packit 032894
    size_t n;								      \
Packit 032894
    for (n = len / sizeof (ElfW2(Bits, Name)); n > 0; ++tdest, ++tsrc, --n) {
Packit 032894
#define END(Bits, Name) } }
Packit 032894
#define TYPE_EXTRA(Code)
Packit 032894
#define TYPE_XLATE(Code) Code
Packit 032894
#define TYPE_NAME(Type, Name) TYPE_NAME2 (Type, Name)
Packit 032894
#define TYPE_NAME2(Type, Name) Type##1 (&tdest->Name, &tsrc->Name);
Packit 032894
#define TYPE(Name, Bits) TYPE2 (Name, Bits)
Packit 032894
#define TYPE2(Name, Bits) TYPE3 (Name##Bits)
Packit 032894
#define TYPE3(Name) Name (cvt_)
Packit 032894
Packit 032894
/* Signal that we are generating conversion functions.  */
Packit 032894
#define GENERATE_CONVERSION
Packit 032894
Packit 032894
/* First generate the 32-bit conversion functions.  */
Packit 032894
#define LIBELFBITS 32
Packit 032894
#include "gelf_xlate.h"
Packit 032894
Packit 032894
/* Now generate the 64-bit conversion functions.  */
Packit 032894
#define LIBELFBITS 64
Packit 032894
#include "gelf_xlate.h"
Packit 032894
Packit 032894
Packit 032894
/* We have a few functions which we must create by hand since the sections
Packit 032894
   do not contain records of only one type.  */
Packit 032894
#include "version_xlate.h"
Packit 032894
#include "gnuhash_xlate.h"
Packit 032894
#include "note_xlate.h"
Packit 032894
#include "chdr_xlate.h"
Packit 032894
Packit 032894
Packit 032894
/* Now the externally visible table with the function pointers.  */
Packit 032894
const xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM] =
Packit 032894
{
Packit 032894
      [ELFCLASS32 - 1] = {
Packit 032894
#define define_xfcts(Bits) \
Packit 032894
	[ELF_T_BYTE]	= elf_cvt_Byte,					      \
Packit 032894
	[ELF_T_ADDR]	= ElfW2(Bits, cvt_Addr),			      \
Packit 032894
	[ELF_T_DYN]	= ElfW2(Bits, cvt_Dyn),				      \
Packit 032894
	[ELF_T_EHDR]	= ElfW2(Bits, cvt_Ehdr),			      \
Packit 032894
	[ELF_T_HALF]	= ElfW2(Bits, cvt_Half),			      \
Packit 032894
	[ELF_T_OFF]	= ElfW2(Bits, cvt_Off),				      \
Packit 032894
	[ELF_T_PHDR]	= ElfW2(Bits, cvt_Phdr),			      \
Packit 032894
	[ELF_T_RELA]	= ElfW2(Bits, cvt_Rela),			      \
Packit 032894
	[ELF_T_REL]	= ElfW2(Bits, cvt_Rel),				      \
Packit 032894
	[ELF_T_SHDR]	= ElfW2(Bits, cvt_Shdr),			      \
Packit 032894
	[ELF_T_SWORD]	= ElfW2(Bits, cvt_Sword),			      \
Packit 032894
	[ELF_T_SYM]	= ElfW2(Bits, cvt_Sym),				      \
Packit 032894
	[ELF_T_WORD]	= ElfW2(Bits, cvt_Word),			      \
Packit 032894
	[ELF_T_XWORD]	= ElfW2(Bits, cvt_Xword),			      \
Packit 032894
	[ELF_T_SXWORD]	= ElfW2(Bits, cvt_Sxword),			      \
Packit 032894
	[ELF_T_VDEF]	= elf_cvt_Verdef,				      \
Packit 032894
	[ELF_T_VDAUX]	= elf_cvt_Verdef,				      \
Packit 032894
	[ELF_T_VNEED]	= elf_cvt_Verneed,				      \
Packit 032894
	[ELF_T_VNAUX]	= elf_cvt_Verneed,				      \
Packit 032894
	[ELF_T_NHDR]	= elf_cvt_note4,				      \
Packit 032894
	[ELF_T_NHDR8]	= elf_cvt_note8,				      \
Packit 032894
	[ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo),			      \
Packit 032894
	[ELF_T_MOVE]	= ElfW2(Bits, cvt_Move),			      \
Packit 032894
	[ELF_T_LIB]	= ElfW2(Bits, cvt_Lib),				      \
Packit 032894
	[ELF_T_AUXV]	= ElfW2(Bits, cvt_auxv_t),			      \
Packit 032894
	[ELF_T_CHDR]	= ElfW2(Bits, cvt_chdr)
Packit 032894
        define_xfcts (32),
Packit 032894
	[ELF_T_GNUHASH] = Elf32_cvt_Word
Packit 032894
      },
Packit 032894
      [ELFCLASS64 - 1] = {
Packit 032894
	define_xfcts (64),
Packit 032894
	[ELF_T_GNUHASH] = elf_cvt_gnuhash
Packit 032894
      }
Packit 032894
};