Blame libelf/gelf_xlate.c

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