ronnie
2022-10-23 e3a1b9bdd0692904702c0e734ea5dfde3b0ac8fb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*  Kernel module help for i386.
    Copyright (C) 2001 Rusty Russell.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#include <linux/moduleloader.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/slab.h>
 
#if 0
#define DEBUGP printk
#else
#define DEBUGP(fmt , ...)
#endif
 
#ifdef CONFIG_ETRAX_KMALLOCED_MODULES
void *module_alloc(unsigned long size)
{
   return kmalloc(size, GFP_KERNEL);
}
 
/* Free memory returned from module_alloc */
void module_memfree(void *module_region)
{
   kfree(module_region);
}
#endif
 
int apply_relocate_add(Elf32_Shdr *sechdrs,
              const char *strtab,
              unsigned int symindex,
              unsigned int relsec,
              struct module *me)
{
      unsigned int i;
   Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
 
   DEBUGP ("Applying add relocate section %u to %u\n", relsec,
       sechdrs[relsec].sh_info);
 
   for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
       /* This is where to make the change */
       uint32_t *loc
           = ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
              + rela[i].r_offset);
       /* This is the symbol it is referring to.  Note that all
          undefined symbols have been resolved.  */
       Elf32_Sym *sym
           = ((Elf32_Sym *)sechdrs[symindex].sh_addr
              + ELF32_R_SYM (rela[i].r_info));
       switch (ELF32_R_TYPE(rela[i].r_info)) {
       case R_CRIS_32:
           *loc = sym->st_value + rela[i].r_addend;
           break;
       case R_CRIS_32_PCREL:
           *loc = sym->st_value - (unsigned)loc + rela[i].r_addend - 4;
            break;
       default:
           printk(KERN_ERR "module %s: Unknown relocation: %u\n",
                  me->name, ELF32_R_TYPE(rela[i].r_info));
           return -ENOEXEC;
       }
   }
 
   return 0;
}