diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-11 14:57:14 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-02-23 12:24:14 -0500 |
commit | 68e6fad488ef21335529c65ca6c88c38be50cd3a (patch) | |
tree | a9ca2d10ee703bbc4ccff79385bd0ee95dcbc29b /arch/arm/kernel/module.c | |
parent | a65d29225ed884456f3d34dcefd3a18df24af03b (diff) |
ARM: improve module relocation fixup diagnostics
Current diagnostics are rather poor when things go wrong:
ipv6: relocation out of range, section 2 reloc 0 sym 'snmp_mib_free'
Let's include a little more information about the problem:
ipv6: section 2 reloc 0 sym 'snmp_mib_free': relocation 28 out of range (0xbf0000a4 -> 0xc11b4858)
so that we show exactly what the problem is - not only what type of
relocation but also the offending address range too.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/module.c')
-rw-r--r-- | arch/arm/kernel/module.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 2cfe8161b478..980fe20a376e 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
@@ -75,6 +75,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
75 | for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { | 75 | for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { |
76 | unsigned long loc; | 76 | unsigned long loc; |
77 | Elf32_Sym *sym; | 77 | Elf32_Sym *sym; |
78 | const char *symname; | ||
78 | s32 offset; | 79 | s32 offset; |
79 | #ifdef CONFIG_THUMB2_KERNEL | 80 | #ifdef CONFIG_THUMB2_KERNEL |
80 | u32 upper, lower, sign, j1, j2; | 81 | u32 upper, lower, sign, j1, j2; |
@@ -82,18 +83,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
82 | 83 | ||
83 | offset = ELF32_R_SYM(rel->r_info); | 84 | offset = ELF32_R_SYM(rel->r_info); |
84 | if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { | 85 | if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { |
85 | printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n", | 86 | pr_err("%s: section %u reloc %u: bad relocation sym offset\n", |
86 | module->name, relindex, i); | 87 | module->name, relindex, i); |
87 | return -ENOEXEC; | 88 | return -ENOEXEC; |
88 | } | 89 | } |
89 | 90 | ||
90 | sym = ((Elf32_Sym *)symsec->sh_addr) + offset; | 91 | sym = ((Elf32_Sym *)symsec->sh_addr) + offset; |
92 | symname = strtab + sym->st_name; | ||
91 | 93 | ||
92 | if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { | 94 | if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { |
93 | printk(KERN_ERR "%s: out of bounds relocation, " | 95 | pr_err("%s: section %u reloc %u sym '%s': out of bounds relocation, offset %d size %u\n", |
94 | "section %d reloc %d offset %d size %d\n", | 96 | module->name, relindex, i, symname, |
95 | module->name, relindex, i, rel->r_offset, | 97 | rel->r_offset, dstsec->sh_size); |
96 | dstsec->sh_size); | ||
97 | return -ENOEXEC; | 98 | return -ENOEXEC; |
98 | } | 99 | } |
99 | 100 | ||
@@ -119,10 +120,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
119 | if (offset & 3 || | 120 | if (offset & 3 || |
120 | offset <= (s32)0xfe000000 || | 121 | offset <= (s32)0xfe000000 || |
121 | offset >= (s32)0x02000000) { | 122 | offset >= (s32)0x02000000) { |
122 | printk(KERN_ERR | 123 | pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", |
123 | "%s: relocation out of range, section " | 124 | module->name, relindex, i, symname, |
124 | "%d reloc %d sym '%s'\n", module->name, | 125 | ELF32_R_TYPE(rel->r_info), loc, |
125 | relindex, i, strtab + sym->st_name); | 126 | sym->st_value); |
126 | return -ENOEXEC; | 127 | return -ENOEXEC; |
127 | } | 128 | } |
128 | 129 | ||
@@ -195,10 +196,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
195 | if (!(offset & 1) || | 196 | if (!(offset & 1) || |
196 | offset <= (s32)0xff000000 || | 197 | offset <= (s32)0xff000000 || |
197 | offset >= (s32)0x01000000) { | 198 | offset >= (s32)0x01000000) { |
198 | printk(KERN_ERR | 199 | pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", |
199 | "%s: relocation out of range, section " | 200 | module->name, relindex, i, symname, |
200 | "%d reloc %d sym '%s'\n", module->name, | 201 | ELF32_R_TYPE(rel->r_info), loc, |
201 | relindex, i, strtab + sym->st_name); | 202 | sym->st_value); |
202 | return -ENOEXEC; | 203 | return -ENOEXEC; |
203 | } | 204 | } |
204 | 205 | ||