cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

module.c (2716B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*  Kernel module help for SH.
      3
      4    SHcompact version by Kaz Kojima and Paul Mundt.
      5
      6    SHmedia bits:
      7
      8	Copyright 2004 SuperH (UK) Ltd
      9	Author: Richard Curnow
     10
     11	Based on the sh version, and on code from the sh64-specific parts of
     12	modutils, originally written by Richard Curnow and Ben Gaster.
     13*/
     14#include <linux/moduleloader.h>
     15#include <linux/elf.h>
     16#include <linux/vmalloc.h>
     17#include <linux/bug.h>
     18#include <linux/fs.h>
     19#include <linux/string.h>
     20#include <linux/kernel.h>
     21#include <asm/unaligned.h>
     22#include <asm/dwarf.h>
     23
     24int apply_relocate_add(Elf32_Shdr *sechdrs,
     25		   const char *strtab,
     26		   unsigned int symindex,
     27		   unsigned int relsec,
     28		   struct module *me)
     29{
     30	unsigned int i;
     31	Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
     32	Elf32_Sym *sym;
     33	Elf32_Addr relocation;
     34	uint32_t *location;
     35	uint32_t value;
     36
     37	pr_debug("Applying relocate section %u to %u\n", relsec,
     38		 sechdrs[relsec].sh_info);
     39	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
     40		/* This is where to make the change */
     41		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
     42			+ rel[i].r_offset;
     43		/* This is the symbol it is referring to.  Note that all
     44		   undefined symbols have been resolved.  */
     45		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
     46			+ ELF32_R_SYM(rel[i].r_info);
     47		relocation = sym->st_value + rel[i].r_addend;
     48
     49		switch (ELF32_R_TYPE(rel[i].r_info)) {
     50		case R_SH_NONE:
     51			break;
     52		case R_SH_DIR32:
     53			value = get_unaligned(location);
     54			value += relocation;
     55			put_unaligned(value, location);
     56			break;
     57		case R_SH_REL32:
     58			relocation = (relocation - (Elf32_Addr) location);
     59			value = get_unaligned(location);
     60			value += relocation;
     61			put_unaligned(value, location);
     62			break;
     63		case R_SH_IMM_LOW16:
     64			*location = (*location & ~0x3fffc00) |
     65				((relocation & 0xffff) << 10);
     66			break;
     67		case R_SH_IMM_MEDLOW16:
     68			*location = (*location & ~0x3fffc00) |
     69				(((relocation >> 16) & 0xffff) << 10);
     70			break;
     71		case R_SH_IMM_LOW16_PCREL:
     72			relocation -= (Elf32_Addr) location;
     73			*location = (*location & ~0x3fffc00) |
     74				((relocation & 0xffff) << 10);
     75			break;
     76		case R_SH_IMM_MEDLOW16_PCREL:
     77			relocation -= (Elf32_Addr) location;
     78			*location = (*location & ~0x3fffc00) |
     79				(((relocation >> 16) & 0xffff) << 10);
     80			break;
     81		default:
     82			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
     83			       me->name, ELF32_R_TYPE(rel[i].r_info));
     84			return -ENOEXEC;
     85		}
     86	}
     87	return 0;
     88}
     89
     90int module_finalize(const Elf_Ehdr *hdr,
     91		    const Elf_Shdr *sechdrs,
     92		    struct module *me)
     93{
     94	int ret = 0;
     95
     96	ret |= module_dwarf_finalize(hdr, sechdrs, me);
     97
     98	return ret;
     99}
    100
    101void module_arch_cleanup(struct module *mod)
    102{
    103	module_dwarf_cleanup(mod);
    104}