aboutsummaryrefslogtreecommitdiffstats
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 d985148af19f..bdccbbfdc0bd 100644
--- a/arch/sh/include/asm/dwarf.h
+++ b/arch/sh/include/asm/dwarf.h
@@ -198,6 +198,7 @@
198#include <linux/compiler.h> 198#include <linux/compiler.h>
199#include <linux/bug.h> 199#include <linux/bug.h>
200#include <linux/list.h> 200#include <linux/list.h>
201#include <linux/module.h>
201 202
202/* 203/*
203 * Read either the frame pointer (r14) or the stack pointer (r15). 204 * 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)
382extern struct dwarf_frame *dwarf_unwind_stack(unsigned long, 383extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
383 struct dwarf_frame *); 384 struct dwarf_frame *);
384extern void dwarf_free_frame(struct dwarf_frame *); 385extern void dwarf_free_frame(struct dwarf_frame *);
385extern int dwarf_parse_section(char *, char *, struct module *); 386
386extern void dwarf_module_unload(struct module *); 387extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *,
388 struct module *);
389extern void module_dwarf_cleanup(struct module *);
387 390
388#endif /* !__ASSEMBLY__ */ 391#endif /* !__ASSEMBLY__ */
389 392
@@ -412,6 +415,10 @@ extern void dwarf_module_unload(struct module *);
412static inline void dwarf_unwinder_init(void) 415static inline void dwarf_unwinder_init(void)
413{ 416{
414} 417}
418
419#define module_dwarf_finalize(hdr, sechdrs, me) (0)
420#define module_dwarf_cleanup(mod) do { } while (0)
421
415#endif 422#endif
416 423
417#endif /* CONFIG_DWARF_UNWINDER */ 424#endif /* CONFIG_DWARF_UNWINDER */
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index c274039e9c8d..718286be6648 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -20,6 +20,7 @@
20#include <linux/list.h> 20#include <linux/list.h>
21#include <linux/mempool.h> 21#include <linux/mempool.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/elf.h>
23#include <asm/dwarf.h> 24#include <asm/dwarf.h>
24#include <asm/unwinder.h> 25#include <asm/unwinder.h>
25#include <asm/sections.h> 26#include <asm/sections.h>
@@ -895,8 +896,8 @@ static void dwarf_unwinder_cleanup(void)
895 * 896 *
896 * Parse the information in a .eh_frame section. 897 * Parse the information in a .eh_frame section.
897 */ 898 */
898int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end, 899static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
899 struct module *mod) 900 struct module *mod)
900{ 901{
901 u32 entry_type; 902 u32 entry_type;
902 void *p, *entry; 903 void *p, *entry;
@@ -959,14 +960,47 @@ out:
959 return err; 960 return err;
960} 961}
961 962
963#ifdef CONFIG_MODULES
964int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
965 struct module *me)
966{
967 unsigned int i, err;
968 unsigned long start, end;
969 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
970
971 start = end = 0;
972
973 for (i = 1; i < hdr->e_shnum; i++) {
974 /* Alloc bit cleared means "ignore it." */
975 if ((sechdrs[i].sh_flags & SHF_ALLOC)
976 && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
977 start = sechdrs[i].sh_addr;
978 end = start + sechdrs[i].sh_size;
979 break;
980 }
981 }
982
983 /* Did we find the .eh_frame section? */
984 if (i != hdr->e_shnum) {
985 err = dwarf_parse_section((char *)start, (char *)end, me);
986 if (err) {
987 printk(KERN_WARNING "%s: failed to parse DWARF info\n",
988 me->name);
989 return err;
990 }
991 }
992
993 return 0;
994}
995
962/** 996/**
963 * dwarf_module_unload - remove FDE/CIEs associated with @mod 997 * module_dwarf_cleanup - remove FDE/CIEs associated with @mod
964 * @mod: the module that is being unloaded 998 * @mod: the module that is being unloaded
965 * 999 *
966 * Remove any FDEs and CIEs from the global lists that came from 1000 * Remove any FDEs and CIEs from the global lists that came from
967 * @mod's .eh_frame section because @mod is being unloaded. 1001 * @mod's .eh_frame section because @mod is being unloaded.
968 */ 1002 */
969void dwarf_module_unload(struct module *mod) 1003void module_dwarf_cleanup(struct module *mod)
970{ 1004{
971 struct dwarf_fde *fde; 1005 struct dwarf_fde *fde;
972 struct dwarf_cie *cie; 1006 struct dwarf_cie *cie;
@@ -1004,6 +1038,7 @@ again_fde:
1004 1038
1005 spin_unlock_irqrestore(&dwarf_fde_lock, flags); 1039 spin_unlock_irqrestore(&dwarf_fde_lock, flags);
1006} 1040}
1041#endif /* CONFIG_MODULES */
1007 1042
1008/** 1043/**
1009 * dwarf_unwinder_init - initialise the dwarf unwinder 1044 * dwarf_unwinder_init - initialise the dwarf unwinder
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index d297a148d16c..43adddfe4c04 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -146,41 +146,16 @@ int module_finalize(const Elf_Ehdr *hdr,
146 const Elf_Shdr *sechdrs, 146 const Elf_Shdr *sechdrs,
147 struct module *me) 147 struct module *me)
148{ 148{
149#ifdef CONFIG_DWARF_UNWINDER 149 int ret = 0;
150 unsigned int i, err;
151 unsigned long start, end;
152 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
153
154 start = end = 0;
155
156 for (i = 1; i < hdr->e_shnum; i++) {
157 /* Alloc bit cleared means "ignore it." */
158 if ((sechdrs[i].sh_flags & SHF_ALLOC)
159 && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
160 start = sechdrs[i].sh_addr;
161 end = start + sechdrs[i].sh_size;
162 break;
163 }
164 }
165 150
166 /* Did we find the .eh_frame section? */ 151 ret |= module_dwarf_finalize(hdr, sechdrs, me);
167 if (i != hdr->e_shnum) { 152 ret |= module_bug_finalize(hdr, sechdrs, me);
168 err = dwarf_parse_section((char *)start, (char *)end, me);
169 if (err)
170 printk(KERN_WARNING "%s: failed to parse DWARF info\n",
171 me->name);
172 }
173
174#endif /* CONFIG_DWARF_UNWINDER */
175 153
176 return module_bug_finalize(hdr, sechdrs, me); 154 return ret;
177} 155}
178 156
179void module_arch_cleanup(struct module *mod) 157void module_arch_cleanup(struct module *mod)
180{ 158{
181 module_bug_cleanup(mod); 159 module_bug_cleanup(mod);
182 160 module_dwarf_cleanup(mod);
183#ifdef CONFIG_DWARF_UNWINDER
184 dwarf_module_unload(mod);
185#endif /* CONFIG_DWARF_UNWINDER */
186} 161}