summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/sh/include/asm/dwarf.h11
-rw-r--r--arch/sh/kernel/dwarf.c43
-rw-r--r--arch/sh/kernel/module.c35
3 files changed, 53 insertions, 36 deletions
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h
index d985148af19..bdccbbfdc0b 100644
--- a/arch/sh/include/asm/dwarf.h
+++ b/arch/sh/include/asm/dwarf.h
@@ -198,6 +198,7 @@
#include <linux/compiler.h>
#include <linux/bug.h>
#include <linux/list.h>
+#include <linux/module.h>
/*
* Read either the frame pointer (r14) or the stack pointer (r15).
@@ -382,8 +383,10 @@ static inline unsigned int DW_CFA_operand(unsigned long insn)
extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
struct dwarf_frame *);
extern void dwarf_free_frame(struct dwarf_frame *);
-extern int dwarf_parse_section(char *, char *, struct module *);
-extern void dwarf_module_unload(struct module *);
+
+extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *,
+ struct module *);
+extern void module_dwarf_cleanup(struct module *);
#endif /* !__ASSEMBLY__ */
@@ -412,6 +415,10 @@ extern void dwarf_module_unload(struct module *);
static inline void dwarf_unwinder_init(void)
{
}
+
+#define module_dwarf_finalize(hdr, sechdrs, me) (0)
+#define module_dwarf_cleanup(mod) do { } while (0)
+
#endif
#endif /* CONFIG_DWARF_UNWINDER */
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index c274039e9c8..718286be664 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/mempool.h>
#include <linux/mm.h>
+#include <linux/elf.h>
#include <asm/dwarf.h>
#include <asm/unwinder.h>
#include <asm/sections.h>
@@ -895,8 +896,8 @@ static void dwarf_unwinder_cleanup(void)
*
* Parse the information in a .eh_frame section.
*/
-int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
- struct module *mod)
+static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
+ struct module *mod)
{
u32 entry_type;
void *p, *entry;
@@ -959,14 +960,47 @@ out:
return err;
}
+#ifdef CONFIG_MODULES
+int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+ struct module *me)
+{
+ unsigned int i, err;
+ unsigned long start, end;
+ char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+ start = end = 0;
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+ /* Alloc bit cleared means "ignore it." */
+ if ((sechdrs[i].sh_flags & SHF_ALLOC)
+ && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
+ start = sechdrs[i].sh_addr;
+ end = start + sechdrs[i].sh_size;
+ break;
+ }
+ }
+
+ /* Did we find the .eh_frame section? */
+ if (i != hdr->e_shnum) {
+ err = dwarf_parse_section((char *)start, (char *)end, me);
+ if (err) {
+ printk(KERN_WARNING "%s: failed to parse DWARF info\n",
+ me->name);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
/**
- * dwarf_module_unload - remove FDE/CIEs associated with @mod
+ * module_dwarf_cleanup - remove FDE/CIEs associated with @mod
* @mod: the module that is being unloaded
*
* Remove any FDEs and CIEs from the global lists that came from
* @mod's .eh_frame section because @mod is being unloaded.
*/
-void dwarf_module_unload(struct module *mod)
+void module_dwarf_cleanup(struct module *mod)
{
struct dwarf_fde *fde;
struct dwarf_cie *cie;
@@ -1004,6 +1038,7 @@ again_fde:
spin_unlock_irqrestore(&dwarf_fde_lock, flags);
}
+#endif /* CONFIG_MODULES */
/**
* dwarf_unwinder_init - initialise the dwarf unwinder
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index d297a148d16..43adddfe4c0 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -146,41 +146,16 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
-#ifdef CONFIG_DWARF_UNWINDER
- unsigned int i, err;
- unsigned long start, end;
- char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-
- start = end = 0;
-
- for (i = 1; i < hdr->e_shnum; i++) {
- /* Alloc bit cleared means "ignore it." */
- if ((sechdrs[i].sh_flags & SHF_ALLOC)
- && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
- start = sechdrs[i].sh_addr;
- end = start + sechdrs[i].sh_size;
- break;
- }
- }
+ int ret = 0;
- /* Did we find the .eh_frame section? */
- if (i != hdr->e_shnum) {
- err = dwarf_parse_section((char *)start, (char *)end, me);
- if (err)
- printk(KERN_WARNING "%s: failed to parse DWARF info\n",
- me->name);
- }
-
-#endif /* CONFIG_DWARF_UNWINDER */
+ ret |= module_dwarf_finalize(hdr, sechdrs, me);
+ ret |= module_bug_finalize(hdr, sechdrs, me);
- return module_bug_finalize(hdr, sechdrs, me);
+ return ret;
}
void module_arch_cleanup(struct module *mod)
{
module_bug_cleanup(mod);
-
-#ifdef CONFIG_DWARF_UNWINDER
- dwarf_module_unload(mod);
-#endif /* CONFIG_DWARF_UNWINDER */
+ module_dwarf_cleanup(mod);
}