aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-10-13 00:32:19 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-10-13 00:32:19 -0400
commit5a3abba77dc0eb0b00332c21899123cdfa3b19e5 (patch)
treecb0b52bcb90f5c680faba380a0832203bdad2fed
parentac4fac8cb24ab209ae373a3e3e9995dff7d0c394 (diff)
sh: Tidy up the dwarf module helpers.
This enables us to build the dwarf unwinder both with modules enabled and disabled in addition to reducing code size in the latter case. The helpers are also consolidated, and modified to resemble the BUG module helpers. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-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}