aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
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}