xref: /linux-6.15/arch/m68k/kernel/module.c (revision 1da177e4)
1*1da177e4SLinus Torvalds #include <linux/moduleloader.h>
2*1da177e4SLinus Torvalds #include <linux/elf.h>
3*1da177e4SLinus Torvalds #include <linux/vmalloc.h>
4*1da177e4SLinus Torvalds #include <linux/fs.h>
5*1da177e4SLinus Torvalds #include <linux/string.h>
6*1da177e4SLinus Torvalds #include <linux/kernel.h>
7*1da177e4SLinus Torvalds 
8*1da177e4SLinus Torvalds #if 0
9*1da177e4SLinus Torvalds #define DEBUGP printk
10*1da177e4SLinus Torvalds #else
11*1da177e4SLinus Torvalds #define DEBUGP(fmt...)
12*1da177e4SLinus Torvalds #endif
13*1da177e4SLinus Torvalds 
14*1da177e4SLinus Torvalds void *module_alloc(unsigned long size)
15*1da177e4SLinus Torvalds {
16*1da177e4SLinus Torvalds 	if (size == 0)
17*1da177e4SLinus Torvalds 		return NULL;
18*1da177e4SLinus Torvalds 	return vmalloc(size);
19*1da177e4SLinus Torvalds }
20*1da177e4SLinus Torvalds 
21*1da177e4SLinus Torvalds 
22*1da177e4SLinus Torvalds /* Free memory returned from module_alloc */
23*1da177e4SLinus Torvalds void module_free(struct module *mod, void *module_region)
24*1da177e4SLinus Torvalds {
25*1da177e4SLinus Torvalds 	vfree(module_region);
26*1da177e4SLinus Torvalds 	/* FIXME: If module_region == mod->init_region, trim exception
27*1da177e4SLinus Torvalds            table entries. */
28*1da177e4SLinus Torvalds }
29*1da177e4SLinus Torvalds 
30*1da177e4SLinus Torvalds /* We don't need anything special. */
31*1da177e4SLinus Torvalds int module_frob_arch_sections(Elf_Ehdr *hdr,
32*1da177e4SLinus Torvalds 			      Elf_Shdr *sechdrs,
33*1da177e4SLinus Torvalds 			      char *secstrings,
34*1da177e4SLinus Torvalds 			      struct module *mod)
35*1da177e4SLinus Torvalds {
36*1da177e4SLinus Torvalds 	return 0;
37*1da177e4SLinus Torvalds }
38*1da177e4SLinus Torvalds 
39*1da177e4SLinus Torvalds int apply_relocate(Elf32_Shdr *sechdrs,
40*1da177e4SLinus Torvalds 		   const char *strtab,
41*1da177e4SLinus Torvalds 		   unsigned int symindex,
42*1da177e4SLinus Torvalds 		   unsigned int relsec,
43*1da177e4SLinus Torvalds 		   struct module *me)
44*1da177e4SLinus Torvalds {
45*1da177e4SLinus Torvalds 	unsigned int i;
46*1da177e4SLinus Torvalds 	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
47*1da177e4SLinus Torvalds 	Elf32_Sym *sym;
48*1da177e4SLinus Torvalds 	uint32_t *location;
49*1da177e4SLinus Torvalds 
50*1da177e4SLinus Torvalds 	DEBUGP("Applying relocate section %u to %u\n", relsec,
51*1da177e4SLinus Torvalds 	       sechdrs[relsec].sh_info);
52*1da177e4SLinus Torvalds 	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
53*1da177e4SLinus Torvalds 		/* This is where to make the change */
54*1da177e4SLinus Torvalds 		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
55*1da177e4SLinus Torvalds 			+ rel[i].r_offset;
56*1da177e4SLinus Torvalds 		/* This is the symbol it is referring to.  Note that all
57*1da177e4SLinus Torvalds 		   undefined symbols have been resolved.  */
58*1da177e4SLinus Torvalds 		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
59*1da177e4SLinus Torvalds 			+ ELF32_R_SYM(rel[i].r_info);
60*1da177e4SLinus Torvalds 
61*1da177e4SLinus Torvalds 		switch (ELF32_R_TYPE(rel[i].r_info)) {
62*1da177e4SLinus Torvalds 		case R_68K_32:
63*1da177e4SLinus Torvalds 			/* We add the value into the location given */
64*1da177e4SLinus Torvalds 			*location += sym->st_value;
65*1da177e4SLinus Torvalds 			break;
66*1da177e4SLinus Torvalds 		case R_68K_PC32:
67*1da177e4SLinus Torvalds 			/* Add the value, subtract its postition */
68*1da177e4SLinus Torvalds 			*location += sym->st_value - (uint32_t)location;
69*1da177e4SLinus Torvalds 			break;
70*1da177e4SLinus Torvalds 		default:
71*1da177e4SLinus Torvalds 			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
72*1da177e4SLinus Torvalds 			       me->name, ELF32_R_TYPE(rel[i].r_info));
73*1da177e4SLinus Torvalds 			return -ENOEXEC;
74*1da177e4SLinus Torvalds 		}
75*1da177e4SLinus Torvalds 	}
76*1da177e4SLinus Torvalds 	return 0;
77*1da177e4SLinus Torvalds }
78*1da177e4SLinus Torvalds 
79*1da177e4SLinus Torvalds int apply_relocate_add(Elf32_Shdr *sechdrs,
80*1da177e4SLinus Torvalds 		       const char *strtab,
81*1da177e4SLinus Torvalds 		       unsigned int symindex,
82*1da177e4SLinus Torvalds 		       unsigned int relsec,
83*1da177e4SLinus Torvalds 		       struct module *me)
84*1da177e4SLinus Torvalds {
85*1da177e4SLinus Torvalds 	unsigned int i;
86*1da177e4SLinus Torvalds 	Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
87*1da177e4SLinus Torvalds 	Elf32_Sym *sym;
88*1da177e4SLinus Torvalds 	uint32_t *location;
89*1da177e4SLinus Torvalds 
90*1da177e4SLinus Torvalds 	DEBUGP("Applying relocate_add section %u to %u\n", relsec,
91*1da177e4SLinus Torvalds 	       sechdrs[relsec].sh_info);
92*1da177e4SLinus Torvalds 	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
93*1da177e4SLinus Torvalds 		/* This is where to make the change */
94*1da177e4SLinus Torvalds 		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
95*1da177e4SLinus Torvalds 			+ rel[i].r_offset;
96*1da177e4SLinus Torvalds 		/* This is the symbol it is referring to.  Note that all
97*1da177e4SLinus Torvalds 		   undefined symbols have been resolved.  */
98*1da177e4SLinus Torvalds 		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
99*1da177e4SLinus Torvalds 			+ ELF32_R_SYM(rel[i].r_info);
100*1da177e4SLinus Torvalds 
101*1da177e4SLinus Torvalds 		switch (ELF32_R_TYPE(rel[i].r_info)) {
102*1da177e4SLinus Torvalds 		case R_68K_32:
103*1da177e4SLinus Torvalds 			/* We add the value into the location given */
104*1da177e4SLinus Torvalds 			*location = rel[i].r_addend + sym->st_value;
105*1da177e4SLinus Torvalds 			break;
106*1da177e4SLinus Torvalds 		case R_68K_PC32:
107*1da177e4SLinus Torvalds 			/* Add the value, subtract its postition */
108*1da177e4SLinus Torvalds 			*location = rel[i].r_addend + sym->st_value - (uint32_t)location;
109*1da177e4SLinus Torvalds 			break;
110*1da177e4SLinus Torvalds 		default:
111*1da177e4SLinus Torvalds 			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
112*1da177e4SLinus Torvalds 			       me->name, ELF32_R_TYPE(rel[i].r_info));
113*1da177e4SLinus Torvalds 			return -ENOEXEC;
114*1da177e4SLinus Torvalds 		}
115*1da177e4SLinus Torvalds 	}
116*1da177e4SLinus Torvalds 	return 0;
117*1da177e4SLinus Torvalds }
118*1da177e4SLinus Torvalds 
119*1da177e4SLinus Torvalds int module_finalize(const Elf_Ehdr *hdr,
120*1da177e4SLinus Torvalds 		    const Elf_Shdr *sechdrs,
121*1da177e4SLinus Torvalds 		    struct module *me)
122*1da177e4SLinus Torvalds {
123*1da177e4SLinus Torvalds 	return 0;
124*1da177e4SLinus Torvalds }
125*1da177e4SLinus Torvalds 
126*1da177e4SLinus Torvalds void module_arch_cleanup(struct module *mod)
127*1da177e4SLinus Torvalds {
128*1da177e4SLinus Torvalds }
129