aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
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 /arch/sh/kernel
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>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/dwarf.c43
-rw-r--r--arch/sh/kernel/module.c35
2 files changed, 44 insertions, 34 deletions
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}