aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/dwarf.c
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/dwarf.c
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/dwarf.c')
-rw-r--r--arch/sh/kernel/dwarf.c43
1 files changed, 39 insertions, 4 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