34
34
#define DEBUGP (fmt ...)
35
35
#endif
36
36
37
+ #if defined(CONFIG_UML ) || defined(CONFIG_X86_32 )
38
+ void * module_alloc (unsigned long size )
39
+ {
40
+ if (size == 0 )
41
+ return NULL ;
42
+ return vmalloc_exec (size );
43
+ }
44
+ #else /*X86_64*/
45
+ void * module_alloc (unsigned long size )
46
+ {
47
+ struct vm_struct * area ;
48
+
49
+ if (!size )
50
+ return NULL ;
51
+ size = PAGE_ALIGN (size );
52
+ if (size > MODULES_LEN )
53
+ return NULL ;
54
+
55
+ area = __get_vm_area (size , VM_ALLOC , MODULES_VADDR , MODULES_END );
56
+ if (!area )
57
+ return NULL ;
58
+
59
+ return __vmalloc_area (area , GFP_KERNEL , PAGE_KERNEL_EXEC );
60
+ }
61
+ #endif
62
+
37
63
/* Free memory returned from module_alloc */
38
64
void module_free (struct module * mod , void * module_region )
39
65
{
@@ -51,6 +77,140 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
51
77
return 0 ;
52
78
}
53
79
80
+ #ifdef CONFIG_X86_32
81
+ int apply_relocate (Elf32_Shdr * sechdrs ,
82
+ const char * strtab ,
83
+ unsigned int symindex ,
84
+ unsigned int relsec ,
85
+ struct module * me )
86
+ {
87
+ unsigned int i ;
88
+ Elf32_Rel * rel = (void * )sechdrs [relsec ].sh_addr ;
89
+ Elf32_Sym * sym ;
90
+ uint32_t * location ;
91
+
92
+ DEBUGP ("Applying relocate section %u to %u\n" , relsec ,
93
+ sechdrs [relsec ].sh_info );
94
+ for (i = 0 ; i < sechdrs [relsec ].sh_size / sizeof (* rel ); i ++ ) {
95
+ /* This is where to make the change */
96
+ location = (void * )sechdrs [sechdrs [relsec ].sh_info ].sh_addr
97
+ + rel [i ].r_offset ;
98
+ /* This is the symbol it is referring to. Note that all
99
+ undefined symbols have been resolved. */
100
+ sym = (Elf32_Sym * )sechdrs [symindex ].sh_addr
101
+ + ELF32_R_SYM (rel [i ].r_info );
102
+
103
+ switch (ELF32_R_TYPE (rel [i ].r_info )) {
104
+ case R_386_32 :
105
+ /* We add the value into the location given */
106
+ * location += sym -> st_value ;
107
+ break ;
108
+ case R_386_PC32 :
109
+ /* Add the value, subtract its postition */
110
+ * location += sym -> st_value - (uint32_t )location ;
111
+ break ;
112
+ default :
113
+ printk (KERN_ERR "module %s: Unknown relocation: %u\n" ,
114
+ me -> name , ELF32_R_TYPE (rel [i ].r_info ));
115
+ return - ENOEXEC ;
116
+ }
117
+ }
118
+ return 0 ;
119
+ }
120
+
121
+ int apply_relocate_add (Elf32_Shdr * sechdrs ,
122
+ const char * strtab ,
123
+ unsigned int symindex ,
124
+ unsigned int relsec ,
125
+ struct module * me )
126
+ {
127
+ printk (KERN_ERR "module %s: ADD RELOCATION unsupported\n" ,
128
+ me -> name );
129
+ return - ENOEXEC ;
130
+ }
131
+ #else /*X86_64*/
132
+ int apply_relocate_add (Elf64_Shdr * sechdrs ,
133
+ const char * strtab ,
134
+ unsigned int symindex ,
135
+ unsigned int relsec ,
136
+ struct module * me )
137
+ {
138
+ unsigned int i ;
139
+ Elf64_Rela * rel = (void * )sechdrs [relsec ].sh_addr ;
140
+ Elf64_Sym * sym ;
141
+ void * loc ;
142
+ u64 val ;
143
+
144
+ DEBUGP ("Applying relocate section %u to %u\n" , relsec ,
145
+ sechdrs [relsec ].sh_info );
146
+ for (i = 0 ; i < sechdrs [relsec ].sh_size / sizeof (* rel ); i ++ ) {
147
+ /* This is where to make the change */
148
+ loc = (void * )sechdrs [sechdrs [relsec ].sh_info ].sh_addr
149
+ + rel [i ].r_offset ;
150
+
151
+ /* This is the symbol it is referring to. Note that all
152
+ undefined symbols have been resolved. */
153
+ sym = (Elf64_Sym * )sechdrs [symindex ].sh_addr
154
+ + ELF64_R_SYM (rel [i ].r_info );
155
+
156
+ DEBUGP ("type %d st_value %Lx r_addend %Lx loc %Lx\n" ,
157
+ (int )ELF64_R_TYPE (rel [i ].r_info ),
158
+ sym -> st_value , rel [i ].r_addend , (u64 )loc );
159
+
160
+ val = sym -> st_value + rel [i ].r_addend ;
161
+
162
+ switch (ELF64_R_TYPE (rel [i ].r_info )) {
163
+ case R_X86_64_NONE :
164
+ break ;
165
+ case R_X86_64_64 :
166
+ * (u64 * )loc = val ;
167
+ break ;
168
+ case R_X86_64_32 :
169
+ * (u32 * )loc = val ;
170
+ if (val != * (u32 * )loc )
171
+ goto overflow ;
172
+ break ;
173
+ case R_X86_64_32S :
174
+ * (s32 * )loc = val ;
175
+ if ((s64 )val != * (s32 * )loc )
176
+ goto overflow ;
177
+ break ;
178
+ case R_X86_64_PC32 :
179
+ val -= (u64 )loc ;
180
+ * (u32 * )loc = val ;
181
+ #if 0
182
+ if ((s64 )val != * (s32 * )loc )
183
+ goto overflow ;
184
+ #endif
185
+ break ;
186
+ default :
187
+ printk (KERN_ERR "module %s: Unknown rela relocation: %llu\n" ,
188
+ me -> name , ELF64_R_TYPE (rel [i ].r_info ));
189
+ return - ENOEXEC ;
190
+ }
191
+ }
192
+ return 0 ;
193
+
194
+ overflow :
195
+ printk (KERN_ERR "overflow in relocation type %d val %Lx\n" ,
196
+ (int )ELF64_R_TYPE (rel [i ].r_info ), val );
197
+ printk (KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n" ,
198
+ me -> name );
199
+ return - ENOEXEC ;
200
+ }
201
+
202
+ int apply_relocate (Elf_Shdr * sechdrs ,
203
+ const char * strtab ,
204
+ unsigned int symindex ,
205
+ unsigned int relsec ,
206
+ struct module * me )
207
+ {
208
+ printk (KERN_ERR "non add relocation not supported\n" );
209
+ return - ENOSYS ;
210
+ }
211
+
212
+ #endif
213
+
54
214
int module_finalize (const Elf_Ehdr * hdr ,
55
215
const Elf_Shdr * sechdrs ,
56
216
struct module * me )
0 commit comments