diff options
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/dwarf.c | 43 | ||||
-rw-r--r-- | arch/sh/kernel/module.c | 35 |
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 | */ |
898 | int dwarf_parse_section(char *eh_frame_start, char *eh_frame_end, | 899 | static 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 | ||
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 | * @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 | */ |
969 | void dwarf_module_unload(struct module *mod) | 1003 | void 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 | ||
179 | void module_arch_cleanup(struct module *mod) | 157 | void 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 | } |