1 // SPDX-License-Identifier: GPL-2.0-only << 2 /* 1 /* 3 * Copyright (C) 2007-2009 Michal Simek <monst !! 2 * This file is subject to the terms and conditions of the GNU General Public 4 * Copyright (C) 2007-2009 PetaLogix !! 3 * License. See the file COPYING in the main directory of this archive >> 4 * for more details. 5 */ 5 */ 6 6 7 #include <linux/export.h> << 8 #include <linux/moduleloader.h> 7 #include <linux/moduleloader.h> 9 #include <linux/kernel.h> << 10 #include <linux/elf.h> 8 #include <linux/elf.h> 11 #include <linux/vmalloc.h> 9 #include <linux/vmalloc.h> 12 #include <linux/fs.h> 10 #include <linux/fs.h> 13 #include <linux/string.h> 11 #include <linux/string.h> 14 #include <linux/pgtable.h> !! 12 #include <linux/kernel.h> 15 << 16 #include <asm/cacheflush.h> << 17 13 18 int apply_relocate_add(Elf32_Shdr *sechdrs, co !! 14 #if 0 19 unsigned int symindex, unsigned int re !! 15 #define DEBUGP(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) >> 16 #else >> 17 #define DEBUGP(fmt, ...) no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) >> 18 #endif >> 19 >> 20 #ifdef CONFIG_MODULES >> 21 >> 22 int apply_relocate(Elf32_Shdr *sechdrs, >> 23 const char *strtab, >> 24 unsigned int symindex, >> 25 unsigned int relsec, >> 26 struct module *me) 20 { 27 { 21 << 22 unsigned int i; 28 unsigned int i; 23 Elf32_Rela *rela = (void *)sechdrs[rel !! 29 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; 24 Elf32_Sym *sym; 30 Elf32_Sym *sym; 25 unsigned long int *location; !! 31 uint32_t *location; 26 unsigned long int value; << 27 << 28 pr_debug("Applying add relocation sect << 29 relsec, sechdrs[relsec].sh_inf << 30 << 31 for (i = 0; i < sechdrs[relsec].sh_siz << 32 << 33 location = (void *)sechdrs[sec << 34 rela[i].r_offs << 35 sym = (Elf32_Sym *)sechdrs[sym << 36 ELF32_R_SYM(rela[i].r_ << 37 value = sym->st_value + rela[i << 38 << 39 switch (ELF32_R_TYPE(rela[i].r << 40 << 41 /* << 42 * Be careful! mb-gcc / mb-ld << 43 * text and the reloc table. I << 44 * read the current contents o << 45 * then store the result back << 46 */ << 47 32 48 case R_MICROBLAZE_32: !! 33 DEBUGP("Applying relocate section %u to %u\n", relsec, 49 *location = value; !! 34 sechdrs[relsec].sh_info); 50 break; !! 35 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 51 !! 36 /* This is where to make the change */ 52 case R_MICROBLAZE_64: !! 37 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 53 location[0] = (locatio !! 38 + rel[i].r_offset; 54 (value !! 39 /* This is the symbol it is referring to. Note that all 55 location[1] = (locatio !! 40 undefined symbols have been resolved. */ 56 (value !! 41 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 57 break; !! 42 + ELF32_R_SYM(rel[i].r_info); 58 !! 43 59 case R_MICROBLAZE_64_PCREL: !! 44 switch (ELF32_R_TYPE(rel[i].r_info)) { 60 value -= (unsigned lon !! 45 case R_68K_32: 61 location[0] = (locatio !! 46 /* We add the value into the location given */ 62 (value !! 47 *location += sym->st_value; 63 location[1] = (locatio !! 48 break; 64 (value !! 49 case R_68K_PC32: 65 pr_debug("R_MICROBLAZE !! 50 /* Add the value, subtract its position */ 66 value); !! 51 *location += sym->st_value - (uint32_t)location; 67 break; << 68 << 69 case R_MICROBLAZE_32_PCREL_LO: << 70 pr_debug("R_MICROBLAZE << 71 break; 52 break; >> 53 default: >> 54 pr_err("module %s: Unknown relocation: %u\n", me->name, >> 55 ELF32_R_TYPE(rel[i].r_info)); >> 56 return -ENOEXEC; >> 57 } >> 58 } >> 59 return 0; >> 60 } 72 61 73 case R_MICROBLAZE_64_NONE: !! 62 int apply_relocate_add(Elf32_Shdr *sechdrs, 74 pr_debug("R_MICROBLAZE !! 63 const char *strtab, 75 break; !! 64 unsigned int symindex, >> 65 unsigned int relsec, >> 66 struct module *me) >> 67 { >> 68 unsigned int i; >> 69 Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; >> 70 Elf32_Sym *sym; >> 71 uint32_t *location; 76 72 77 case R_MICROBLAZE_NONE: !! 73 DEBUGP("Applying relocate_add section %u to %u\n", relsec, 78 pr_debug("R_MICROBLAZE !! 74 sechdrs[relsec].sh_info); >> 75 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { >> 76 /* This is where to make the change */ >> 77 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr >> 78 + rel[i].r_offset; >> 79 /* This is the symbol it is referring to. Note that all >> 80 undefined symbols have been resolved. */ >> 81 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr >> 82 + ELF32_R_SYM(rel[i].r_info); >> 83 >> 84 switch (ELF32_R_TYPE(rel[i].r_info)) { >> 85 case R_68K_32: >> 86 /* We add the value into the location given */ >> 87 *location = rel[i].r_addend + sym->st_value; >> 88 break; >> 89 case R_68K_PC32: >> 90 /* Add the value, subtract its position */ >> 91 *location = rel[i].r_addend + sym->st_value - (uint32_t)location; 79 break; 92 break; 80 << 81 default: 93 default: 82 pr_err("module %s: Unk !! 94 pr_err("module %s: Unknown relocation: %u\n", me->name, 83 module->name, !! 95 ELF32_R_TYPE(rel[i].r_info)); 84 ELF32_R_TYPE(r << 85 return -ENOEXEC; 96 return -ENOEXEC; 86 } 97 } 87 } 98 } 88 return 0; 99 return 0; 89 } 100 } 90 101 91 int module_finalize(const Elf32_Ehdr *hdr, con !! 102 int module_finalize(const Elf_Ehdr *hdr, 92 struct module *module) !! 103 const Elf_Shdr *sechdrs, >> 104 struct module *mod) 93 { 105 { 94 flush_dcache(); !! 106 module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end); 95 return 0; 107 return 0; >> 108 } >> 109 >> 110 #endif /* CONFIG_MODULES */ >> 111 >> 112 void module_fixup(struct module *mod, struct m68k_fixup_info *start, >> 113 struct m68k_fixup_info *end) >> 114 { >> 115 #ifdef CONFIG_MMU >> 116 struct m68k_fixup_info *fixup; >> 117 >> 118 for (fixup = start; fixup < end; fixup++) { >> 119 switch (fixup->type) { >> 120 case m68k_fixup_memoffset: >> 121 *(u32 *)fixup->addr = m68k_memoffset; >> 122 break; >> 123 case m68k_fixup_vnode_shift: >> 124 *(u16 *)fixup->addr += m68k_virt_to_node_shift; >> 125 break; >> 126 } >> 127 } >> 128 #endif 96 } 129 } 97 130
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.