浏览代码

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>
Paul Mundt 15 年之前
父节点
当前提交
5a3abba77d
共有 3 个文件被更改,包括 53 次插入36 次删除
  1. 9 2
      arch/sh/include/asm/dwarf.h
  2. 39 4
      arch/sh/kernel/dwarf.c
  3. 5 30
      arch/sh/kernel/module.c

+ 9 - 2
arch/sh/include/asm/dwarf.h

@@ -198,6 +198,7 @@
 #include <linux/compiler.h>
 #include <linux/compiler.h>
 #include <linux/bug.h>
 #include <linux/bug.h>
 #include <linux/list.h>
 #include <linux/list.h>
+#include <linux/module.h>
 
 
 /*
 /*
  * Read either the frame pointer (r14) or the stack pointer (r15).
  * 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)
 extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
 extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
 					      struct dwarf_frame *);
 					      struct dwarf_frame *);
 extern void dwarf_free_frame(struct dwarf_frame *);
 extern void dwarf_free_frame(struct dwarf_frame *);
-extern int dwarf_parse_section(char *, char *, struct module *);
-extern void dwarf_module_unload(struct module *);
+
+extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *,
+				 struct module *);
+extern void module_dwarf_cleanup(struct module *);
 
 
 #endif /* !__ASSEMBLY__ */
 #endif /* !__ASSEMBLY__ */
 
 
@@ -412,6 +415,10 @@ extern void dwarf_module_unload(struct module *);
 static inline void dwarf_unwinder_init(void)
 static inline void dwarf_unwinder_init(void)
 {
 {
 }
 }
+
+#define module_dwarf_finalize(hdr, sechdrs, me)	(0)
+#define module_dwarf_cleanup(mod)		do { } while (0)
+
 #endif
 #endif
 
 
 #endif /* CONFIG_DWARF_UNWINDER */
 #endif /* CONFIG_DWARF_UNWINDER */

+ 39 - 4
arch/sh/kernel/dwarf.c

@@ -20,6 +20,7 @@
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/mempool.h>
 #include <linux/mempool.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
+#include <linux/elf.h>
 #include <asm/dwarf.h>
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
 #include <asm/unwinder.h>
 #include <asm/sections.h>
 #include <asm/sections.h>
@@ -895,8 +896,8 @@ static void dwarf_unwinder_cleanup(void)
  *
  *
  *	Parse the information in a .eh_frame section.
  *	Parse the information in a .eh_frame section.
  */
  */
-int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
-			struct module *mod)
+static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
+			       struct module *mod)
 {
 {
 	u32 entry_type;
 	u32 entry_type;
 	void *p, *entry;
 	void *p, *entry;
@@ -959,14 +960,47 @@ out:
 	return err;
 	return err;
 }
 }
 
 
+#ifdef CONFIG_MODULES
+int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+			  struct module *me)
+{
+	unsigned int i, err;
+	unsigned long start, end;
+	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+	start = end = 0;
+
+	for (i = 1; i < hdr->e_shnum; i++) {
+		/* Alloc bit cleared means "ignore it." */
+		if ((sechdrs[i].sh_flags & SHF_ALLOC)
+		    && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
+			start = sechdrs[i].sh_addr;
+			end = start + sechdrs[i].sh_size;
+			break;
+		}
+	}
+
+	/* Did we find the .eh_frame section? */
+	if (i != hdr->e_shnum) {
+		err = dwarf_parse_section((char *)start, (char *)end, me);
+		if (err) {
+			printk(KERN_WARNING "%s: failed to parse DWARF info\n",
+			       me->name);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
 /**
 /**
- *	dwarf_module_unload - remove FDE/CIEs associated with @mod
+ *	module_dwarf_cleanup - remove FDE/CIEs associated with @mod
  *	@mod: the module that is being unloaded
  *	@mod: the module that is being unloaded
  *
  *
  *	Remove any FDEs and CIEs from the global lists that came from
  *	Remove any FDEs and CIEs from the global lists that came from
  *	@mod's .eh_frame section because @mod is being unloaded.
  *	@mod's .eh_frame section because @mod is being unloaded.
  */
  */
-void dwarf_module_unload(struct module *mod)
+void module_dwarf_cleanup(struct module *mod)
 {
 {
 	struct dwarf_fde *fde;
 	struct dwarf_fde *fde;
 	struct dwarf_cie *cie;
 	struct dwarf_cie *cie;
@@ -1004,6 +1038,7 @@ again_fde:
 
 
 	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
 	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
 }
 }
+#endif /* CONFIG_MODULES */
 
 
 /**
 /**
  *	dwarf_unwinder_init - initialise the dwarf unwinder
  *	dwarf_unwinder_init - initialise the dwarf unwinder

+ 5 - 30
arch/sh/kernel/module.c

@@ -146,41 +146,16 @@ int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
 		    struct module *me)
 {
 {
-#ifdef CONFIG_DWARF_UNWINDER
-	unsigned int i, err;
-	unsigned long start, end;
-	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-
-	start = end = 0;
-
-	for (i = 1; i < hdr->e_shnum; i++) {
-		/* Alloc bit cleared means "ignore it." */
-		if ((sechdrs[i].sh_flags & SHF_ALLOC)
-		    && !strcmp(secstrings+sechdrs[i].sh_name, ".eh_frame")) {
-			start = sechdrs[i].sh_addr;
-			end = start + sechdrs[i].sh_size;
-			break;
-		}
-	}
+	int ret = 0;
 
 
-	/* Did we find the .eh_frame section? */
-	if (i != hdr->e_shnum) {
-		err = dwarf_parse_section((char *)start, (char *)end, me);
-		if (err)
-			printk(KERN_WARNING "%s: failed to parse DWARF info\n",
-			       me->name);
-	}
-
-#endif /* CONFIG_DWARF_UNWINDER */
+	ret |= module_dwarf_finalize(hdr, sechdrs, me);
+	ret |= module_bug_finalize(hdr, sechdrs, me);
 
 
-	return module_bug_finalize(hdr, sechdrs, me);
+	return ret;
 }
 }
 
 
 void module_arch_cleanup(struct module *mod)
 void module_arch_cleanup(struct module *mod)
 {
 {
 	module_bug_cleanup(mod);
 	module_bug_cleanup(mod);
-
-#ifdef CONFIG_DWARF_UNWINDER
-	dwarf_module_unload(mod);
-#endif /* CONFIG_DWARF_UNWINDER */
+	module_dwarf_cleanup(mod);
 }
 }