2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-18 18:23:53 +08:00
linux-next/arch/cris/kernel/module.c
Rusty Russell 82fab442f5 modules: don't hand 0 to vmalloc.
In commit d0a21265df David Rientjes unified various archs'
module_alloc implementation (including x86) and removed the graduitous
shortcut for size == 0.

Then, in commit de7d2b567d, Joe Perches added a warning for
zero-length vmallocs, which can happen without kallsyms on modules
with no init sections (eg. zlib_deflate).

Fix this once and for all; the module code has to handle zero length
anyway, so get it right at the caller and remove the now-gratuitous
checks within the arch-specific module_alloc implementations.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42608
Reported-by: Conrad Kostecki <ConiKost@gmx.de>
Cc: David Rientjes <rientjes@google.com>
Cc: Joe Perches <joe@perches.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2012-12-14 13:06:43 +10:30

83 lines
2.4 KiB
C

/* 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_free(struct module *mod, 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;
}