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