Subversion Repositories HelenOS

Rev

Rev 2726 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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