Home | History | Annotate | Line # | Download | only in gnuefi
reloc_ia32.c revision 1.1.1.1.4.2
      1  1.1.1.1.4.2  rmind /*	$NetBSD: reloc_ia32.c,v 1.1.1.1.4.2 2014/05/18 17:46:02 rmind Exp $	*/
      2  1.1.1.1.4.2  rmind 
      3  1.1.1.1.4.2  rmind /* reloc_ia32.c - position independent x86 ELF shared object relocator
      4  1.1.1.1.4.2  rmind    Copyright (C) 1999 Hewlett-Packard Co.
      5  1.1.1.1.4.2  rmind 	Contributed by David Mosberger <davidm (at) hpl.hp.com>.
      6  1.1.1.1.4.2  rmind 
      7  1.1.1.1.4.2  rmind     All rights reserved.
      8  1.1.1.1.4.2  rmind 
      9  1.1.1.1.4.2  rmind     Redistribution and use in source and binary forms, with or without
     10  1.1.1.1.4.2  rmind     modification, are permitted provided that the following conditions
     11  1.1.1.1.4.2  rmind     are met:
     12  1.1.1.1.4.2  rmind 
     13  1.1.1.1.4.2  rmind     * Redistributions of source code must retain the above copyright
     14  1.1.1.1.4.2  rmind       notice, this list of conditions and the following disclaimer.
     15  1.1.1.1.4.2  rmind     * Redistributions in binary form must reproduce the above
     16  1.1.1.1.4.2  rmind       copyright notice, this list of conditions and the following
     17  1.1.1.1.4.2  rmind       disclaimer in the documentation and/or other materials
     18  1.1.1.1.4.2  rmind       provided with the distribution.
     19  1.1.1.1.4.2  rmind     * Neither the name of Hewlett-Packard Co. nor the names of its
     20  1.1.1.1.4.2  rmind       contributors may be used to endorse or promote products derived
     21  1.1.1.1.4.2  rmind       from this software without specific prior written permission.
     22  1.1.1.1.4.2  rmind 
     23  1.1.1.1.4.2  rmind     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
     24  1.1.1.1.4.2  rmind     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
     25  1.1.1.1.4.2  rmind     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     26  1.1.1.1.4.2  rmind     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     27  1.1.1.1.4.2  rmind     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     28  1.1.1.1.4.2  rmind     BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
     29  1.1.1.1.4.2  rmind     OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     30  1.1.1.1.4.2  rmind     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     31  1.1.1.1.4.2  rmind     PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     32  1.1.1.1.4.2  rmind     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     33  1.1.1.1.4.2  rmind     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
     34  1.1.1.1.4.2  rmind     THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  1.1.1.1.4.2  rmind     SUCH DAMAGE.
     36  1.1.1.1.4.2  rmind */
     37  1.1.1.1.4.2  rmind 
     38  1.1.1.1.4.2  rmind #include <efi.h>
     39  1.1.1.1.4.2  rmind #include <efilib.h>
     40  1.1.1.1.4.2  rmind 
     41  1.1.1.1.4.2  rmind #include <elf.h>
     42  1.1.1.1.4.2  rmind 
     43  1.1.1.1.4.2  rmind EFI_STATUS _relocate (long ldbase, Elf32_Dyn *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
     44  1.1.1.1.4.2  rmind {
     45  1.1.1.1.4.2  rmind 	long relsz = 0, relent = 0;
     46  1.1.1.1.4.2  rmind 	Elf32_Rel *rel = 0;
     47  1.1.1.1.4.2  rmind 	unsigned long *addr;
     48  1.1.1.1.4.2  rmind 	int i;
     49  1.1.1.1.4.2  rmind 
     50  1.1.1.1.4.2  rmind 	for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
     51  1.1.1.1.4.2  rmind 		switch (dyn[i].d_tag) {
     52  1.1.1.1.4.2  rmind 			case DT_REL:
     53  1.1.1.1.4.2  rmind 				rel = (Elf32_Rel*)
     54  1.1.1.1.4.2  rmind 					((unsigned long)dyn[i].d_un.d_ptr
     55  1.1.1.1.4.2  rmind 					 + ldbase);
     56  1.1.1.1.4.2  rmind 				break;
     57  1.1.1.1.4.2  rmind 
     58  1.1.1.1.4.2  rmind 			case DT_RELSZ:
     59  1.1.1.1.4.2  rmind 				relsz = dyn[i].d_un.d_val;
     60  1.1.1.1.4.2  rmind 				break;
     61  1.1.1.1.4.2  rmind 
     62  1.1.1.1.4.2  rmind 			case DT_RELENT:
     63  1.1.1.1.4.2  rmind 				relent = dyn[i].d_un.d_val;
     64  1.1.1.1.4.2  rmind 				break;
     65  1.1.1.1.4.2  rmind 
     66  1.1.1.1.4.2  rmind 			case DT_RELA:
     67  1.1.1.1.4.2  rmind 				break;
     68  1.1.1.1.4.2  rmind 
     69  1.1.1.1.4.2  rmind 			default:
     70  1.1.1.1.4.2  rmind 				break;
     71  1.1.1.1.4.2  rmind 		}
     72  1.1.1.1.4.2  rmind 	}
     73  1.1.1.1.4.2  rmind 
     74  1.1.1.1.4.2  rmind         if (!rel && relent == 0)
     75  1.1.1.1.4.2  rmind                 return EFI_SUCCESS;
     76  1.1.1.1.4.2  rmind 
     77  1.1.1.1.4.2  rmind 	if (!rel || relent == 0)
     78  1.1.1.1.4.2  rmind 		return EFI_LOAD_ERROR;
     79  1.1.1.1.4.2  rmind 
     80  1.1.1.1.4.2  rmind 	while (relsz > 0) {
     81  1.1.1.1.4.2  rmind 		/* apply the relocs */
     82  1.1.1.1.4.2  rmind 		switch (ELF32_R_TYPE (rel->r_info)) {
     83  1.1.1.1.4.2  rmind 			case R_386_NONE:
     84  1.1.1.1.4.2  rmind 				break;
     85  1.1.1.1.4.2  rmind 
     86  1.1.1.1.4.2  rmind 			case R_386_RELATIVE:
     87  1.1.1.1.4.2  rmind 				addr = (unsigned long *)
     88  1.1.1.1.4.2  rmind 					(ldbase + rel->r_offset);
     89  1.1.1.1.4.2  rmind 				*addr += ldbase;
     90  1.1.1.1.4.2  rmind 				break;
     91  1.1.1.1.4.2  rmind 
     92  1.1.1.1.4.2  rmind 			default:
     93  1.1.1.1.4.2  rmind 				break;
     94  1.1.1.1.4.2  rmind 		}
     95  1.1.1.1.4.2  rmind 		rel = (Elf32_Rel*) ((char *) rel + relent);
     96  1.1.1.1.4.2  rmind 		relsz -= relent;
     97  1.1.1.1.4.2  rmind 	}
     98  1.1.1.1.4.2  rmind 	return EFI_SUCCESS;
     99  1.1.1.1.4.2  rmind }
    100