aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/kernel/module.c')
-rw-r--r--arch/arc/kernel/module.c53
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
116relo_err: 121relo_err: