Subversion Repositories HelenOS

Rev

Rev 2726 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /* reloc_ia32.c - position independent x86 ELF shared object relocator
  2.    Copyright (C) 1999 Hewlett-Packard Co.
  3.     Contributed by David Mosberger <davidm@hpl.hp.com>.
  4.  
  5.    This file is part of GNU-EFI, the GNU EFI development environment.
  6.  
  7.    GNU EFI is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2, or (at your option)
  10.    any later version.
  11.  
  12.    GNU EFI is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with GNU EFI; see the file COPYING.  If not, write to the Free
  19.    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  20.    02111-1307, USA. */
  21.  
  22. #include <elf.h>
  23. #include <link.h>   /* get _DYNAMIC decl and ElfW and ELFW macros */
  24.  
  25. #undef NULL
  26. #define uint64_t    efi_uint64_t
  27. #define int64_t     efi_int64_t
  28. #define uint32_t    efi_uint32_t
  29. #define int32_t     efi_int32_t
  30. #define uint16_t    efi_uint16_t
  31. #define int16_t     efi_int16_t
  32. #define uint8_t     efi_uint8_t
  33. #define int8_t      efi_int8_t
  34.  
  35. #undef NULL
  36. #define uint64_t    efi_uint64_t
  37. #define int64_t     efi_int64_t
  38. #define uint32_t    efi_uint32_t
  39. #define int32_t     efi_int32_t
  40. #define uint16_t    efi_uint16_t
  41. #define int16_t     efi_int16_t
  42. #define uint8_t     efi_uint8_t
  43. #define int8_t      efi_int8_t
  44.  
  45. #include <efi.h>
  46. #include <efilib.h>
  47.  
  48. int
  49. _relocate (long ldbase, ElfW(Dyn) *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
  50. {
  51.     extern EFI_STATUS efi_main (EFI_HANDLE, EFI_SYSTEM_TABLE *);
  52.     long relsz = 0, relent = 0;
  53.     ElfW(Rel) *rel = 0;
  54.     int i;
  55.  
  56.     for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
  57.         switch (dyn[i].d_tag) {
  58.               case DT_REL:
  59.             rel = (ElfW(Rel)*) ((long) dyn[i].d_un.d_ptr + ldbase);
  60.             break;
  61.  
  62.               case DT_RELSZ:
  63.             relsz = dyn[i].d_un.d_val;
  64.             break;
  65.  
  66.               case DT_RELENT:
  67.             relent = dyn[i].d_un.d_val;
  68.             break;
  69.  
  70.               case DT_RELA:
  71.             break;
  72.  
  73.               default:
  74.             break;
  75.         }
  76.     }
  77.  
  78.     while (relsz > 0) {
  79.         if (!rel || relent == 0)
  80.             return EFI_LOAD_ERROR;
  81.  
  82.         /* apply the relocs */
  83.         switch (ELF32_R_TYPE (rel->r_info)) {
  84.               case R_386_NONE:
  85.             break;
  86.  
  87.               case R_386_RELATIVE:
  88.               {
  89.                   long *addr;
  90.  
  91.                   addr = (long *) (ldbase + rel->r_offset);
  92.                   *addr += ldbase;
  93.                   break;
  94.               }
  95.  
  96.               default:
  97.             return EFI_LOAD_ERROR;
  98.         }
  99.         rel = (ElfW(Rel)*) ((char *) rel + relent);
  100.         relsz -= relent;
  101.     }
  102.     return EFI_SUCCESS;
  103. }
  104.