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
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) #include <linux/moduleloader.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) int apply_relocate_add(Elf32_Shdr *sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) 		       const char *strtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) 		       unsigned int symindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) 		       unsigned int relsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 		       struct module *me)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) 	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 	pr_debug("Applying relocate section %u to %u\n", relsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 	       sechdrs[relsec].sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) 	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) 		/* This is where to make the change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) 		uint32_t *loc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 			(uint32_t *)(sechdrs[sechdrs[relsec].sh_info].sh_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 					     + rela[i].r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 		/* This is the symbol it is referring to.  Note that all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 		   undefined symbols have been resolved.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 		Elf32_Sym *sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 			+ ELF32_R_SYM(rela[i].r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 		uint32_t v = sym->st_value + rela[i].r_addend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 		switch (ELF32_R_TYPE(rela[i].r_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 		case R_H8_DIR24R8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 			loc = (uint32_t *)((uint32_t)loc - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 			*loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 		case R_H8_DIR24A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 			if (ELF32_R_SYM(rela[i].r_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 				*loc += v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 		case R_H8_DIR32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 		case R_H8_DIR32A16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 			*loc += v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 		case R_H8_PCREL16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 			v -= (unsigned long)loc + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 			if ((Elf32_Sword)v > 0x7fff ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 			    (Elf32_Sword)v < -(Elf32_Sword)0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 				goto overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 				*(unsigned short *)loc = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 		case R_H8_PCREL8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 			v -= (unsigned long)loc + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 			if ((Elf32_Sword)v > 0x7f ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 			    (Elf32_Sword)v < -(Elf32_Sword)0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 				goto overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 				*(unsigned char *)loc = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 			pr_err("module %s: Unknown relocation: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 			       me->name, ELF32_R_TYPE(rela[i].r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 			return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)  overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 	pr_err("module %s: relocation offset overflow: %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 	       me->name, rela[i].r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 	return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }