1da0c48c4Sopenharmony_ci/* Transformation functions for ELF data types.
2da0c48c4Sopenharmony_ci   Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007,2015 Red Hat, Inc.
3da0c48c4Sopenharmony_ci   Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
4da0c48c4Sopenharmony_ci   This file is part of elfutils.
5da0c48c4Sopenharmony_ci   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
6da0c48c4Sopenharmony_ci
7da0c48c4Sopenharmony_ci   This file is free software; you can redistribute it and/or modify
8da0c48c4Sopenharmony_ci   it under the terms of either
9da0c48c4Sopenharmony_ci
10da0c48c4Sopenharmony_ci     * the GNU Lesser General Public License as published by the Free
11da0c48c4Sopenharmony_ci       Software Foundation; either version 3 of the License, or (at
12da0c48c4Sopenharmony_ci       your option) any later version
13da0c48c4Sopenharmony_ci
14da0c48c4Sopenharmony_ci   or
15da0c48c4Sopenharmony_ci
16da0c48c4Sopenharmony_ci     * the GNU General Public License as published by the Free
17da0c48c4Sopenharmony_ci       Software Foundation; either version 2 of the License, or (at
18da0c48c4Sopenharmony_ci       your option) any later version
19da0c48c4Sopenharmony_ci
20da0c48c4Sopenharmony_ci   or both in parallel, as here.
21da0c48c4Sopenharmony_ci
22da0c48c4Sopenharmony_ci   elfutils is distributed in the hope that it will be useful, but
23da0c48c4Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
24da0c48c4Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25da0c48c4Sopenharmony_ci   General Public License for more details.
26da0c48c4Sopenharmony_ci
27da0c48c4Sopenharmony_ci   You should have received copies of the GNU General Public License and
28da0c48c4Sopenharmony_ci   the GNU Lesser General Public License along with this program.  If
29da0c48c4Sopenharmony_ci   not, see <http://www.gnu.org/licenses/>.  */
30da0c48c4Sopenharmony_ci
31da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H
32da0c48c4Sopenharmony_ci# include <config.h>
33da0c48c4Sopenharmony_ci#endif
34da0c48c4Sopenharmony_ci
35da0c48c4Sopenharmony_ci#include <stdint.h>
36da0c48c4Sopenharmony_ci#include <string.h>
37da0c48c4Sopenharmony_ci#include <stdlib.h>
38da0c48c4Sopenharmony_ci
39da0c48c4Sopenharmony_ci#include "libelfP.h"
40da0c48c4Sopenharmony_ci
41da0c48c4Sopenharmony_ci#ifndef LIBELFBITS
42da0c48c4Sopenharmony_ci# define LIBELFBITS	32
43da0c48c4Sopenharmony_ci#endif
44da0c48c4Sopenharmony_ci
45da0c48c4Sopenharmony_ci
46da0c48c4Sopenharmony_ci/* Well, what shall I say.  Nothing to do here.  */
47da0c48c4Sopenharmony_ci#define elf_cvt_Byte(dest, src, n) \
48da0c48c4Sopenharmony_ci  (__builtin_constant_p (n) && (n) == 1					      \
49da0c48c4Sopenharmony_ci   ? (void) (*((char *) (dest)) = *((char *) (src)))			      \
50da0c48c4Sopenharmony_ci   : Elf32_cvt_Byte (dest, src, n))
51da0c48c4Sopenharmony_cistatic void
52da0c48c4Sopenharmony_ci(elf_cvt_Byte) (void *dest, const void *src, size_t n,
53da0c48c4Sopenharmony_ci		int encode __attribute__ ((unused)))
54da0c48c4Sopenharmony_ci{
55da0c48c4Sopenharmony_ci  if (n != 0)
56da0c48c4Sopenharmony_ci    memmove (dest, src, n);
57da0c48c4Sopenharmony_ci}
58da0c48c4Sopenharmony_ci
59da0c48c4Sopenharmony_ci
60da0c48c4Sopenharmony_ci/* We'll optimize the definition of the conversion functions here a
61da0c48c4Sopenharmony_ci   bit.  We need only functions for 16, 32, and 64 bits.  The
62da0c48c4Sopenharmony_ci   functions referenced in the table will be aliases for one of these
63da0c48c4Sopenharmony_ci   functions.  Which one is decided by the ELFxx_FSZ_type.  */
64da0c48c4Sopenharmony_ci
65da0c48c4Sopenharmony_ci#if ALLOW_UNALIGNED
66da0c48c4Sopenharmony_ci
67da0c48c4Sopenharmony_ci#define FETCH(Bits, ptr)	(*(const uint##Bits##_t *) ptr)
68da0c48c4Sopenharmony_ci#define STORE(Bits, ptr, val)	(*(uint##Bits##_t *) ptr = val)
69da0c48c4Sopenharmony_ci
70da0c48c4Sopenharmony_ci#else
71da0c48c4Sopenharmony_ci
72da0c48c4Sopenharmony_ciunion unaligned
73da0c48c4Sopenharmony_ci  {
74da0c48c4Sopenharmony_ci    uint16_t u16;
75da0c48c4Sopenharmony_ci    uint32_t u32;
76da0c48c4Sopenharmony_ci    uint64_t u64;
77da0c48c4Sopenharmony_ci  } attribute_packed;
78da0c48c4Sopenharmony_ci
79da0c48c4Sopenharmony_ci#define FETCH(Bits, ptr)	(((const union unaligned *) ptr)->u##Bits)
80da0c48c4Sopenharmony_ci#define STORE(Bits, ptr, val)	(((union unaligned *) ptr)->u##Bits = val)
81da0c48c4Sopenharmony_ci
82da0c48c4Sopenharmony_ci#endif
83da0c48c4Sopenharmony_ci
84da0c48c4Sopenharmony_ci/* Now define the conversion functions for the basic types.  We use here
85da0c48c4Sopenharmony_ci   the fact that file and memory types are the same and that we have the
86da0c48c4Sopenharmony_ci   ELFxx_FSZ_* macros.
87da0c48c4Sopenharmony_ci
88da0c48c4Sopenharmony_ci   At the same time we define inline functions which we will use to
89da0c48c4Sopenharmony_ci   convert the complex types.  */
90da0c48c4Sopenharmony_ci#define FUNDAMENTAL(NAME, Name, Bits) \
91da0c48c4Sopenharmony_ci  INLINE2 (ELFW2(Bits,FSZ_##NAME), ElfW2(Bits,cvt_##Name), ElfW2(Bits,Name))
92da0c48c4Sopenharmony_ci#define INLINE2(Bytes, FName, TName) \
93da0c48c4Sopenharmony_ci  INLINE3 (Bytes, FName, TName)
94da0c48c4Sopenharmony_ci#define INLINE3(Bytes, FName, TName)					      \
95da0c48c4Sopenharmony_ci  static inline void FName##1 (void *dest, const void *ptr)		      \
96da0c48c4Sopenharmony_ci  {									      \
97da0c48c4Sopenharmony_ci    switch (Bytes)							      \
98da0c48c4Sopenharmony_ci      {									      \
99da0c48c4Sopenharmony_ci      case 2: STORE (16, dest, bswap_16 (FETCH (16, ptr))); break;	      \
100da0c48c4Sopenharmony_ci      case 4: STORE (32, dest, bswap_32 (FETCH (32, ptr))); break;	      \
101da0c48c4Sopenharmony_ci      case 8: STORE (64, dest, bswap_64 (FETCH (64, ptr))); break;	      \
102da0c48c4Sopenharmony_ci      default:								      \
103da0c48c4Sopenharmony_ci	abort ();							      \
104da0c48c4Sopenharmony_ci      }									      \
105da0c48c4Sopenharmony_ci  }									      \
106da0c48c4Sopenharmony_ci									      \
107da0c48c4Sopenharmony_ci  static void FName (void *dest, const void *ptr, size_t len,		      \
108da0c48c4Sopenharmony_ci		     int encode __attribute__ ((unused)))		      \
109da0c48c4Sopenharmony_ci  {									      \
110da0c48c4Sopenharmony_ci    size_t n = len / sizeof (TName);					      \
111da0c48c4Sopenharmony_ci    if (dest < ptr)							      \
112da0c48c4Sopenharmony_ci      while (n-- > 0)							      \
113da0c48c4Sopenharmony_ci	{								      \
114da0c48c4Sopenharmony_ci	  FName##1 (dest, ptr);						      \
115da0c48c4Sopenharmony_ci	  dest += Bytes;						      \
116da0c48c4Sopenharmony_ci	  ptr += Bytes;							      \
117da0c48c4Sopenharmony_ci	}								      \
118da0c48c4Sopenharmony_ci    else								      \
119da0c48c4Sopenharmony_ci      {									      \
120da0c48c4Sopenharmony_ci	dest += len;							      \
121da0c48c4Sopenharmony_ci	ptr += len;							      \
122da0c48c4Sopenharmony_ci	while (n-- > 0)							      \
123da0c48c4Sopenharmony_ci	  {								      \
124da0c48c4Sopenharmony_ci	    ptr -= Bytes;						      \
125da0c48c4Sopenharmony_ci	    dest -= Bytes;						      \
126da0c48c4Sopenharmony_ci	    FName##1 (dest, ptr);					      \
127da0c48c4Sopenharmony_ci	  }								      \
128da0c48c4Sopenharmony_ci      }									      \
129da0c48c4Sopenharmony_ci  }
130da0c48c4Sopenharmony_ci
131da0c48c4Sopenharmony_ci
132da0c48c4Sopenharmony_ci/* Now the tricky part: define the transformation functions for the
133da0c48c4Sopenharmony_ci   complex types.  We will use the definitions of the types in
134da0c48c4Sopenharmony_ci   abstract.h.  */
135da0c48c4Sopenharmony_ci#define START(Bits, Name, EName) \
136da0c48c4Sopenharmony_ci  static void								      \
137da0c48c4Sopenharmony_ci  ElfW2 (Bits, cvt_##Name) (void *dest, const void *src, size_t len,	      \
138da0c48c4Sopenharmony_ci			    int encode __attribute__ ((unused)))	      \
139da0c48c4Sopenharmony_ci  { ElfW2(Bits, Name) *tdest = (ElfW2(Bits, Name) *) dest;		      \
140da0c48c4Sopenharmony_ci    ElfW2(Bits, Name) *tsrc = (ElfW2(Bits, Name) *) src;		      \
141da0c48c4Sopenharmony_ci    size_t sz = sizeof (ElfW2(Bits, Name));				      \
142da0c48c4Sopenharmony_ci    size_t n;								      \
143da0c48c4Sopenharmony_ci    for (n = len / sz; n > 0; ++tdest, ++tsrc, --n) {
144da0c48c4Sopenharmony_ci#define END(Bits, Name)							      \
145da0c48c4Sopenharmony_ci    }									      \
146da0c48c4Sopenharmony_ci    if (len % sz > 0) /* Cannot convert partial structures, just copy. */     \
147da0c48c4Sopenharmony_ci      memmove (dest, src, len % sz);					      \
148da0c48c4Sopenharmony_ci  }
149da0c48c4Sopenharmony_ci#define TYPE_EXTRA(Code)
150da0c48c4Sopenharmony_ci#define TYPE_XLATE(Code) Code
151da0c48c4Sopenharmony_ci#define TYPE_NAME(Type, Name) TYPE_NAME2 (Type, Name)
152da0c48c4Sopenharmony_ci#define TYPE_NAME2(Type, Name) Type##1 (&tdest->Name, &tsrc->Name);
153da0c48c4Sopenharmony_ci#define TYPE(Name, Bits) TYPE2 (Name, Bits)
154da0c48c4Sopenharmony_ci#define TYPE2(Name, Bits) TYPE3 (Name##Bits)
155da0c48c4Sopenharmony_ci#define TYPE3(Name) Name (cvt_)
156da0c48c4Sopenharmony_ci
157da0c48c4Sopenharmony_ci/* Signal that we are generating conversion functions.  */
158da0c48c4Sopenharmony_ci#define GENERATE_CONVERSION
159da0c48c4Sopenharmony_ci
160da0c48c4Sopenharmony_ci/* First generate the 32-bit conversion functions.  */
161da0c48c4Sopenharmony_ci#define LIBELFBITS 32
162da0c48c4Sopenharmony_ci#include "gelf_xlate.h"
163da0c48c4Sopenharmony_ci
164da0c48c4Sopenharmony_ci/* Now generate the 64-bit conversion functions.  */
165da0c48c4Sopenharmony_ci#define LIBELFBITS 64
166da0c48c4Sopenharmony_ci#include "gelf_xlate.h"
167da0c48c4Sopenharmony_ci
168da0c48c4Sopenharmony_ci
169da0c48c4Sopenharmony_ci/* We have a few functions which we must create by hand since the sections
170da0c48c4Sopenharmony_ci   do not contain records of only one type.  */
171da0c48c4Sopenharmony_ci#include "version_xlate.h"
172da0c48c4Sopenharmony_ci#include "gnuhash_xlate.h"
173da0c48c4Sopenharmony_ci#include "note_xlate.h"
174da0c48c4Sopenharmony_ci#include "chdr_xlate.h"
175da0c48c4Sopenharmony_ci
176da0c48c4Sopenharmony_ci
177da0c48c4Sopenharmony_ci/* Now the externally visible table with the function pointers.  */
178da0c48c4Sopenharmony_ciconst xfct_t __elf_xfctstom[ELFCLASSNUM - 1][ELF_T_NUM] =
179da0c48c4Sopenharmony_ci{
180da0c48c4Sopenharmony_ci      [ELFCLASS32 - 1] = {
181da0c48c4Sopenharmony_ci#define define_xfcts(Bits) \
182da0c48c4Sopenharmony_ci	[ELF_T_BYTE]	= elf_cvt_Byte,					      \
183da0c48c4Sopenharmony_ci	[ELF_T_ADDR]	= ElfW2(Bits, cvt_Addr),			      \
184da0c48c4Sopenharmony_ci	[ELF_T_DYN]	= ElfW2(Bits, cvt_Dyn),				      \
185da0c48c4Sopenharmony_ci	[ELF_T_EHDR]	= ElfW2(Bits, cvt_Ehdr),			      \
186da0c48c4Sopenharmony_ci	[ELF_T_HALF]	= ElfW2(Bits, cvt_Half),			      \
187da0c48c4Sopenharmony_ci	[ELF_T_OFF]	= ElfW2(Bits, cvt_Off),				      \
188da0c48c4Sopenharmony_ci	[ELF_T_PHDR]	= ElfW2(Bits, cvt_Phdr),			      \
189da0c48c4Sopenharmony_ci	[ELF_T_RELA]	= ElfW2(Bits, cvt_Rela),			      \
190da0c48c4Sopenharmony_ci	[ELF_T_REL]	= ElfW2(Bits, cvt_Rel),				      \
191da0c48c4Sopenharmony_ci	[ELF_T_SHDR]	= ElfW2(Bits, cvt_Shdr),			      \
192da0c48c4Sopenharmony_ci	[ELF_T_SWORD]	= ElfW2(Bits, cvt_Sword),			      \
193da0c48c4Sopenharmony_ci	[ELF_T_SYM]	= ElfW2(Bits, cvt_Sym),				      \
194da0c48c4Sopenharmony_ci	[ELF_T_WORD]	= ElfW2(Bits, cvt_Word),			      \
195da0c48c4Sopenharmony_ci	[ELF_T_XWORD]	= ElfW2(Bits, cvt_Xword),			      \
196da0c48c4Sopenharmony_ci	[ELF_T_SXWORD]	= ElfW2(Bits, cvt_Sxword),			      \
197da0c48c4Sopenharmony_ci	[ELF_T_VDEF]	= elf_cvt_Verdef,				      \
198da0c48c4Sopenharmony_ci	[ELF_T_VDAUX]	= elf_cvt_Verdef,				      \
199da0c48c4Sopenharmony_ci	[ELF_T_VNEED]	= elf_cvt_Verneed,				      \
200da0c48c4Sopenharmony_ci	[ELF_T_VNAUX]	= elf_cvt_Verneed,				      \
201da0c48c4Sopenharmony_ci	[ELF_T_NHDR]	= elf_cvt_note4,				      \
202da0c48c4Sopenharmony_ci	[ELF_T_NHDR8]	= elf_cvt_note8,				      \
203da0c48c4Sopenharmony_ci	[ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo),			      \
204da0c48c4Sopenharmony_ci	[ELF_T_MOVE]	= ElfW2(Bits, cvt_Move),			      \
205da0c48c4Sopenharmony_ci	[ELF_T_LIB]	= ElfW2(Bits, cvt_Lib),				      \
206da0c48c4Sopenharmony_ci	[ELF_T_AUXV]	= ElfW2(Bits, cvt_auxv_t),			      \
207da0c48c4Sopenharmony_ci	[ELF_T_CHDR]	= ElfW2(Bits, cvt_chdr)
208da0c48c4Sopenharmony_ci        define_xfcts (32),
209da0c48c4Sopenharmony_ci	[ELF_T_GNUHASH] = Elf32_cvt_Word
210da0c48c4Sopenharmony_ci      },
211da0c48c4Sopenharmony_ci      [ELFCLASS64 - 1] = {
212da0c48c4Sopenharmony_ci	define_xfcts (64),
213da0c48c4Sopenharmony_ci	[ELF_T_GNUHASH] = elf_cvt_gnuhash
214da0c48c4Sopenharmony_ci      }
215da0c48c4Sopenharmony_ci};
216