Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 137147
b: refs/heads/master
c: 2e1926e
h: refs/heads/master
i:
  137145: 23cee4e
  137143: 337279d
v: v3
  • Loading branch information
Catalin Marinas authored and Russell King committed Feb 19, 2009
1 parent 6308384 commit 0be9d8d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bff595c15c92b9c5c8f3d32edefcef6c3cbdd59f
refs/heads/master: 2e1926e7b5d39eb31880152d636e8d8d011888cb
1 change: 1 addition & 0 deletions trunk/arch/arm/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ typedef struct user_fp elf_fpregset_t;
#define R_ARM_ABS32 2
#define R_ARM_CALL 28
#define R_ARM_JUMP24 29
#define R_ARM_PREL31 42

/*
* These are used to set parameters in the core dumps.
Expand Down
22 changes: 17 additions & 5 deletions trunk/arch/arm/include/asm/module.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
#ifndef _ASM_ARM_MODULE_H
#define _ASM_ARM_MODULE_H

struct mod_arch_specific
{
int foo;
};

#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr

struct unwind_table;

struct mod_arch_specific
{
#ifdef CONFIG_ARM_UNWIND
Elf_Shdr *unw_sec_init;
Elf_Shdr *unw_sec_devinit;
Elf_Shdr *unw_sec_core;
Elf_Shdr *sec_init_text;
Elf_Shdr *sec_devinit_text;
Elf_Shdr *sec_core_text;
struct unwind_table *unwind_init;
struct unwind_table *unwind_devinit;
struct unwind_table *unwind_core;
#endif
};

/*
* Include the ARM architecture version.
*/
Expand Down
64 changes: 64 additions & 0 deletions trunk/arch/arm/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <asm/pgtable.h>
#include <asm/sections.h>
#include <asm/unwind.h>

#ifdef CONFIG_XIP_KERNEL
/*
Expand Down Expand Up @@ -66,6 +67,24 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
char *secstrings,
struct module *mod)
{
#ifdef CONFIG_ARM_UNWIND
Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;

for (s = sechdrs; s < sechdrs_end; s++) {
if (strcmp(".ARM.exidx.init.text", secstrings + s->sh_name) == 0)
mod->arch.unw_sec_init = s;
else if (strcmp(".ARM.exidx.devinit.text", secstrings + s->sh_name) == 0)
mod->arch.unw_sec_devinit = s;
else if (strcmp(".ARM.exidx", secstrings + s->sh_name) == 0)
mod->arch.unw_sec_core = s;
else if (strcmp(".init.text", secstrings + s->sh_name) == 0)
mod->arch.sec_init_text = s;
else if (strcmp(".devinit.text", secstrings + s->sh_name) == 0)
mod->arch.sec_devinit_text = s;
else if (strcmp(".text", secstrings + s->sh_name) == 0)
mod->arch.sec_core_text = s;
}
#endif
return 0;
}

Expand Down Expand Up @@ -104,6 +123,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
loc = dstsec->sh_addr + rel->r_offset;

switch (ELF32_R_TYPE(rel->r_info)) {
case R_ARM_NONE:
/* ignore */
break;

case R_ARM_ABS32:
*(u32 *)loc += sym->st_value;
break;
Expand Down Expand Up @@ -132,6 +155,11 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
*(u32 *)loc |= offset & 0x00ffffff;
break;

case R_ARM_PREL31:
offset = *(u32 *)loc + sym->st_value - loc;
*(u32 *)loc = offset & 0x7fffffff;
break;

default:
printk(KERN_ERR "%s: unknown relocation: %u\n",
module->name, ELF32_R_TYPE(rel->r_info));
Expand All @@ -150,14 +178,50 @@ apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
return -ENOEXEC;
}

#ifdef CONFIG_ARM_UNWIND
static void register_unwind_tables(struct module *mod)
{
if (mod->arch.unw_sec_init && mod->arch.sec_init_text)
mod->arch.unwind_init =
unwind_table_add(mod->arch.unw_sec_init->sh_addr,
mod->arch.unw_sec_init->sh_size,
mod->arch.sec_init_text->sh_addr,
mod->arch.sec_init_text->sh_size);
if (mod->arch.unw_sec_devinit && mod->arch.sec_devinit_text)
mod->arch.unwind_devinit =
unwind_table_add(mod->arch.unw_sec_devinit->sh_addr,
mod->arch.unw_sec_devinit->sh_size,
mod->arch.sec_devinit_text->sh_addr,
mod->arch.sec_devinit_text->sh_size);
if (mod->arch.unw_sec_core && mod->arch.sec_core_text)
mod->arch.unwind_core =
unwind_table_add(mod->arch.unw_sec_core->sh_addr,
mod->arch.unw_sec_core->sh_size,
mod->arch.sec_core_text->sh_addr,
mod->arch.sec_core_text->sh_size);
}

static void unregister_unwind_tables(struct module *mod)
{
unwind_table_del(mod->arch.unwind_init);
unwind_table_del(mod->arch.unwind_devinit);
unwind_table_del(mod->arch.unwind_core);
}
#else
static inline void register_unwind_tables(struct module *mod) { }
static inline void unregister_unwind_tables(struct module *mod) { }
#endif

int
module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
struct module *module)
{
register_unwind_tables(module);
return 0;
}

void
module_arch_cleanup(struct module *mod)
{
unregister_unwind_tables(mod);
}

0 comments on commit 0be9d8d

Please sign in to comment.