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