Subversion Repositories HelenOS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2726 vana 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
}