lkml.org 
[lkml]   [2011]   [Jun]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 14/19] OpenRISC: Module support
    Date

    Signed-off-by: Jonas Bonn <jonas@southpole.se>
    ---
    arch/openrisc/kernel/module.c | 126 +++++++++++++++++++++++++++++++++++++++++
    1 files changed, 126 insertions(+), 0 deletions(-)
    create mode 100644 arch/openrisc/kernel/module.c

    diff --git a/arch/openrisc/kernel/module.c b/arch/openrisc/kernel/module.c
    new file mode 100644
    index 0000000..952b129
    --- /dev/null
    +++ b/arch/openrisc/kernel/module.c
    @@ -0,0 +1,126 @@
    +/*
    + * OpenRISC module.c
    + *
    + * Linux architectural port borrowing liberally from similar works of
    + * others. All original copyrights apply as per the original source
    + * declaration.
    + *
    + * Modifications for the OpenRISC architecture:
    + * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
    + *
    + * 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.
    + */
    +
    +#include <linux/moduleloader.h>
    +#include <linux/elf.h>
    +#include <linux/vmalloc.h>
    +#include <linux/fs.h>
    +#include <linux/string.h>
    +#include <linux/kernel.h>
    +
    +void *module_alloc(unsigned long size)
    +{
    + pr_debug("module_alloc size: %lu\n", size);
    +
    + if (size == 0)
    + return NULL;
    +
    + return vmalloc(size);
    +}
    +
    +
    +/* Free memory returned from module_alloc */
    +void module_free(struct module *mod, void *module_region)
    +{
    + vfree(module_region);
    + /* FIXME: If module_region == mod->init_region, trim exception
    + table entries. */
    +}
    +
    +/* We don't need anything special. */
    +int module_frob_arch_sections(Elf_Ehdr *hdr,
    + Elf_Shdr *sechdrs,
    + char *secstrings,
    + struct module *mod)
    +{
    + return 0;
    +}
    +
    +int apply_relocate_add(Elf32_Shdr *sechdrs,
    + const char *strtab,
    + unsigned int symindex,
    + unsigned int relsec,
    + struct module *me)
    +{
    + unsigned int i;
    + Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
    + Elf32_Sym *sym;
    +// Elf32_Addr relocation;
    + uint32_t *location;
    + uint32_t value;
    +
    + pr_debug("Applying relocate section %u to %u\n", relsec,
    + sechdrs[relsec].sh_info);
    + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
    + /* This is where to make the change */
    + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
    + + rel[i].r_offset;
    +
    + /* This is the symbol it is referring to. Note that all
    + undefined symbols have been resolved. */
    + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
    + + ELF32_R_SYM(rel[i].r_info);
    + value = sym->st_value + rel[i].r_addend;
    +
    + switch(ELF32_R_TYPE(rel[i].r_info)) {
    + case R_OR32_32:
    + *location = value;
    + break;
    + case R_OR32_CONST:
    + location = (uint16_t*)location + 1;
    + *((uint16_t*)location) = (uint16_t) (value);
    + break;
    + case R_OR32_CONSTH:
    + location = (uint16_t*)location + 1;
    + *((uint16_t*)location) = (uint16_t) (value >> 16);
    + break;
    + case R_OR32_JUMPTARG:
    + value -= (uint32_t)location;
    + value >>= 2;
    + value &= 0x03ffffff;
    + value |= *location & 0xfc000000;
    + *location = value;
    + break;
    + default:
    + pr_err("module %s: Unknown relocation: %u\n",
    + me->name, ELF32_R_TYPE(rel[i].r_info));
    + break;
    + }
    + }
    +
    + return 0;
    +}
    +
    +int apply_relocate(Elf32_Shdr *sechdrs,
    + const char *strtab,
    + unsigned int symindex,
    + unsigned int relsec,
    + struct module *me)
    +{
    + pr_err("module %s: REL relocation unsupported\n", me->name);
    + return -ENOEXEC;
    +}
    +
    +int module_finalize(const Elf_Ehdr *hdr,
    + const Elf_Shdr *sechdrs,
    + struct module *me)
    +{
    + return 0;
    +}
    +
    +void module_arch_cleanup(struct module *mod)
    +{
    +}
    --
    1.7.4.1


    \
     
     \ /
      Last update: 2011-06-19 13:49    [W:0.027 / U:64.436 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site