diff options
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/include/asm/dwarf.h | 11 | ||||
-rw-r--r-- | arch/sh/kernel/dwarf.c | 43 | ||||
-rw-r--r-- | arch/sh/kernel/module.c | 35 |
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); } |