xref: /haiku/src/system/boot/platform/efi/arch/arm/relocation_func.cpp (revision 9b91a310bf29d72c999da8865571d307d5cc44bc)
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