diff options
Diffstat (limited to 'arch/arc/kernel/module.c')
-rw-r--r-- | arch/arc/kernel/module.c | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/arch/arc/kernel/module.c b/arch/arc/kernel/module.c index 9a2849756022..42e964db2967 100644 --- a/arch/arc/kernel/module.c +++ b/arch/arc/kernel/module.c | |||
@@ -30,17 +30,9 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, | |||
30 | char *secstr, struct module *mod) | 30 | char *secstr, struct module *mod) |
31 | { | 31 | { |
32 | #ifdef CONFIG_ARC_DW2_UNWIND | 32 | #ifdef CONFIG_ARC_DW2_UNWIND |
33 | int i; | ||
34 | |||
35 | mod->arch.unw_sec_idx = 0; | 33 | mod->arch.unw_sec_idx = 0; |
36 | mod->arch.unw_info = NULL; | 34 | mod->arch.unw_info = NULL; |
37 | 35 | mod->arch.secstr = secstr; | |
38 | for (i = 1; i < hdr->e_shnum; i++) { | ||
39 | if (strcmp(secstr+sechdrs[i].sh_name, ".eh_frame") == 0) { | ||
40 | mod->arch.unw_sec_idx = i; | ||
41 | break; | ||
42 | } | ||
43 | } | ||
44 | #endif | 36 | #endif |
45 | return 0; | 37 | return 0; |
46 | } | 38 | } |
@@ -59,29 +51,33 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
59 | unsigned int relsec, /* sec index for relo sec */ | 51 | unsigned int relsec, /* sec index for relo sec */ |
60 | struct module *module) | 52 | struct module *module) |
61 | { | 53 | { |
62 | int i, n; | 54 | int i, n, relo_type; |
63 | Elf32_Rela *rel_entry = (void *)sechdrs[relsec].sh_addr; | 55 | Elf32_Rela *rel_entry = (void *)sechdrs[relsec].sh_addr; |
64 | Elf32_Sym *sym_entry, *sym_sec; | 56 | Elf32_Sym *sym_entry, *sym_sec; |
65 | Elf32_Addr relocation; | 57 | Elf32_Addr relocation, location, tgt_addr; |
66 | Elf32_Addr location; | 58 | unsigned int tgtsec; |
67 | Elf32_Addr sec_to_patch; | 59 | |
68 | int relo_type; | 60 | /* |
69 | 61 | * @relsec has relocations e.g. .rela.init.text | |
70 | sec_to_patch = sechdrs[sechdrs[relsec].sh_info].sh_addr; | 62 | * @tgtsec is section to patch e.g. .init.text |
63 | */ | ||
64 | tgtsec = sechdrs[relsec].sh_info; | ||
65 | tgt_addr = sechdrs[tgtsec].sh_addr; | ||
71 | sym_sec = (Elf32_Sym *) sechdrs[symindex].sh_addr; | 66 | sym_sec = (Elf32_Sym *) sechdrs[symindex].sh_addr; |
72 | n = sechdrs[relsec].sh_size / sizeof(*rel_entry); | 67 | n = sechdrs[relsec].sh_size / sizeof(*rel_entry); |
73 | 68 | ||
74 | pr_debug("\n========== Module Sym reloc ===========================\n"); | 69 | pr_debug("\nSection to fixup %s @%x\n", |
75 | pr_debug("Section to fixup %x\n", sec_to_patch); | 70 | module->arch.secstr + sechdrs[tgtsec].sh_name, tgt_addr); |
76 | pr_debug("=========================================================\n"); | 71 | pr_debug("=========================================================\n"); |
77 | pr_debug("rela->r_off | rela->addend | sym->st_value | ADDR | VALUE\n"); | 72 | pr_debug("r_off\tr_add\tst_value ADDRESS VALUE\n"); |
78 | pr_debug("=========================================================\n"); | 73 | pr_debug("=========================================================\n"); |
79 | 74 | ||
80 | /* Loop thru entries in relocation section */ | 75 | /* Loop thru entries in relocation section */ |
81 | for (i = 0; i < n; i++) { | 76 | for (i = 0; i < n; i++) { |
77 | const char *s; | ||
82 | 78 | ||
83 | /* This is where to make the change */ | 79 | /* This is where to make the change */ |
84 | location = sec_to_patch + rel_entry[i].r_offset; | 80 | location = tgt_addr + rel_entry[i].r_offset; |
85 | 81 | ||
86 | /* This is the symbol it is referring to. Note that all | 82 | /* This is the symbol it is referring to. Note that all |
87 | undefined symbols have been resolved. */ | 83 | undefined symbols have been resolved. */ |
@@ -89,10 +85,15 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
89 | 85 | ||
90 | relocation = sym_entry->st_value + rel_entry[i].r_addend; | 86 | relocation = sym_entry->st_value + rel_entry[i].r_addend; |
91 | 87 | ||
92 | pr_debug("\t%x\t\t%x\t\t%x %x %x [%s]\n", | 88 | if (sym_entry->st_name == 0 && ELF_ST_TYPE (sym_entry->st_info) == STT_SECTION) { |
93 | rel_entry[i].r_offset, rel_entry[i].r_addend, | 89 | s = module->arch.secstr + sechdrs[sym_entry->st_shndx].sh_name; |
94 | sym_entry->st_value, location, relocation, | 90 | } else { |
95 | strtab + sym_entry->st_name); | 91 | s = strtab + sym_entry->st_name; |
92 | } | ||
93 | |||
94 | pr_debug(" %x\t%x\t%x %x %x [%s]\n", | ||
95 | rel_entry[i].r_offset, rel_entry[i].r_addend, | ||
96 | sym_entry->st_value, location, relocation, s); | ||
96 | 97 | ||
97 | /* This assumes modules are built with -mlong-calls | 98 | /* This assumes modules are built with -mlong-calls |
98 | * so any branches/jumps are absolute 32 bit jmps | 99 | * so any branches/jumps are absolute 32 bit jmps |
@@ -111,6 +112,10 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
111 | goto relo_err; | 112 | goto relo_err; |
112 | 113 | ||
113 | } | 114 | } |
115 | |||
116 | if (strcmp(module->arch.secstr+sechdrs[tgtsec].sh_name, ".eh_frame") == 0) | ||
117 | module->arch.unw_sec_idx = tgtsec; | ||
118 | |||
114 | return 0; | 119 | return 0; |
115 | 120 | ||
116 | relo_err: | 121 | relo_err: |