1/* 2 * Copyright (c) 1999-2004 University of New South Wales 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <strops.h> 8#include <binaries/elf/elf.h> 9 10/* 11 * Checks that elfFile points to a valid elf file. Returns 0 if the elf 12 * file is valid, < 0 if invalid. 13 */ 14 15int 16elf_checkFile(void *elfFile) 17{ 18 return ISELF32 (elfFile) 19 ? elf32_checkFile(elfFile) 20 : elf64_checkFile(elfFile); 21} 22 23/* Program Headers Access functions */ 24uint16_t 25elf_getNumProgramHeaders(void *elfFile) 26{ 27 return ISELF32 (elfFile) 28 ? elf32_getNumProgramHeaders(elfFile) 29 : elf64_getNumProgramHeaders(elfFile); 30} 31 32uint32_t 33elf_getProgramHeaderFlags(void *elfFile, uint16_t ph) 34{ 35 return ISELF32 (elfFile) 36 ? elf32_getProgramHeaderFlags(elfFile, ph) 37 : elf64_getProgramHeaderFlags(elfFile, ph); 38} 39 40uint32_t 41elf_getProgramHeaderType(void *elfFile, uint16_t ph) 42{ 43 return ISELF32 (elfFile) 44 ? elf32_getProgramHeaderType(elfFile, ph) 45 : elf64_getProgramHeaderType(elfFile, ph); 46} 47 48uint64_t 49elf_getProgramHeaderPaddr(void *elfFile, uint16_t ph) 50{ 51 return ISELF32 (elfFile) 52 ? elf32_getProgramHeaderPaddr(elfFile, ph) 53 : elf64_getProgramHeaderPaddr(elfFile, ph); 54} 55 56uint64_t 57elf_getProgramHeaderVaddr(void *elfFile, uint16_t ph) 58{ 59 return ISELF32 (elfFile) 60 ? elf32_getProgramHeaderVaddr(elfFile, ph) 61 : elf64_getProgramHeaderVaddr(elfFile, ph); 62} 63 64uint64_t 65elf_getProgramHeaderMemorySize(void *elfFile, uint16_t ph) 66{ 67 return ISELF32 (elfFile) 68 ? elf32_getProgramHeaderMemorySize(elfFile, ph) 69 : elf64_getProgramHeaderMemorySize(elfFile, ph); 70} 71 72uint64_t 73elf_getProgramHeaderFileSize(void *elfFile, uint16_t ph) 74{ 75 return ISELF32 (elfFile) 76 ? elf32_getProgramHeaderFileSize(elfFile, ph) 77 : elf64_getProgramHeaderFileSize(elfFile, ph); 78} 79 80uint64_t 81elf_getProgramHeaderOffset(void *elfFile, uint16_t ph) 82{ 83 return ISELF32 (elfFile) 84 ? elf32_getProgramHeaderOffset(elfFile, ph) 85 : elf64_getProgramHeaderOffset(elfFile, ph); 86} 87 88char * 89elf_getSegmentStringTable(void *elfFile) 90{ 91 return ISELF32 (elfFile) 92 ? elf32_getSegmentStringTable(elfFile) 93 : elf64_getSegmentStringTable(elfFile); 94} 95 96char * 97elf_getStringTable(void *elfFile, int string_segment) 98{ 99 return ISELF32 (elfFile) 100 ? elf32_getStringTable(elfFile) 101 : elf64_getStringTable(elfFile, string_segment); 102} 103 104unsigned 105elf_getNumSections(void *elfFile) 106{ 107 return ISELF32 (elfFile) 108 ? elf32_getNumSections(elfFile) 109 : elf64_getNumSections(elfFile); 110} 111 112char * 113elf_getSectionName(void *elfFile, int i) 114{ 115 return ISELF32 (elfFile) 116 ? elf32_getSectionName(elfFile, i) 117 : elf64_getSectionName(elfFile, i); 118} 119 120uint32_t 121elf_getSectionFlags(void *elfFile, int i) 122{ 123 return ISELF32 (elfFile) 124 ? elf32_getSectionFlags(elfFile, i) 125 : elf64_getSectionFlags(elfFile, i); 126} 127 128uint32_t 129elf_getSectionType(void *elfFile, int i) 130{ 131 return ISELF32 (elfFile) 132 ? elf32_getSectionType(elfFile, i) 133 : elf64_getSectionType(elfFile, i); 134} 135 136uint64_t 137elf_getSectionSize(void *elfFile, int i) 138{ 139 return ISELF32 (elfFile) 140 ? elf32_getSectionSize(elfFile, i) 141 : elf64_getSectionSize(elfFile, i); 142} 143 144uint64_t 145elf_getSectionAddr(void *elfFile, int i) 146{ 147 return ISELF32 (elfFile) 148 ? elf32_getSectionAddr(elfFile, i) 149 : elf64_getSectionAddr(elfFile, i); 150} 151 152void * 153elf_getSection(void *elfFile, int i) 154{ 155 return ISELF32 (elfFile) 156 ? elf32_getSection(elfFile, i) 157 : elf64_getSection(elfFile, i); 158} 159 160void * 161elf_getSectionNamed(void *elfFile, char *_str) 162{ 163 return ISELF32 (elfFile) 164 ? elf32_getSectionNamed(elfFile, _str) 165 : elf64_getSectionNamed(elfFile, _str); 166} 167 168void 169elf_getProgramHeaderInfo(void *elfFile, uint16_t ph, uint64_t *p_vaddr, 170 uint64_t *p_paddr, uint64_t *p_filesz, uint64_t *p_offset, 171 uint64_t *p_memsz) 172{ 173 *p_vaddr = elf_getProgramHeaderVaddr(elfFile, ph); 174 *p_paddr = elf_getProgramHeaderPaddr(elfFile, ph); 175 *p_filesz = elf_getProgramHeaderFileSize(elfFile, ph); 176 *p_offset = elf_getProgramHeaderOffset(elfFile, ph); 177 *p_memsz = elf_getProgramHeaderMemorySize(elfFile, ph); 178} 179 180uint64_t 181elf_getEntryPoint(void *elfFile) 182{ 183 return ISELF32 (elfFile) 184 ? elf32_getEntryPoint (elfFile) 185 : elf64_getEntryPoint (elfFile); 186} 187 188int 189elf_getMemoryBounds(void *elfFile, int phys, uint64_t *min, uint64_t *max) 190{ 191 uint64_t mem_min = UINT64_MAX; 192 uint64_t mem_max = 0; 193 int i; 194 195 if (elf_checkFile(elfFile) != 0) { 196 return 0; 197 } 198 199 for (i = 0; i < elf_getNumProgramHeaders(elfFile); i++) { 200 uint64_t sect_min, sect_max; 201 202 if (elf_getProgramHeaderMemorySize(elfFile, i) == 0) { 203 continue; 204 } 205 206 if (phys) { 207 sect_min = elf_getProgramHeaderPaddr(elfFile, i); 208 } else { 209 sect_min = elf_getProgramHeaderVaddr(elfFile, i); 210 } 211 212 sect_max = sect_min + elf_getProgramHeaderMemorySize(elfFile, i); 213 214 if (sect_max > mem_max) { 215 mem_max = sect_max; 216 } 217 if (sect_min < mem_min) { 218 mem_min = sect_min; 219 } 220 } 221 *min = mem_min; 222 *max = mem_max; 223 224 return 1; 225} 226 227int 228elf_vaddrInProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr) 229{ 230 uint64_t min = elf_getProgramHeaderVaddr(elfFile, ph); 231 uint64_t max = min + elf_getProgramHeaderMemorySize(elfFile, ph); 232 if (vaddr >= min && vaddr < max) { 233 return 1; 234 } else { 235 return 0; 236 } 237} 238 239uint64_t 240elf_vtopProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr) 241{ 242 uint64_t ph_phys = elf_getProgramHeaderPaddr(elfFile, ph); 243 uint64_t ph_virt = elf_getProgramHeaderVaddr(elfFile, ph); 244 uint64_t paddr; 245 246 paddr = vaddr - ph_virt + ph_phys; 247 248 return paddr; 249} 250 251int 252elf_loadFile(void *elfFile, int phys) 253{ 254 int i; 255 256 if (elf_checkFile(elfFile) != 0) { 257 return 0; 258 } 259 260 for (i = 0; i < elf_getNumProgramHeaders(elfFile); i++) { 261 /* Load that section */ 262 uint64_t dest, src; 263 size_t len; 264 if (phys) { 265 dest = elf_getProgramHeaderPaddr(elfFile, i); 266 } else { 267 dest = elf_getProgramHeaderVaddr(elfFile, i); 268 } 269 len = elf_getProgramHeaderFileSize(elfFile, i); 270 src = (uint64_t) (uintptr_t) elfFile + elf_getProgramHeaderOffset(elfFile, i); 271 memcpy((void*) (uintptr_t) dest, (void*) (uintptr_t) src, len); 272 dest += len; 273 memset((void*) (uintptr_t) dest, 0, elf_getProgramHeaderMemorySize(elfFile, i) - len); 274 } 275 276 return 1; 277} 278