183d290c5STom Rini // SPDX-License-Identifier: BSD-3-Clause 22dcd4e9eSSimon Glass /* 32dcd4e9eSSimon Glass * reloc_x86_64.c - position independent x86_64 ELF shared object relocator 42dcd4e9eSSimon Glass * Copyright (C) 1999 Hewlett-Packard Co. 52dcd4e9eSSimon Glass * Contributed by David Mosberger <davidm@hpl.hp.com>. 62dcd4e9eSSimon Glass * Copyright (C) 2005 Intel Co. 72dcd4e9eSSimon Glass * Contributed by Fenghua Yu <fenghua.yu@intel.com>. 82dcd4e9eSSimon Glass * 92dcd4e9eSSimon Glass * All rights reserved. 102dcd4e9eSSimon Glass */ 112dcd4e9eSSimon Glass 122dcd4e9eSSimon Glass #include <common.h> 132dcd4e9eSSimon Glass #include <efi.h> 142dcd4e9eSSimon Glass #include <elf.h> 152dcd4e9eSSimon Glass _relocate(long ldbase,Elf64_Dyn * dyn)16*62500986SIvan Gorinovefi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn) 172dcd4e9eSSimon Glass { 182dcd4e9eSSimon Glass long relsz = 0, relent = 0; 192dcd4e9eSSimon Glass Elf64_Rel *rel = 0; 202dcd4e9eSSimon Glass unsigned long *addr; 212dcd4e9eSSimon Glass int i; 222dcd4e9eSSimon Glass 232dcd4e9eSSimon Glass for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { 242dcd4e9eSSimon Glass switch (dyn[i].d_tag) { 252dcd4e9eSSimon Glass case DT_RELA: 262dcd4e9eSSimon Glass rel = (Elf64_Rel *) 272dcd4e9eSSimon Glass ((unsigned long)dyn[i].d_un.d_ptr + ldbase); 282dcd4e9eSSimon Glass break; 292dcd4e9eSSimon Glass case DT_RELASZ: 302dcd4e9eSSimon Glass relsz = dyn[i].d_un.d_val; 312dcd4e9eSSimon Glass break; 322dcd4e9eSSimon Glass case DT_RELAENT: 332dcd4e9eSSimon Glass relent = dyn[i].d_un.d_val; 342dcd4e9eSSimon Glass break; 352dcd4e9eSSimon Glass default: 362dcd4e9eSSimon Glass break; 372dcd4e9eSSimon Glass } 382dcd4e9eSSimon Glass } 392dcd4e9eSSimon Glass 402dcd4e9eSSimon Glass if (!rel && relent == 0) 412dcd4e9eSSimon Glass return EFI_SUCCESS; 422dcd4e9eSSimon Glass 432dcd4e9eSSimon Glass if (!rel || relent == 0) 442dcd4e9eSSimon Glass return EFI_LOAD_ERROR; 452dcd4e9eSSimon Glass 462dcd4e9eSSimon Glass while (relsz > 0) { 472dcd4e9eSSimon Glass /* apply the relocs */ 482dcd4e9eSSimon Glass switch (ELF64_R_TYPE(rel->r_info)) { 492dcd4e9eSSimon Glass case R_X86_64_NONE: 502dcd4e9eSSimon Glass break; 512dcd4e9eSSimon Glass case R_X86_64_RELATIVE: 522dcd4e9eSSimon Glass addr = (unsigned long *)(ldbase + rel->r_offset); 532dcd4e9eSSimon Glass *addr += ldbase; 542dcd4e9eSSimon Glass break; 552dcd4e9eSSimon Glass default: 562dcd4e9eSSimon Glass break; 572dcd4e9eSSimon Glass } 582dcd4e9eSSimon Glass rel = (Elf64_Rel *)((char *)rel + relent); 592dcd4e9eSSimon Glass relsz -= relent; 602dcd4e9eSSimon Glass } 612dcd4e9eSSimon Glass 622dcd4e9eSSimon Glass return EFI_SUCCESS; 632dcd4e9eSSimon Glass } 64