Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2007-2009 PetaLogix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/moduleloader.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	unsigned int symindex, unsigned int relsec, struct module *module)
^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) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	Elf32_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	unsigned long int *location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	unsigned long int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #if __GNUC__ < 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	unsigned long int old_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	pr_debug("Applying add relocation section %u to %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		relsec, sechdrs[relsec].sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 				rela[i].r_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			ELF32_R_SYM(rela[i].r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		value = sym->st_value + rela[i].r_addend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		switch (ELF32_R_TYPE(rela[i].r_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		 * Be careful! mb-gcc / mb-ld splits the relocs between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		 * text and the reloc table. In general this means we must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		 * read the current contents of (*location), add any offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		 * then store the result back in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		case R_MICROBLAZE_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #if __GNUC__ < 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			old_value = *location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			*location = value + old_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			pr_debug("R_MICROBLAZE_32 (%08lx->%08lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 				old_value, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			*location = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		case R_MICROBLAZE_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #if __GNUC__ < 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			/* Split relocs only required/used pre gcc4.1.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			old_value = ((location[0] & 0x0000FFFF) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 					(location[1] & 0x0000FFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			value += old_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			location[0] = (location[0] & 0xFFFF0000) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 					(value >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			location[1] = (location[1] & 0xFFFF0000) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 					(value & 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #if __GNUC__ < 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			pr_debug("R_MICROBLAZE_64 (%08lx->%08lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 				old_value, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		case R_MICROBLAZE_64_PCREL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #if __GNUC__ < 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			old_value = (location[0] & 0xFFFF) << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				(location[1] & 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			value -= old_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			value -= (unsigned long int)(location) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			location[0] = (location[0] & 0xFFFF0000) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 					(value >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			location[1] = (location[1] & 0xFFFF0000) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 					(value & 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			pr_debug("R_MICROBLAZE_64_PCREL (%08lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 				value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		case R_MICROBLAZE_32_PCREL_LO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			pr_debug("R_MICROBLAZE_32_PCREL_LO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		case R_MICROBLAZE_64_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			pr_debug("R_MICROBLAZE_64_NONE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		case R_MICROBLAZE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			pr_debug("R_MICROBLAZE_NONE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			pr_err("module %s: Unknown relocation: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 				module->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 				ELF32_R_TYPE(rela[i].r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		struct module *module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	flush_dcache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }