uboot/arch/x86/lib/reloc_x86_64_efi.c
<<
>>
Prefs
   1/*
   2 * reloc_x86_64.c - position independent x86_64 ELF shared object relocator
   3 * Copyright (C) 1999 Hewlett-Packard Co.
   4 * Contributed by David Mosberger <davidm@hpl.hp.com>.
   5 * Copyright (C) 2005 Intel Co.
   6 * Contributed by Fenghua Yu <fenghua.yu@intel.com>.
   7 *
   8 * All rights reserved.
   9 *
  10 * SPDX-License-Identifier:     BSD-3-Clause
  11 */
  12
  13#include <common.h>
  14#include <efi.h>
  15#include <elf.h>
  16#include <asm/elf.h>
  17
  18efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
  19                       struct efi_system_table *systab)
  20{
  21        long relsz = 0, relent = 0;
  22        Elf64_Rel *rel = 0;
  23        unsigned long *addr;
  24        int i;
  25
  26        for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
  27                switch (dyn[i].d_tag) {
  28                case DT_RELA:
  29                        rel = (Elf64_Rel *)
  30                                ((unsigned long)dyn[i].d_un.d_ptr + ldbase);
  31                        break;
  32                case DT_RELASZ:
  33                        relsz = dyn[i].d_un.d_val;
  34                        break;
  35                case DT_RELAENT:
  36                        relent = dyn[i].d_un.d_val;
  37                        break;
  38                default:
  39                        break;
  40                }
  41        }
  42
  43        if (!rel && relent == 0)
  44                return EFI_SUCCESS;
  45
  46        if (!rel || relent == 0)
  47                return EFI_LOAD_ERROR;
  48
  49        while (relsz > 0) {
  50                /* apply the relocs */
  51                switch (ELF64_R_TYPE(rel->r_info)) {
  52                case R_X86_64_NONE:
  53                        break;
  54                case R_X86_64_RELATIVE:
  55                        addr = (unsigned long *)(ldbase + rel->r_offset);
  56                        *addr += ldbase;
  57                        break;
  58                default:
  59                        break;
  60                }
  61                rel = (Elf64_Rel *)((char *)rel + relent);
  62                relsz -= relent;
  63        }
  64
  65        return EFI_SUCCESS;
  66}
  67