diff options
Diffstat (limited to 'arch/sh/kernel/dwarf.c')
-rw-r--r-- | arch/sh/kernel/dwarf.c | 43 |
1 files changed, 39 insertions, 4 deletions
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 |