From 2c3c1048746a4622d8c89a29670120dc8fab93c4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:49:45 +0200 Subject: Adding upstream version 6.1.76. Signed-off-by: Daniel Baumann --- arch/microblaze/kernel/module.c | 96 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 arch/microblaze/kernel/module.c (limited to 'arch/microblaze/kernel/module.c') diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c new file mode 100644 index 000000000..e5db3a57b --- /dev/null +++ b/arch/microblaze/kernel/module.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2007-2009 Michal Simek + * Copyright (C) 2007-2009 PetaLogix + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, + unsigned int symindex, unsigned int relsec, struct module *module) +{ + + unsigned int i; + Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; + Elf32_Sym *sym; + unsigned long int *location; + unsigned long int value; + + pr_debug("Applying add relocation section %u to %u\n", + relsec, sechdrs[relsec].sh_info); + + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { + + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + + rela[i].r_offset; + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr + + ELF32_R_SYM(rela[i].r_info); + value = sym->st_value + rela[i].r_addend; + + switch (ELF32_R_TYPE(rela[i].r_info)) { + + /* + * Be careful! mb-gcc / mb-ld splits the relocs between the + * text and the reloc table. In general this means we must + * read the current contents of (*location), add any offset + * then store the result back in + */ + + case R_MICROBLAZE_32: + *location = value; + break; + + case R_MICROBLAZE_64: + location[0] = (location[0] & 0xFFFF0000) | + (value >> 16); + location[1] = (location[1] & 0xFFFF0000) | + (value & 0xFFFF); + break; + + case R_MICROBLAZE_64_PCREL: + value -= (unsigned long int)(location) + 4; + location[0] = (location[0] & 0xFFFF0000) | + (value >> 16); + location[1] = (location[1] & 0xFFFF0000) | + (value & 0xFFFF); + pr_debug("R_MICROBLAZE_64_PCREL (%08lx)\n", + value); + break; + + case R_MICROBLAZE_32_PCREL_LO: + pr_debug("R_MICROBLAZE_32_PCREL_LO\n"); + break; + + case R_MICROBLAZE_64_NONE: + pr_debug("R_MICROBLAZE_64_NONE\n"); + break; + + case R_MICROBLAZE_NONE: + pr_debug("R_MICROBLAZE_NONE\n"); + break; + + default: + pr_err("module %s: Unknown relocation: %u\n", + module->name, + ELF32_R_TYPE(rela[i].r_info)); + return -ENOEXEC; + } + } + return 0; +} + +int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, + struct module *module) +{ + flush_dcache(); + return 0; +} -- cgit v1.2.3