10f9c15feSbmeng@tinylab.org // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2b95f138fSHeinrich Schuchardt /* reloc_riscv.c - position independent ELF shared object relocator
3b95f138fSHeinrich Schuchardt Copyright (C) 2018 Alexander Graf <agraf@suse.de>
4b95f138fSHeinrich Schuchardt Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
5b95f138fSHeinrich Schuchardt Copyright (C) 1999 Hewlett-Packard Co.
6b95f138fSHeinrich Schuchardt Contributed by David Mosberger <davidm@hpl.hp.com>.
7b95f138fSHeinrich Schuchardt
8b95f138fSHeinrich Schuchardt All rights reserved.
9b95f138fSHeinrich Schuchardt
10b95f138fSHeinrich Schuchardt Redistribution and use in source and binary forms, with or without
11b95f138fSHeinrich Schuchardt modification, are permitted provided that the following conditions
12b95f138fSHeinrich Schuchardt are met:
13b95f138fSHeinrich Schuchardt
14b95f138fSHeinrich Schuchardt * Redistributions of source code must retain the above copyright
15b95f138fSHeinrich Schuchardt notice, this list of conditions and the following disclaimer.
16b95f138fSHeinrich Schuchardt * Redistributions in binary form must reproduce the above
17b95f138fSHeinrich Schuchardt copyright notice, this list of conditions and the following
18b95f138fSHeinrich Schuchardt disclaimer in the documentation and/or other materials
19b95f138fSHeinrich Schuchardt provided with the distribution.
20b95f138fSHeinrich Schuchardt * Neither the name of Hewlett-Packard Co. nor the names of its
21b95f138fSHeinrich Schuchardt contributors may be used to endorse or promote products derived
22b95f138fSHeinrich Schuchardt from this software without specific prior written permission.
23b95f138fSHeinrich Schuchardt
24b95f138fSHeinrich Schuchardt THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25b95f138fSHeinrich Schuchardt CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26b95f138fSHeinrich Schuchardt INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27b95f138fSHeinrich Schuchardt MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28b95f138fSHeinrich Schuchardt DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
29b95f138fSHeinrich Schuchardt BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30b95f138fSHeinrich Schuchardt OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31b95f138fSHeinrich Schuchardt PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32b95f138fSHeinrich Schuchardt PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33b95f138fSHeinrich Schuchardt THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34b95f138fSHeinrich Schuchardt TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
35b95f138fSHeinrich Schuchardt THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36b95f138fSHeinrich Schuchardt SUCH DAMAGE.
37b95f138fSHeinrich Schuchardt */
38b95f138fSHeinrich Schuchardt
39b95f138fSHeinrich Schuchardt #include <efi.h>
40b95f138fSHeinrich Schuchardt
41b95f138fSHeinrich Schuchardt #include <elf.h>
42b95f138fSHeinrich Schuchardt
43b95f138fSHeinrich Schuchardt #define Elf_Dyn Elf64_Dyn
44b95f138fSHeinrich Schuchardt #define Elf_Rela Elf64_Rela
45b95f138fSHeinrich Schuchardt #define ELF_R_TYPE ELF64_R_TYPE
46b95f138fSHeinrich Schuchardt
_relocate(long ldbase,Elf_Dyn * dyn)47b95f138fSHeinrich Schuchardt EFI_STATUS EFIAPI _relocate(long ldbase, Elf_Dyn *dyn)
48b95f138fSHeinrich Schuchardt {
49b95f138fSHeinrich Schuchardt long relsz = 0, relent = 0;
50b95f138fSHeinrich Schuchardt Elf_Rela *rel = NULL;
51b95f138fSHeinrich Schuchardt unsigned long *addr;
52b95f138fSHeinrich Schuchardt int i;
53b95f138fSHeinrich Schuchardt
54b95f138fSHeinrich Schuchardt for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
55b95f138fSHeinrich Schuchardt switch (dyn[i].d_tag) {
56b95f138fSHeinrich Schuchardt case DT_RELA:
57b95f138fSHeinrich Schuchardt rel = (Elf_Rela *)((unsigned long)dyn[i].d_un.d_ptr + ldbase);
58b95f138fSHeinrich Schuchardt break;
59b95f138fSHeinrich Schuchardt case DT_RELASZ:
60b95f138fSHeinrich Schuchardt relsz = dyn[i].d_un.d_val;
61b95f138fSHeinrich Schuchardt break;
62b95f138fSHeinrich Schuchardt case DT_RELAENT:
63b95f138fSHeinrich Schuchardt relent = dyn[i].d_un.d_val;
64b95f138fSHeinrich Schuchardt break;
65b95f138fSHeinrich Schuchardt default:
66b95f138fSHeinrich Schuchardt break;
67b95f138fSHeinrich Schuchardt }
68b95f138fSHeinrich Schuchardt }
69b95f138fSHeinrich Schuchardt
70b95f138fSHeinrich Schuchardt if (!rel && relent == 0)
71b95f138fSHeinrich Schuchardt return EFI_SUCCESS;
72b95f138fSHeinrich Schuchardt
73b95f138fSHeinrich Schuchardt if (!rel || relent == 0)
74b95f138fSHeinrich Schuchardt return EFI_LOAD_ERROR;
75b95f138fSHeinrich Schuchardt
76b95f138fSHeinrich Schuchardt while (relsz > 0) {
77b95f138fSHeinrich Schuchardt /* apply the relocs */
78b95f138fSHeinrich Schuchardt switch (ELF_R_TYPE(rel->r_info)) {
79b95f138fSHeinrich Schuchardt case R_RISCV_RELATIVE:
80b95f138fSHeinrich Schuchardt addr = (unsigned long *)(ldbase + rel->r_offset);
81b95f138fSHeinrich Schuchardt *addr = ldbase + rel->r_addend;
82b95f138fSHeinrich Schuchardt break;
83b95f138fSHeinrich Schuchardt default:
84*708f66acSCallum Farmer break;
85b95f138fSHeinrich Schuchardt }
86b95f138fSHeinrich Schuchardt rel = (Elf_Rela *)((char *)rel + relent);
87b95f138fSHeinrich Schuchardt relsz -= relent;
88b95f138fSHeinrich Schuchardt }
89b95f138fSHeinrich Schuchardt return EFI_SUCCESS;
90b95f138fSHeinrich Schuchardt }
91