OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [sparc/] [kernel/] [module.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/* Kernel module help for sparc32.
2
 *
3
 * Copyright (C) 2001 Rusty Russell.
4
 * Copyright (C) 2002 David S. Miller.
5
 */
6
 
7
#include <linux/moduleloader.h>
8
#include <linux/kernel.h>
9
#include <linux/elf.h>
10
#include <linux/vmalloc.h>
11
#include <linux/fs.h>
12
#include <linux/string.h>
13
#include <linux/ctype.h>
14
 
15
void *module_alloc(unsigned long size)
16
{
17
        void *ret;
18
 
19
        /* We handle the zero case fine, unlike vmalloc */
20
        if (size == 0)
21
                return NULL;
22
 
23
        ret = vmalloc(size);
24
        if (!ret)
25
                ret = ERR_PTR(-ENOMEM);
26
        else
27
                memset(ret, 0, size);
28
 
29
        return ret;
30
}
31
 
32
/* Free memory returned from module_core_alloc/module_init_alloc */
33
void module_free(struct module *mod, void *module_region)
34
{
35
        vfree(module_region);
36
        /* FIXME: If module_region == mod->init_region, trim exception
37
           table entries. */
38
}
39
 
40
/* Make generic code ignore STT_REGISTER dummy undefined symbols,
41
 * and replace references to .func with _Func
42
 */
43
int module_frob_arch_sections(Elf_Ehdr *hdr,
44
                              Elf_Shdr *sechdrs,
45
                              char *secstrings,
46
                              struct module *mod)
47
{
48
        unsigned int symidx;
49
        Elf32_Sym *sym;
50
        char *strtab;
51
        int i;
52
 
53
        for (symidx = 0; sechdrs[symidx].sh_type != SHT_SYMTAB; symidx++) {
54
                if (symidx == hdr->e_shnum-1) {
55
                        printk("%s: no symtab found.\n", mod->name);
56
                        return -ENOEXEC;
57
                }
58
        }
59
        sym = (Elf32_Sym *)sechdrs[symidx].sh_addr;
60
        strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr;
61
 
62
        for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) {
63
                if (sym[i].st_shndx == SHN_UNDEF) {
64
                        if (ELF32_ST_TYPE(sym[i].st_info) == STT_REGISTER)
65
                                sym[i].st_shndx = SHN_ABS;
66
                        else {
67
                                char *name = strtab + sym[i].st_name;
68
                                if (name[0] == '.') {
69
                                        name[0] = '_';
70
                                        name[1] = toupper(name[1]);
71
                                }
72
                        }
73
                }
74
        }
75
        return 0;
76
}
77
 
78
int apply_relocate(Elf32_Shdr *sechdrs,
79
                   const char *strtab,
80
                   unsigned int symindex,
81
                   unsigned int relsec,
82
                   struct module *me)
83
{
84
        printk(KERN_ERR "module %s: non-ADD RELOCATION unsupported\n",
85
               me->name);
86
        return -ENOEXEC;
87
}
88
 
89
int apply_relocate_add(Elf32_Shdr *sechdrs,
90
                       const char *strtab,
91
                       unsigned int symindex,
92
                       unsigned int relsec,
93
                       struct module *me)
94
{
95
        unsigned int i;
96
        Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
97
        Elf32_Sym *sym;
98
        u8 *location;
99
        u32 *loc32;
100
 
101
        for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
102
                Elf32_Addr v;
103
 
104
                /* This is where to make the change */
105
                location = (u8 *)sechdrs[sechdrs[relsec].sh_info].sh_addr
106
                        + rel[i].r_offset;
107
                loc32 = (u32 *) location;
108
                /* This is the symbol it is referring to.  Note that all
109
                   undefined symbols have been resolved.  */
110
                sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
111
                        + ELF32_R_SYM(rel[i].r_info);
112
                v = sym->st_value + rel[i].r_addend;
113
 
114
                switch (ELF32_R_TYPE(rel[i].r_info)) {
115
                case R_SPARC_32:
116
                case R_SPARC_UA32:
117
                        location[0] = v >> 24;
118
                        location[1] = v >> 16;
119
                        location[2] = v >>  8;
120
                        location[3] = v >>  0;
121
                        break;
122
 
123
                case R_SPARC_WDISP30:
124
                        v -= (Elf32_Addr) location;
125
                        *loc32 = (*loc32 & ~0x3fffffff) |
126
                                ((v >> 2) & 0x3fffffff);
127
                        break;
128
 
129
                case R_SPARC_WDISP22:
130
                        v -= (Elf32_Addr) location;
131
                        *loc32 = (*loc32 & ~0x3fffff) |
132
                                ((v >> 2) & 0x3fffff);
133
                        break;
134
 
135
                case R_SPARC_LO10:
136
                        *loc32 = (*loc32 & ~0x3ff) | (v & 0x3ff);
137
                        break;
138
 
139
                case R_SPARC_HI22:
140
                        *loc32 = (*loc32 & ~0x3fffff) |
141
                                ((v >> 10) & 0x3fffff);
142
                        break;
143
 
144
                default:
145
                        printk(KERN_ERR "module %s: Unknown relocation: %x\n",
146
                               me->name,
147
                               (int) (ELF32_R_TYPE(rel[i].r_info) & 0xff));
148
                        return -ENOEXEC;
149
                };
150
        }
151
        return 0;
152
}
153
 
154
int module_finalize(const Elf_Ehdr *hdr,
155
                    const Elf_Shdr *sechdrs,
156
                    struct module *me)
157
{
158
        return 0;
159
}
160
 
161
void module_arch_cleanup(struct module *mod)
162
{
163
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.