diff options
Diffstat (limited to 'arch/sh/kernel/dwarf.c')
-rw-r--r-- | arch/sh/kernel/dwarf.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 5ec1d1818691..49c09c7d5b77 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c | |||
@@ -49,6 +49,8 @@ static DEFINE_SPINLOCK(dwarf_fde_lock); | |||
49 | 49 | ||
50 | static struct dwarf_cie *cached_cie; | 50 | static struct dwarf_cie *cached_cie; |
51 | 51 | ||
52 | static unsigned int dwarf_unwinder_ready; | ||
53 | |||
52 | /** | 54 | /** |
53 | * dwarf_frame_alloc_reg - allocate memory for a DWARF register | 55 | * dwarf_frame_alloc_reg - allocate memory for a DWARF register |
54 | * @frame: the DWARF frame whose list of registers we insert on | 56 | * @frame: the DWARF frame whose list of registers we insert on |
@@ -582,6 +584,13 @@ struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, | |||
582 | unsigned long addr; | 584 | unsigned long addr; |
583 | 585 | ||
584 | /* | 586 | /* |
587 | * If we've been called in to before initialization has | ||
588 | * completed, bail out immediately. | ||
589 | */ | ||
590 | if (!dwarf_unwinder_ready) | ||
591 | return NULL; | ||
592 | |||
593 | /* | ||
585 | * If we're starting at the top of the stack we need get the | 594 | * If we're starting at the top of the stack we need get the |
586 | * contents of a physical register to get the CFA in order to | 595 | * contents of a physical register to get the CFA in order to |
587 | * begin the virtual unwinding of the stack. | 596 | * begin the virtual unwinding of the stack. |
@@ -845,8 +854,10 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len, | |||
845 | rb_link_node(&cie->node, parent, rb_node); | 854 | rb_link_node(&cie->node, parent, rb_node); |
846 | rb_insert_color(&cie->node, &cie_root); | 855 | rb_insert_color(&cie->node, &cie_root); |
847 | 856 | ||
857 | #ifdef CONFIG_MODULES | ||
848 | if (mod != NULL) | 858 | if (mod != NULL) |
849 | list_add_tail(&cie->link, &mod->arch.cie_list); | 859 | list_add_tail(&cie->link, &mod->arch.cie_list); |
860 | #endif | ||
850 | 861 | ||
851 | spin_unlock_irqrestore(&dwarf_cie_lock, flags); | 862 | spin_unlock_irqrestore(&dwarf_cie_lock, flags); |
852 | 863 | ||
@@ -935,8 +946,10 @@ static int dwarf_parse_fde(void *entry, u32 entry_type, | |||
935 | rb_link_node(&fde->node, parent, rb_node); | 946 | rb_link_node(&fde->node, parent, rb_node); |
936 | rb_insert_color(&fde->node, &fde_root); | 947 | rb_insert_color(&fde->node, &fde_root); |
937 | 948 | ||
949 | #ifdef CONFIG_MODULES | ||
938 | if (mod != NULL) | 950 | if (mod != NULL) |
939 | list_add_tail(&fde->link, &mod->arch.fde_list); | 951 | list_add_tail(&fde->link, &mod->arch.fde_list); |
952 | #endif | ||
940 | 953 | ||
941 | spin_unlock_irqrestore(&dwarf_fde_lock, flags); | 954 | spin_unlock_irqrestore(&dwarf_fde_lock, flags); |
942 | 955 | ||
@@ -1163,7 +1176,7 @@ void module_dwarf_cleanup(struct module *mod) | |||
1163 | */ | 1176 | */ |
1164 | static int __init dwarf_unwinder_init(void) | 1177 | static int __init dwarf_unwinder_init(void) |
1165 | { | 1178 | { |
1166 | int err; | 1179 | int err = -ENOMEM; |
1167 | 1180 | ||
1168 | dwarf_frame_cachep = kmem_cache_create("dwarf_frames", | 1181 | dwarf_frame_cachep = kmem_cache_create("dwarf_frames", |
1169 | sizeof(struct dwarf_frame), 0, | 1182 | sizeof(struct dwarf_frame), 0, |
@@ -1177,11 +1190,15 @@ static int __init dwarf_unwinder_init(void) | |||
1177 | mempool_alloc_slab, | 1190 | mempool_alloc_slab, |
1178 | mempool_free_slab, | 1191 | mempool_free_slab, |
1179 | dwarf_frame_cachep); | 1192 | dwarf_frame_cachep); |
1193 | if (!dwarf_frame_pool) | ||
1194 | goto out; | ||
1180 | 1195 | ||
1181 | dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ, | 1196 | dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ, |
1182 | mempool_alloc_slab, | 1197 | mempool_alloc_slab, |
1183 | mempool_free_slab, | 1198 | mempool_free_slab, |
1184 | dwarf_reg_cachep); | 1199 | dwarf_reg_cachep); |
1200 | if (!dwarf_reg_pool) | ||
1201 | goto out; | ||
1185 | 1202 | ||
1186 | err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL); | 1203 | err = dwarf_parse_section(__start_eh_frame, __stop_eh_frame, NULL); |
1187 | if (err) | 1204 | if (err) |
@@ -1191,11 +1208,13 @@ static int __init dwarf_unwinder_init(void) | |||
1191 | if (err) | 1208 | if (err) |
1192 | goto out; | 1209 | goto out; |
1193 | 1210 | ||
1211 | dwarf_unwinder_ready = 1; | ||
1212 | |||
1194 | return 0; | 1213 | return 0; |
1195 | 1214 | ||
1196 | out: | 1215 | out: |
1197 | printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err); | 1216 | printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err); |
1198 | dwarf_unwinder_cleanup(); | 1217 | dwarf_unwinder_cleanup(); |
1199 | return -EINVAL; | 1218 | return err; |
1200 | } | 1219 | } |
1201 | early_initcall(dwarf_unwinder_init); | 1220 | early_initcall(dwarf_unwinder_init); |