Commit 5a3abba77dc0eb0b00332c21899123cdfa3b19e5

Authored by Paul Mundt
1 parent ac4fac8cb2

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>

Showing 3 changed files with 53 additions and 36 deletions Side-by-side Diff

arch/sh/include/asm/dwarf.h
... ... @@ -198,6 +198,7 @@
198 198 #include <linux/compiler.h>
199 199 #include <linux/bug.h>
200 200 #include <linux/list.h>
  201 +#include <linux/module.h>
201 202  
202 203 /*
203 204 * Read either the frame pointer (r14) or the stack pointer (r15).
204 205  
... ... @@ -382,9 +383,11 @@
382 383 extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
383 384 struct dwarf_frame *);
384 385 extern void dwarf_free_frame(struct dwarf_frame *);
385   -extern int dwarf_parse_section(char *, char *, struct module *);
386   -extern void dwarf_module_unload(struct module *);
387 386  
  387 +extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *,
  388 + struct module *);
  389 +extern void module_dwarf_cleanup(struct module *);
  390 +
388 391 #endif /* !__ASSEMBLY__ */
389 392  
390 393 #define CFI_STARTPROC .cfi_startproc
... ... @@ -412,6 +415,10 @@
412 415 static 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 422 #endif
416 423  
417 424 #endif /* CONFIG_DWARF_UNWINDER */
arch/sh/kernel/dwarf.c
... ... @@ -20,6 +20,7 @@
20 20 #include <linux/list.h>
21 21 #include <linux/mempool.h>
22 22 #include <linux/mm.h>
  23 +#include <linux/elf.h>
23 24 #include <asm/dwarf.h>
24 25 #include <asm/unwinder.h>
25 26 #include <asm/sections.h>
... ... @@ -895,8 +896,8 @@
895 896 *
896 897 * Parse the information in a .eh_frame section.
897 898 */
898   -int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
899   - struct module *mod)
  899 +static int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end,
  900 + struct module *mod)
900 901 {
901 902 u32 entry_type;
902 903 void *p, *entry;
903 904  
904 905  
... ... @@ -959,14 +960,47 @@
959 960 return err;
960 961 }
961 962  
  963 +#ifdef CONFIG_MODULES
  964 +int 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 998 * @mod: the module that is being unloaded
965 999 *
966 1000 * Remove any FDEs and CIEs from the global lists that came from
967 1001 * @mod's .eh_frame section because @mod is being unloaded.
968 1002 */
969   -void dwarf_module_unload(struct module *mod)
  1003 +void module_dwarf_cleanup(struct module *mod)
970 1004 {
971 1005 struct dwarf_fde *fde;
972 1006 struct dwarf_cie *cie;
... ... @@ -1004,6 +1038,7 @@
1004 1038  
1005 1039 spin_unlock_irqrestore(&dwarf_fde_lock, flags);
1006 1040 }
  1041 +#endif /* CONFIG_MODULES */
1007 1042  
1008 1043 /**
1009 1044 * dwarf_unwinder_init - initialise the dwarf unwinder
arch/sh/kernel/module.c
... ... @@ -146,42 +146,17 @@
146 146 const Elf_Shdr *sechdrs,
147 147 struct module *me)
148 148 {
149   -#ifdef CONFIG_DWARF_UNWINDER
150   - unsigned int i, err;
151   - unsigned long start, end;
152   - char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
  149 + int ret = 0;
153 150  
154   - start = end = 0;
  151 + ret |= module_dwarf_finalize(hdr, sechdrs, me);
  152 + ret |= module_bug_finalize(hdr, sechdrs, me);
155 153  
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   -
166   - /* Did we find the .eh_frame section? */
167   - if (i != hdr->e_shnum) {
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   -
176   - return module_bug_finalize(hdr, sechdrs, me);
  154 + return ret;
177 155 }
178 156  
179 157 void module_arch_cleanup(struct module *mod)
180 158 {
181 159 module_bug_cleanup(mod);
182   -
183   -#ifdef CONFIG_DWARF_UNWINDER
184   - dwarf_module_unload(mod);
185   -#endif /* CONFIG_DWARF_UNWINDER */
  160 + module_dwarf_cleanup(mod);
186 161 }