18ee963f9SAlexander von Gluck IV /* reloc_arm.c - position independent x86 ELF shared object relocator
28ee963f9SAlexander von Gluck IV Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
38ee963f9SAlexander von Gluck IV Copyright (C) 1999 Hewlett-Packard Co.
48ee963f9SAlexander von Gluck IV Contributed by David Mosberger <davidm@hpl.hp.com>.
58ee963f9SAlexander von Gluck IV
68ee963f9SAlexander von Gluck IV All rights reserved.
78ee963f9SAlexander von Gluck IV
88ee963f9SAlexander von Gluck IV Redistribution and use in source and binary forms, with or without
98ee963f9SAlexander von Gluck IV modification, are permitted provided that the following conditions
108ee963f9SAlexander von Gluck IV are met:
118ee963f9SAlexander von Gluck IV
128ee963f9SAlexander von Gluck IV * Redistributions of source code must retain the above copyright
138ee963f9SAlexander von Gluck IV notice, this list of conditions and the following disclaimer.
148ee963f9SAlexander von Gluck IV * Redistributions in binary form must reproduce the above
158ee963f9SAlexander von Gluck IV copyright notice, this list of conditions and the following
168ee963f9SAlexander von Gluck IV disclaimer in the documentation and/or other materials
178ee963f9SAlexander von Gluck IV provided with the distribution.
188ee963f9SAlexander von Gluck IV * Neither the name of Hewlett-Packard Co. nor the names of its
198ee963f9SAlexander von Gluck IV contributors may be used to endorse or promote products derived
208ee963f9SAlexander von Gluck IV from this software without specific prior written permission.
218ee963f9SAlexander von Gluck IV
228ee963f9SAlexander von Gluck IV THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
238ee963f9SAlexander von Gluck IV CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
248ee963f9SAlexander von Gluck IV INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
258ee963f9SAlexander von Gluck IV MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
268ee963f9SAlexander von Gluck IV DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
278ee963f9SAlexander von Gluck IV BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
288ee963f9SAlexander von Gluck IV OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
298ee963f9SAlexander von Gluck IV PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
308ee963f9SAlexander von Gluck IV PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
318ee963f9SAlexander von Gluck IV THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
328ee963f9SAlexander von Gluck IV TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
338ee963f9SAlexander von Gluck IV THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
348ee963f9SAlexander von Gluck IV SUCH DAMAGE.
358ee963f9SAlexander von Gluck IV */
368ee963f9SAlexander von Gluck IV
37485b5cf8SAlexander von Gluck IV #include <efi/types.h>
3858bf3f36SAlexander von Gluck IV #include <efi/system-table.h>
398ee963f9SAlexander von Gluck IV
408ee963f9SAlexander von Gluck IV #include <elf.h>
418ee963f9SAlexander von Gluck IV
_relocate(long ldbase,Elf32_Dyn * dyn,efi_handle image,efi_system_table * systab)42*9b91a310SAlexander von Gluck IV extern "C" efi_status _relocate(long ldbase, Elf32_Dyn *dyn,
4358bf3f36SAlexander von Gluck IV efi_handle image __attribute__((__unused__)),
4458bf3f36SAlexander von Gluck IV efi_system_table *systab __attribute__((__unused__)))
458ee963f9SAlexander von Gluck IV {
468ee963f9SAlexander von Gluck IV long relsz = 0, relent = 0;
478ee963f9SAlexander von Gluck IV Elf32_Rel *rel = 0;
488ee963f9SAlexander von Gluck IV unsigned long *addr;
498ee963f9SAlexander von Gluck IV int i;
508ee963f9SAlexander von Gluck IV
518ee963f9SAlexander von Gluck IV for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
528ee963f9SAlexander von Gluck IV switch (dyn[i].d_tag) {
538ee963f9SAlexander von Gluck IV case DT_REL:
548ee963f9SAlexander von Gluck IV rel = (Elf32_Rel*)
558ee963f9SAlexander von Gluck IV ((unsigned long)dyn[i].d_un.d_ptr
568ee963f9SAlexander von Gluck IV + ldbase);
578ee963f9SAlexander von Gluck IV break;
588ee963f9SAlexander von Gluck IV
598ee963f9SAlexander von Gluck IV case DT_RELSZ:
608ee963f9SAlexander von Gluck IV relsz = dyn[i].d_un.d_val;
618ee963f9SAlexander von Gluck IV break;
628ee963f9SAlexander von Gluck IV
638ee963f9SAlexander von Gluck IV case DT_RELENT:
648ee963f9SAlexander von Gluck IV relent = dyn[i].d_un.d_val;
658ee963f9SAlexander von Gluck IV break;
668ee963f9SAlexander von Gluck IV
678ee963f9SAlexander von Gluck IV default:
688ee963f9SAlexander von Gluck IV break;
698ee963f9SAlexander von Gluck IV }
708ee963f9SAlexander von Gluck IV }
718ee963f9SAlexander von Gluck IV
728ee963f9SAlexander von Gluck IV if (!rel && relent == 0)
738ee963f9SAlexander von Gluck IV return EFI_SUCCESS;
748ee963f9SAlexander von Gluck IV
758ee963f9SAlexander von Gluck IV if (!rel || relent == 0)
768ee963f9SAlexander von Gluck IV return EFI_LOAD_ERROR;
778ee963f9SAlexander von Gluck IV
788ee963f9SAlexander von Gluck IV while (relsz > 0) {
798ee963f9SAlexander von Gluck IV /* apply the relocs */
808ee963f9SAlexander von Gluck IV switch (ELF32_R_TYPE (rel->r_info)) {
818ee963f9SAlexander von Gluck IV case R_ARM_NONE:
828ee963f9SAlexander von Gluck IV break;
838ee963f9SAlexander von Gluck IV
848ee963f9SAlexander von Gluck IV case R_ARM_RELATIVE:
858ee963f9SAlexander von Gluck IV addr = (unsigned long *)
868ee963f9SAlexander von Gluck IV (ldbase + rel->r_offset);
878ee963f9SAlexander von Gluck IV *addr += ldbase;
888ee963f9SAlexander von Gluck IV break;
898ee963f9SAlexander von Gluck IV
908ee963f9SAlexander von Gluck IV default:
918ee963f9SAlexander von Gluck IV break;
928ee963f9SAlexander von Gluck IV }
938ee963f9SAlexander von Gluck IV rel = (Elf32_Rel*) ((char *) rel + relent);
948ee963f9SAlexander von Gluck IV relsz -= relent;
958ee963f9SAlexander von Gluck IV }
968ee963f9SAlexander von Gluck IV return EFI_SUCCESS;
978ee963f9SAlexander von Gluck IV }
98