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 (3493B)


      1/*
      2 * This file is subject to the terms and conditions of the GNU General Public
      3 * License.  See the file COPYING in the main directory of this archive
      4 * for more details.
      5 */
      6
      7#include <linux/moduleloader.h>
      8#include <linux/elf.h>
      9#include <linux/vmalloc.h>
     10#include <linux/fs.h>
     11#include <linux/string.h>
     12#include <linux/kernel.h>
     13
     14#if 0
     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
     22int apply_relocate(Elf32_Shdr *sechdrs,
     23		   const char *strtab,
     24		   unsigned int symindex,
     25		   unsigned int relsec,
     26		   struct module *me)
     27{
     28	unsigned int i;
     29	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
     30	Elf32_Sym *sym;
     31	uint32_t *location;
     32
     33	DEBUGP("Applying relocate section %u to %u\n", relsec,
     34	       sechdrs[relsec].sh_info);
     35	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
     36		/* This is where to make the change */
     37		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
     38			+ rel[i].r_offset;
     39		/* This is the symbol it is referring to.  Note that all
     40		   undefined symbols have been resolved.  */
     41		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
     42			+ ELF32_R_SYM(rel[i].r_info);
     43
     44		switch (ELF32_R_TYPE(rel[i].r_info)) {
     45		case R_68K_32:
     46			/* We add the value into the location given */
     47			*location += sym->st_value;
     48			break;
     49		case R_68K_PC32:
     50			/* Add the value, subtract its position */
     51			*location += sym->st_value - (uint32_t)location;
     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}
     61
     62int apply_relocate_add(Elf32_Shdr *sechdrs,
     63		       const char *strtab,
     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;
     72
     73	DEBUGP("Applying relocate_add section %u to %u\n", relsec,
     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;
     92			break;
     93		default:
     94			pr_err("module %s: Unknown relocation: %u\n", me->name,
     95			       ELF32_R_TYPE(rel[i].r_info));
     96			return -ENOEXEC;
     97		}
     98	}
     99	return 0;
    100}
    101
    102int module_finalize(const Elf_Ehdr *hdr,
    103		    const Elf_Shdr *sechdrs,
    104		    struct module *mod)
    105{
    106	module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
    107	return 0;
    108}
    109
    110#endif /* CONFIG_MODULES */
    111
    112void 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
    129}