0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/moduleloader.h>
0009 #include <linux/kernel.h>
0010 #include <linux/elf.h>
0011 #include <linux/vmalloc.h>
0012 #include <linux/fs.h>
0013 #include <linux/gfp.h>
0014 #include <linux/string.h>
0015 #include <linux/ctype.h>
0016 #include <linux/mm.h>
0017
0018 #include <asm/processor.h>
0019 #include <asm/spitfire.h>
0020 #include <asm/cacheflush.h>
0021
0022 #include "entry.h"
0023
0024 #ifdef CONFIG_SPARC64
0025
0026 #include <linux/jump_label.h>
0027
0028 static void *module_map(unsigned long size)
0029 {
0030 if (PAGE_ALIGN(size) > MODULES_LEN)
0031 return NULL;
0032 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
0033 GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
0034 __builtin_return_address(0));
0035 }
0036 #else
0037 static void *module_map(unsigned long size)
0038 {
0039 return vmalloc(size);
0040 }
0041 #endif
0042
0043 void *module_alloc(unsigned long size)
0044 {
0045 void *ret;
0046
0047 ret = module_map(size);
0048 if (ret)
0049 memset(ret, 0, size);
0050
0051 return ret;
0052 }
0053
0054
0055 int module_frob_arch_sections(Elf_Ehdr *hdr,
0056 Elf_Shdr *sechdrs,
0057 char *secstrings,
0058 struct module *mod)
0059 {
0060 unsigned int symidx;
0061 Elf_Sym *sym;
0062 char *strtab;
0063 int i;
0064
0065 for (symidx = 0; sechdrs[symidx].sh_type != SHT_SYMTAB; symidx++) {
0066 if (symidx == hdr->e_shnum-1) {
0067 printk("%s: no symtab found.\n", mod->name);
0068 return -ENOEXEC;
0069 }
0070 }
0071 sym = (Elf_Sym *)sechdrs[symidx].sh_addr;
0072 strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr;
0073
0074 for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) {
0075 if (sym[i].st_shndx == SHN_UNDEF) {
0076 if (ELF_ST_TYPE(sym[i].st_info) == STT_REGISTER)
0077 sym[i].st_shndx = SHN_ABS;
0078 }
0079 }
0080 return 0;
0081 }
0082
0083 int apply_relocate_add(Elf_Shdr *sechdrs,
0084 const char *strtab,
0085 unsigned int symindex,
0086 unsigned int relsec,
0087 struct module *me)
0088 {
0089 unsigned int i;
0090 Elf_Rela *rel = (void *)sechdrs[relsec].sh_addr;
0091 Elf_Sym *sym;
0092 u8 *location;
0093 u32 *loc32;
0094
0095 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
0096 Elf_Addr v;
0097
0098
0099 location = (u8 *)sechdrs[sechdrs[relsec].sh_info].sh_addr
0100 + rel[i].r_offset;
0101 loc32 = (u32 *) location;
0102
0103 #ifdef CONFIG_SPARC64
0104 BUG_ON(((u64)location >> (u64)32) != (u64)0);
0105 #endif
0106
0107
0108
0109 sym = (Elf_Sym *)sechdrs[symindex].sh_addr
0110 + ELF_R_SYM(rel[i].r_info);
0111 v = sym->st_value + rel[i].r_addend;
0112
0113 switch (ELF_R_TYPE(rel[i].r_info) & 0xff) {
0114 case R_SPARC_DISP32:
0115 v -= (Elf_Addr) location;
0116 *loc32 = v;
0117 break;
0118 #ifdef CONFIG_SPARC64
0119 case R_SPARC_64:
0120 location[0] = v >> 56;
0121 location[1] = v >> 48;
0122 location[2] = v >> 40;
0123 location[3] = v >> 32;
0124 location[4] = v >> 24;
0125 location[5] = v >> 16;
0126 location[6] = v >> 8;
0127 location[7] = v >> 0;
0128 break;
0129
0130 case R_SPARC_WDISP19:
0131 v -= (Elf_Addr) location;
0132 *loc32 = (*loc32 & ~0x7ffff) |
0133 ((v >> 2) & 0x7ffff);
0134 break;
0135
0136 case R_SPARC_OLO10:
0137 *loc32 = (*loc32 & ~0x1fff) |
0138 (((v & 0x3ff) +
0139 (ELF_R_TYPE(rel[i].r_info) >> 8))
0140 & 0x1fff);
0141 break;
0142 #endif
0143
0144 case R_SPARC_32:
0145 case R_SPARC_UA32:
0146 location[0] = v >> 24;
0147 location[1] = v >> 16;
0148 location[2] = v >> 8;
0149 location[3] = v >> 0;
0150 break;
0151
0152 case R_SPARC_WDISP30:
0153 v -= (Elf_Addr) location;
0154 *loc32 = (*loc32 & ~0x3fffffff) |
0155 ((v >> 2) & 0x3fffffff);
0156 break;
0157
0158 case R_SPARC_WDISP22:
0159 v -= (Elf_Addr) location;
0160 *loc32 = (*loc32 & ~0x3fffff) |
0161 ((v >> 2) & 0x3fffff);
0162 break;
0163
0164 case R_SPARC_LO10:
0165 *loc32 = (*loc32 & ~0x3ff) | (v & 0x3ff);
0166 break;
0167
0168 case R_SPARC_HI22:
0169 *loc32 = (*loc32 & ~0x3fffff) |
0170 ((v >> 10) & 0x3fffff);
0171 break;
0172
0173 default:
0174 printk(KERN_ERR "module %s: Unknown relocation: %x\n",
0175 me->name,
0176 (int) (ELF_R_TYPE(rel[i].r_info) & 0xff));
0177 return -ENOEXEC;
0178 }
0179 }
0180 return 0;
0181 }
0182
0183 #ifdef CONFIG_SPARC64
0184 static void do_patch_sections(const Elf_Ehdr *hdr,
0185 const Elf_Shdr *sechdrs)
0186 {
0187 const Elf_Shdr *s, *sun4v_1insn = NULL, *sun4v_2insn = NULL;
0188 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
0189
0190 for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
0191 if (!strcmp(".sun4v_1insn_patch", secstrings + s->sh_name))
0192 sun4v_1insn = s;
0193 if (!strcmp(".sun4v_2insn_patch", secstrings + s->sh_name))
0194 sun4v_2insn = s;
0195 }
0196
0197 if (sun4v_1insn && tlb_type == hypervisor) {
0198 void *p = (void *) sun4v_1insn->sh_addr;
0199 sun4v_patch_1insn_range(p, p + sun4v_1insn->sh_size);
0200 }
0201 if (sun4v_2insn && tlb_type == hypervisor) {
0202 void *p = (void *) sun4v_2insn->sh_addr;
0203 sun4v_patch_2insn_range(p, p + sun4v_2insn->sh_size);
0204 }
0205 }
0206
0207 int module_finalize(const Elf_Ehdr *hdr,
0208 const Elf_Shdr *sechdrs,
0209 struct module *me)
0210 {
0211 do_patch_sections(hdr, sechdrs);
0212
0213
0214 if (tlb_type == spitfire) {
0215 unsigned long va;
0216
0217 flushw_all();
0218 for (va = 0; va < (PAGE_SIZE << 1); va += 32)
0219 spitfire_put_icache_tag(va, 0x0);
0220 __asm__ __volatile__("flush %g6");
0221 }
0222
0223 return 0;
0224 }
0225 #endif