1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include <libelf.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 28 /** 29 * TODO: This is an intial and crude attempt to access structure 30 * fields of some ELF structrures. Need to figure out a way to access the 31 * given field of a given structure instead of writing one shim function 32 * per access of each of the structure field. 33 **/ 34 35 #define STRINGIFYHELPER(x) #x 36 #define STRINGIFY(x) STRINGIFYHELPER(x) 37 #define FUNC_NAME(S, F) set_ ## S ## _ ## F 38 #define CAST_STRUCT(S, F) ((Elf_ ## S *) structPtr) 39 #define CAST_STRUCT32(S, F) ((Elf32_ ## S *) structPtr) 40 #define CAST_STRUCT64(S, F) ((Elf64_ ## S *) structPtr) 41 #define ACCESS_FIELD(S, F) CAST_STRUCT(S, F)-> F 42 #define ACCESS_FIELD32(S, F) CAST_STRUCT32(S, F)-> F 43 #define ACCESS_FIELD64(S, F) CAST_STRUCT64(S, F)-> F 44 45 /* 46 Example: 47 SET_TYPE_BASED_FIELD(Ehdr, e_machine, int) 48 expands to 49 set_Ehdr_e_machine(int elfclass, void * strPtr, int val) { 50 } 51 */ 52 53 #define SET_TYPE_BASED_FIELD(S, F, T) \ 54 void FUNC_NAME(S, F)(int elfclass, void * structPtr, T val) { \ 55 if (elfclass == ELFCLASS32) { \ 56 ACCESS_FIELD32(S, F) = val; \ 57 } else if (elfclass == ELFCLASS64) { \ 58 ACCESS_FIELD64(S, F) = val; \ 59 } else { \ 60 printf("%s: Unknown ELF Class %d provided\n", STRINGIFY(FUNC_NAME(S, F)), elfclass); \ 61 } \ 62 return; \ 63 } 64 65 /* 66 Example: 67 SET_FIELD(Ehdr, e_machine, int) 68 expands to 69 set_Ehdr_e_machine(void * strPtr, int val) { 70 } 71 */ 72 73 #define SET_FIELD(S, F, T) \ 74 void FUNC_NAME(S, F)(void * structPtr, T val) { \ 75 ACCESS_FIELD(S, F) = val; \ 76 return; \ 77 } 78 79 int size_of_Sym(int elfclass) { 80 if (elfclass == ELFCLASS32) { 81 return sizeof(Elf32_Sym); 82 } else if (elfclass == ELFCLASS64) { 83 return sizeof(Elf64_Sym); 84 } else { 85 printf("Unknown ELF Class %d provided\n", elfclass); 86 } 87 return -1; 88 } 89 90 int size_of_Rela(int elfclass) { 91 if (elfclass == ELFCLASS32) { 92 return sizeof(Elf32_Rela); 93 } else if (elfclass == ELFCLASS64) { 94 return sizeof(Elf64_Rela); 95 } else { 96 printf("Unknown ELF Class %d provided\n", elfclass); 97 } 98 return -1; 99 } 100 101 int size_of_Rel(int elfclass) { 102 if (elfclass == ELFCLASS32) { 103 return sizeof(Elf32_Rel); 104 } else if (elfclass == ELFCLASS64) { 105 return sizeof(Elf64_Rel); 106 } else { 107 printf("Unknown ELF Class %d provided\n", elfclass); 108 } 109 return -1; 110 } 111 112 /* ELF Header field access */ 113 114 void ehdr_set_data_encoding(void * ehdr, int val) { 115 ((Elf32_Ehdr *) ehdr)->e_ident[EI_DATA] = val; 116 return; 117 } 118 119 SET_TYPE_BASED_FIELD(Ehdr, e_machine, int) 120 SET_TYPE_BASED_FIELD(Ehdr, e_type, int) 121 SET_TYPE_BASED_FIELD(Ehdr, e_version, int) 122 SET_TYPE_BASED_FIELD(Ehdr, e_shstrndx, int) 123 124 /* Data descriptor field access */ 125 SET_FIELD(Data, d_align, int) 126 SET_FIELD(Data, d_off, int) 127 SET_FIELD(Data, d_buf, void*) 128 SET_FIELD(Data, d_type, int) 129 SET_FIELD(Data, d_size, int) 130 SET_FIELD(Data, d_version, int) 131 132 /* Section Header Access functions */ 133 SET_TYPE_BASED_FIELD(Shdr, sh_name, int) 134 SET_TYPE_BASED_FIELD(Shdr, sh_type, int) 135 SET_TYPE_BASED_FIELD(Shdr, sh_flags, int) 136 SET_TYPE_BASED_FIELD(Shdr, sh_entsize, int) 137 SET_TYPE_BASED_FIELD(Shdr, sh_link, int) 138 SET_TYPE_BASED_FIELD(Shdr, sh_info, int) 139 140 /* Set the Program Header to be of PH_PHDR type and initialize other 141 related fields of the program header. 142 */ 143 void phdr_set_type_self(int elfclass, void * ehdr, void * phdr) { 144 if (elfclass == ELFCLASS32) { 145 Elf32_Ehdr * ehdr32 = (Elf32_Ehdr *) ehdr; 146 Elf32_Phdr * phdr32 = (Elf32_Phdr *) phdr; 147 phdr32->p_type = PT_PHDR; 148 phdr32->p_offset = ehdr32->e_phoff; 149 phdr32->p_filesz = elf32_fsize(ELF_T_PHDR, 1, EV_CURRENT); 150 } else if (elfclass == ELFCLASS64) { 151 Elf64_Ehdr * ehdr64 = (Elf64_Ehdr *) ehdr; 152 Elf64_Phdr * phdr64 = (Elf64_Phdr *) phdr; 153 phdr64->p_type = PT_PHDR; 154 phdr64->p_offset = ehdr64->e_phoff; 155 phdr64->p_filesz = elf64_fsize(ELF_T_PHDR, 1, EV_CURRENT); 156 } else { 157 printf("phdr_set_type_self: Unknown ELF Class %d provided\n", elfclass); 158 } 159 return; 160 } 161 162 /* 163 Create symbol table entry with given type and binding 164 */ 165 void * create_sym_entry(int elfclass, int index, int type, int bind, 166 int shndx, int size, int value) { 167 void * symentry = NULL; 168 if (elfclass == ELFCLASS32) { 169 Elf32_Sym * sym32 = (Elf32_Sym *) malloc(sizeof(Elf32_Sym)); 170 sym32->st_name = index; 171 sym32->st_value = value; 172 sym32->st_size = size; 173 sym32->st_info = ELF32_ST_INFO(bind, type); 174 sym32->st_other = 0; // TODO: Add an argument to get this value ?? 175 sym32->st_shndx = shndx; 176 symentry = sym32; 177 } else if (elfclass == ELFCLASS64) { 178 Elf64_Sym * sym64 = (Elf64_Sym *) malloc(sizeof(Elf64_Sym)); 179 sym64->st_name = index; 180 sym64->st_value = value; 181 sym64->st_size = size; 182 sym64->st_info = ELF64_ST_INFO(bind, type); 183 sym64->st_other = 0; // TODO: Add an argument to get this value ?? 184 sym64->st_shndx = shndx; 185 symentry = sym64; 186 } else { 187 printf("create_sym_entry: Unknown ELF Class %d provided\n", elfclass); 188 } 189 return (void *) symentry; 190 } 191 192 // Create a reloc (or reloca entry if argument reloca is non-zero) 193 void * create_reloc_entry(int elfclass, int roffset, int symtabIdx, 194 int relocType, int raddend, int reloca) { 195 void * relocentry = NULL; 196 if (elfclass == ELFCLASS32) { 197 if (reloca) { 198 Elf32_Rela * rela32 = (Elf32_Rela *) malloc(sizeof(Elf32_Rela)); 199 rela32->r_offset = roffset; 200 rela32->r_info = ELF32_R_INFO(symtabIdx, relocType); 201 rela32->r_addend = raddend; 202 relocentry = rela32; 203 } else { 204 Elf32_Rel * rel32 = (Elf32_Rel *) malloc(sizeof(Elf32_Rel)); 205 rel32->r_offset = roffset; 206 rel32->r_info = ELF32_R_INFO(symtabIdx, relocType); 207 relocentry = rel32; 208 } 209 } else if (elfclass == ELFCLASS64) { 210 if (reloca) { 211 Elf64_Rela * rela64 = (Elf64_Rela *) malloc(sizeof(Elf64_Rela)); 212 rela64->r_offset = roffset; 213 rela64->r_info = ELF64_R_INFO(symtabIdx, relocType); 214 rela64->r_addend = raddend; 215 relocentry = rela64; 216 } else { 217 Elf64_Rel * rel64 = (Elf64_Rel *) malloc(sizeof(Elf64_Rel)); 218 rel64->r_offset = roffset; 219 rel64->r_info = ELF64_R_INFO(symtabIdx, relocType); 220 relocentry = rel64; 221 } 222 } else { 223 printf("create_reloc_entry: Unknown ELF Class %d provided\n", elfclass); 224 } 225 return (void *) relocentry; 226 }