^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (C) 2005-2017 Andes Technology Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/moduleloader.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) void *module_alloc(unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) __builtin_return_address(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) void module_free(struct module *module, void *region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) vfree(region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int module_frob_arch_sections(Elf_Ehdr * hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) Elf_Shdr * sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) char *secstrings, struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) void do_reloc16(unsigned int val, unsigned int *loc, unsigned int val_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) unsigned int val_shift, unsigned int loc_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned int partial_in_place, unsigned int swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned int tmp = 0, tmp2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) __asm__ __volatile__("\tlhi.bi\t%0, [%2], 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) "\tbeqz\t%3, 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "\twsbh\t%0, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) tmp2 = tmp & loc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (partial_in_place) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) tmp &= (~loc_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) tmp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) tmp = tmp2 | ((val & val_mask) >> val_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) __asm__ __volatile__("\tbeqz\t%3, 2f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) "\twsbh\t%0, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) "2:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) "\tshi.bi\t%0, [%2], 0\n":"=r"(tmp):"0"(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) "r"(loc), "r"(swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) void do_reloc32(unsigned int val, unsigned int *loc, unsigned int val_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int val_shift, unsigned int loc_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned int partial_in_place, unsigned int swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int tmp = 0, tmp2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) __asm__ __volatile__("\tlmw.bi\t%0, [%2], %0, 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "\tbeqz\t%3, 1f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) "\twsbh\t%0, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "\trotri\t%0, %1, 16\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) tmp2 = tmp & loc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (partial_in_place) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) tmp &= (~loc_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) tmp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) tmp = tmp2 | ((val & val_mask) >> val_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) __asm__ __volatile__("\tbeqz\t%3, 2f\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) "\twsbh\t%0, %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) "\trotri\t%0, %1, 16\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "2:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "\tsmw.bi\t%0, [%2], %0, 0\n":"=r"(tmp):"0"(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) "r"(loc), "r"(swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static inline int exceed_limit(int offset, unsigned int val_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct module *module, Elf32_Rela * rel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned int relindex, unsigned int reloc_order)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int abs_off = offset < 0 ? ~offset : offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (abs_off & (~val_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pr_err("\n%s: relocation type %d out of range.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) "please rebuild the kernel module with gcc option \"-Wa,-mno-small-text\".\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) module->name, ELF32_R_TYPE(rel->r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) pr_err("section %d reloc %d offset 0x%x relative 0x%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) relindex, reloc_order, rel->r_offset, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #ifdef __NDS32_EL__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define NEED_SWAP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define NEED_SWAP 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned int symindex, unsigned int relindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct module *module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) Elf32_Shdr *symsec = sechdrs + symindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) Elf32_Shdr *relsec = sechdrs + relindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) Elf32_Rela *rel = (void *)relsec->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) Elf32_Addr *loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) Elf32_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) Elf32_Addr v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) s32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) offset = ELF32_R_SYM(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (offset < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pr_err("%s: bad relocation\n", module->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) pr_err("section %d reloc %d\n", relindex, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) sym = ((Elf32_Sym *) symsec->sh_addr) + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (rel->r_offset < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) || rel->r_offset > dstsec->sh_size - sizeof(u16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) pr_err("%s: out of bounds relocation\n", module->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) pr_err("section %d reloc %d offset 0x%0x size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) relindex, i, rel->r_offset, dstsec->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) loc = (Elf32_Addr *) (dstsec->sh_addr + rel->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) v = sym->st_value + rel->r_addend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) switch (ELF32_R_TYPE(rel->r_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) case R_NDS32_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case R_NDS32_INSN16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) case R_NDS32_LABEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case R_NDS32_LONGCALL1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case R_NDS32_LONGCALL2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case R_NDS32_LONGCALL3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case R_NDS32_LONGCALL4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) case R_NDS32_LONGJUMP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case R_NDS32_LONGJUMP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case R_NDS32_LONGJUMP3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case R_NDS32_9_FIXED_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case R_NDS32_15_FIXED_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) case R_NDS32_17_FIXED_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case R_NDS32_25_FIXED_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case R_NDS32_LOADSTORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case R_NDS32_DWARF2_OP1_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case R_NDS32_DWARF2_OP2_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case R_NDS32_DWARF2_LEB_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case R_NDS32_RELA_NOP_MIX ... R_NDS32_RELA_NOP_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case R_NDS32_32_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) do_reloc32(v, loc, 0xffffffff, 0, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case R_NDS32_HI20_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) do_reloc32(v, loc, 0xfffff000, 12, 0xfff00000, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case R_NDS32_LO12S3_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) do_reloc32(v, loc, 0x00000fff, 3, 0xfffff000, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case R_NDS32_LO12S2_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) do_reloc32(v, loc, 0x00000fff, 2, 0xfffff000, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case R_NDS32_LO12S1_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) do_reloc32(v, loc, 0x00000fff, 1, 0xfffff000, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) case R_NDS32_LO12S0_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case R_NDS32_LO12S0_ORI_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) do_reloc32(v, loc, 0x00000fff, 0, 0xfffff000, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case R_NDS32_9_PCREL_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (exceed_limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ((v - (Elf32_Addr) loc), 0x000000ff, module, rel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) relindex, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) do_reloc16(v - (Elf32_Addr) loc, loc, 0x000001ff, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 0xffffff00, 0, NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case R_NDS32_15_PCREL_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (exceed_limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ((v - (Elf32_Addr) loc), 0x00003fff, module, rel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) relindex, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) do_reloc32(v - (Elf32_Addr) loc, loc, 0x00007fff, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 0xffffc000, 0, NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case R_NDS32_17_PCREL_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (exceed_limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ((v - (Elf32_Addr) loc), 0x0000ffff, module, rel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) relindex, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) do_reloc32(v - (Elf32_Addr) loc, loc, 0x0001ffff, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 0xffff0000, 0, NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case R_NDS32_25_PCREL_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (exceed_limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ((v - (Elf32_Addr) loc), 0x00ffffff, module, rel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) relindex, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) do_reloc32(v - (Elf32_Addr) loc, loc, 0x01ffffff, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 0xff000000, 0, NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case R_NDS32_WORD_9_PCREL_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (exceed_limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ((v - (Elf32_Addr) loc), 0x000000ff, module, rel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) relindex, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) do_reloc32(v - (Elf32_Addr) loc, loc, 0x000001ff, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 0xffffff00, 0, NEED_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case R_NDS32_SDA15S3_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case R_NDS32_SDA15S2_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) case R_NDS32_SDA15S1_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) case R_NDS32_SDA15S0_RELA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) pr_err("%s: unsupported relocation type %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) module->name, ELF32_R_TYPE(rel->r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) pr_err
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ("Small data section access doesn't work in the kernel space; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) "please rebuild the kernel module with gcc option -mcmodel=large.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) pr_err("section %d reloc %d offset 0x%x size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) relindex, i, rel->r_offset, dstsec->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) pr_err("%s: unsupported relocation type %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) module->name, ELF32_R_TYPE(rel->r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) pr_err("section %d reloc %d offset 0x%x size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) relindex, i, rel->r_offset, dstsec->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr * sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct module *module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) void module_arch_cleanup(struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }