~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/hexagon/kernel/module.c

Version: ~ [ linux-5.5 ] ~ [ linux-5.4.15 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.98 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.167 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.211 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.211 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.81 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Kernel module loader for Hexagon
  3  *
  4  * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License version 2 and
  8  * only version 2 as published by the Free Software Foundation.
  9  *
 10  * This program is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  * GNU General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU General Public License
 16  * along with this program; if not, write to the Free Software
 17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 18  * 02110-1301, USA.
 19  */
 20 
 21 #include <asm/module.h>
 22 #include <linux/elf.h>
 23 #include <linux/module.h>
 24 #include <linux/moduleloader.h>
 25 #include <linux/vmalloc.h>
 26 
 27 #if 0
 28 #define DEBUGP printk
 29 #else
 30 #define DEBUGP(fmt , ...)
 31 #endif
 32 
 33 /*
 34  * module_frob_arch_sections - tweak got/plt sections.
 35  * @hdr - pointer to elf header
 36  * @sechdrs - pointer to elf load section headers
 37  * @secstrings - symbol names
 38  * @mod - pointer to module
 39  */
 40 int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
 41                                 char *secstrings,
 42                                 struct module *mod)
 43 {
 44         unsigned int i;
 45         int found = 0;
 46 
 47         /* Look for .plt and/or .got.plt and/or .init.plt sections */
 48         for (i = 0; i < hdr->e_shnum; i++) {
 49                 DEBUGP("Section %d is %s\n", i,
 50                        secstrings + sechdrs[i].sh_name);
 51                 if (strcmp(secstrings + sechdrs[i].sh_name, ".plt") == 0)
 52                         found = i+1;
 53                 if (strcmp(secstrings + sechdrs[i].sh_name, ".got.plt") == 0)
 54                         found = i+1;
 55                 if (strcmp(secstrings + sechdrs[i].sh_name, ".rela.plt") == 0)
 56                         found = i+1;
 57         }
 58 
 59         /* At this time, we don't support modules comiled with -shared */
 60         if (found) {
 61                 printk(KERN_WARNING
 62                         "Module '%s' contains unexpected .plt/.got sections.\n",
 63                         mod->name);
 64                 /*  return -ENOEXEC;  */
 65         }
 66 
 67         return 0;
 68 }
 69 
 70 /*
 71  * apply_relocate_add - perform rela relocations.
 72  * @sechdrs - pointer to section headers
 73  * @strtab - some sort of start address?
 74  * @symindex - symbol index offset or something?
 75  * @relsec - address to relocate to?
 76  * @module - pointer to module
 77  *
 78  * Perform rela relocations.
 79  */
 80 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
 81                         unsigned int symindex, unsigned int relsec,
 82                         struct module *module)
 83 {
 84         unsigned int i;
 85         Elf32_Sym *sym;
 86         uint32_t *location;
 87         uint32_t value;
 88         unsigned int nrelocs = sechdrs[relsec].sh_size / sizeof(Elf32_Rela);
 89         Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
 90         Elf32_Word sym_info = sechdrs[relsec].sh_info;
 91         Elf32_Sym *sym_base = (Elf32_Sym *) sechdrs[symindex].sh_addr;
 92         void *loc_base = (void *) sechdrs[sym_info].sh_addr;
 93 
 94         DEBUGP("Applying relocations in section %u to section %u base=%p\n",
 95                relsec, sym_info, loc_base);
 96 
 97         for (i = 0; i < nrelocs; i++) {
 98 
 99                 /* Symbol to relocate */
100                 sym = sym_base + ELF32_R_SYM(rela[i].r_info);
101 
102                 /* Where to make the change */
103                 location = loc_base + rela[i].r_offset;
104 
105                 /* `Everything is relative'. */
106                 value = sym->st_value + rela[i].r_addend;
107 
108                 DEBUGP("%d: value=%08x loc=%p reloc=%d symbol=%s\n",
109                        i, value, location, ELF32_R_TYPE(rela[i].r_info),
110                        sym->st_name ?
111                        &strtab[sym->st_name] : "(anonymous)");
112 
113                 switch (ELF32_R_TYPE(rela[i].r_info)) {
114                 case R_HEXAGON_B22_PCREL: {
115                         int dist = (int)(value - (uint32_t)location);
116                         if ((dist < -0x00800000) ||
117                             (dist >= 0x00800000)) {
118                                 printk(KERN_ERR
119                                        "%s: %s: %08x=%08x-%08x %s\n",
120                                        module->name,
121                                        "R_HEXAGON_B22_PCREL reloc out of range",
122                                        dist, value, (uint32_t)location,
123                                        sym->st_name ?
124                                        &strtab[sym->st_name] : "(anonymous)");
125                                 return -ENOEXEC;
126                         }
127                         DEBUGP("B22_PCREL contents: %08X.\n", *location);
128                         *location &= ~0x01ff3fff;
129                         *location |= 0x00003fff & dist;
130                         *location |= 0x01ff0000 & (dist<<2);
131                         DEBUGP("Contents after reloc: %08x\n", *location);
132                         break;
133                 }
134                 case R_HEXAGON_HI16:
135                         value = (value>>16) & 0xffff;
136                         /* fallthrough */
137                 case R_HEXAGON_LO16:
138                         *location &= ~0x00c03fff;
139                         *location |= value & 0x3fff;
140                         *location |= (value & 0xc000) << 8;
141                         break;
142                 case R_HEXAGON_32:
143                         *location = value;
144                         break;
145                 case R_HEXAGON_32_PCREL:
146                         *location = value - (uint32_t)location;
147                         break;
148                 case R_HEXAGON_PLT_B22_PCREL:
149                 case R_HEXAGON_GOTOFF_LO16:
150                 case R_HEXAGON_GOTOFF_HI16:
151                         printk(KERN_ERR "%s: GOT/PLT relocations unsupported\n",
152                                module->name);
153                         return -ENOEXEC;
154                 default:
155                         printk(KERN_ERR "%s: unknown relocation: %u\n",
156                                module->name,
157                                ELF32_R_TYPE(rela[i].r_info));
158                         return -ENOEXEC;
159                 }
160         }
161         return 0;
162 }
163 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp