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