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