hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/parisc/kernel/module.c
....@@ -1,28 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Kernel dynamically loadable module help for PARISC.
23 *
34 * The best reference for this stuff is probably the Processor-
45 * Specific ELF Supplement for PA-RISC:
5
- * http://ftp.parisc-linux.org/docs/arch/elf-pa-hp.pdf
6
+ * https://parisc.wiki.kernel.org/index.php/File:Elf-pa-hp.pdf
67 *
7
- * Linux/PA-RISC Project (http://www.parisc-linux.org/)
8
+ * Linux/PA-RISC Project
89 * Copyright (C) 2003 Randolph Chung <tausq at debian . org>
910 * Copyright (C) 2008 Helge Deller <deller@gmx.de>
10
- *
11
- *
12
- * This program is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation; either version 2 of the License, or
15
- * (at your option) any later version.
16
- *
17
- * This program is distributed in the hope that it will be useful,
18
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- * GNU General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU General Public License
23
- * along with this program; if not, write to the Free Software
24
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
- *
2611 *
2712 * Notes:
2813 * - PLT stub handling
....@@ -48,9 +33,9 @@
4833 * However, SEGREL32 is used only for PARISC unwind entries, and we want
4934 * those entries to have an absolute address, and not just an offset.
5035 *
51
- * The unwind table mechanism has the ability to specify an offset for
36
+ * The unwind table mechanism has the ability to specify an offset for
5237 * the unwind table; however, because we split off the init functions into
53
- * a different piece of memory, it is not possible to do this using a
38
+ * a different piece of memory, it is not possible to do this using a
5439 * single offset. Instead, we use the above hack for now.
5540 */
5641
....@@ -58,21 +43,15 @@
5843 #include <linux/elf.h>
5944 #include <linux/vmalloc.h>
6045 #include <linux/fs.h>
46
+#include <linux/ftrace.h>
6147 #include <linux/string.h>
6248 #include <linux/kernel.h>
6349 #include <linux/bug.h>
6450 #include <linux/mm.h>
6551 #include <linux/slab.h>
6652
67
-#include <asm/pgtable.h>
6853 #include <asm/unwind.h>
6954 #include <asm/sections.h>
70
-
71
-#if 0
72
-#define DEBUGP printk
73
-#else
74
-#define DEBUGP(fmt...)
75
-#endif
7655
7756 #define RELOC_REACHABLE(val, bits) \
7857 (( ( !((val) & (1<<((bits)-1))) && ((val)>>(bits)) != 0 ) || \
....@@ -315,7 +294,7 @@
315294 * sizeof(struct stub_entry);
316295 }
317296
318
-#define CONST
297
+#define CONST
319298 int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
320299 CONST Elf_Shdr *sechdrs,
321300 CONST char *secstrings,
....@@ -401,7 +380,7 @@
401380
402381 got[i].addr = value;
403382 out:
404
- DEBUGP("GOT ENTRY %d[%x] val %lx\n", i, i*sizeof(struct got_entry),
383
+ pr_debug("GOT ENTRY %d[%lx] val %lx\n", i, i*sizeof(struct got_entry),
405384 value);
406385 return i * sizeof(struct got_entry);
407386 }
....@@ -554,7 +533,7 @@
554533 //unsigned long dp = (unsigned long)$global$;
555534 register unsigned long dp asm ("r27");
556535
557
- DEBUGP("Applying relocate section %u to %u\n", relsec,
536
+ pr_debug("Applying relocate section %u to %u\n", relsec,
558537 targetsec);
559538 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
560539 /* This is where to make the change */
....@@ -578,7 +557,7 @@
578557
579558 #if 0
580559 #define r(t) ELF32_R_TYPE(rel[i].r_info)==t ? #t :
581
- DEBUGP("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n",
560
+ pr_debug("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n",
582561 strtab + sym->st_name,
583562 (uint32_t)loc, val, addend,
584563 r(R_PARISC_PLABEL32)
....@@ -619,7 +598,7 @@
619598 /* See note about special handling of SEGREL32 at
620599 * the beginning of this file.
621600 */
622
- *loc = fsel(val, addend);
601
+ *loc = fsel(val, addend);
623602 break;
624603 case R_PARISC_SECREL32:
625604 /* 32-bit section relative address. */
....@@ -698,7 +677,7 @@
698677 Elf_Addr loc0;
699678 unsigned int targetsec = sechdrs[relsec].sh_info;
700679
701
- DEBUGP("Applying relocate section %u to %u\n", relsec,
680
+ pr_debug("Applying relocate section %u to %u\n", relsec,
702681 targetsec);
703682 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
704683 /* This is where to make the change */
....@@ -740,7 +719,7 @@
740719 case R_PARISC_LTOFF21L:
741720 /* LT-relative; left 21 bits */
742721 val = get_got(me, val, addend);
743
- DEBUGP("LTOFF21L Symbol %s loc %p val %lx\n",
722
+ pr_debug("LTOFF21L Symbol %s loc %p val %llx\n",
744723 strtab + sym->st_name,
745724 loc, val);
746725 val = lrsel(val, 0);
....@@ -751,14 +730,14 @@
751730 /* LT-relative; right 14 bits */
752731 val = get_got(me, val, addend);
753732 val = rrsel(val, 0);
754
- DEBUGP("LTOFF14R Symbol %s loc %p val %lx\n",
733
+ pr_debug("LTOFF14R Symbol %s loc %p val %llx\n",
755734 strtab + sym->st_name,
756735 loc, val);
757736 *loc = mask(*loc, 14) | reassemble_14(val);
758737 break;
759738 case R_PARISC_PCREL22F:
760739 /* PC-relative; 22 bits */
761
- DEBUGP("PCREL22F Symbol %s loc %p val %lx\n",
740
+ pr_debug("PCREL22F Symbol %s loc %p val %llx\n",
762741 strtab + sym->st_name,
763742 loc, val);
764743 val += addend;
....@@ -790,7 +769,7 @@
790769 val = get_stub(me, val, addend, ELF_STUB_GOT,
791770 loc0, targetsec);
792771 }
793
- DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n",
772
+ pr_debug("STUB FOR %s loc %px, val %llx+%llx at %llx\n",
794773 strtab + sym->st_name, loc, sym->st_value,
795774 addend, val);
796775 val = (val - dot - 8)/4;
....@@ -801,6 +780,10 @@
801780 /* 32-bit PC relative address */
802781 *loc = val - dot - 8 + addend;
803782 break;
783
+ case R_PARISC_PCREL64:
784
+ /* 64-bit PC relative address */
785
+ *loc64 = val - dot - 8 + addend;
786
+ break;
804787 case R_PARISC_DIR64:
805788 /* 64-bit effective address */
806789 *loc64 = val + addend;
....@@ -810,7 +793,7 @@
810793 /* See note about special handling of SEGREL32 at
811794 * the beginning of this file.
812795 */
813
- *loc = fsel(val, addend);
796
+ *loc = fsel(val, addend);
814797 break;
815798 case R_PARISC_SECREL32:
816799 /* 32-bit section relative address. */
....@@ -820,14 +803,14 @@
820803 /* 64-bit function address */
821804 if(in_local(me, (void *)(val + addend))) {
822805 *loc64 = get_fdesc(me, val+addend);
823
- DEBUGP("FDESC for %s at %p points to %lx\n",
806
+ pr_debug("FDESC for %s at %llx points to %llx\n",
824807 strtab + sym->st_name, *loc64,
825808 ((Elf_Fdesc *)*loc64)->addr);
826809 } else {
827810 /* if the symbol is not local to this
828811 * module then val+addend is a pointer
829812 * to the function descriptor */
830
- DEBUGP("Non local FPTR64 Symbol %s loc %p val %lx\n",
813
+ pr_debug("Non local FPTR64 Symbol %s loc %p val %llx\n",
831814 strtab + sym->st_name,
832815 loc, val);
833816 *loc64 = val + addend;
....@@ -858,7 +841,7 @@
858841 end = table + sechdrs[me->arch.unwind_section].sh_size;
859842 gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
860843
861
- DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
844
+ pr_debug("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
862845 me->arch.unwind_section, table, end, gp);
863846 me->arch.unwind = unwind_table_add(me->name, 0, gp, table, end);
864847 }
....@@ -877,6 +860,9 @@
877860 int i;
878861 unsigned long nsyms;
879862 const char *strtab = NULL;
863
+ const Elf_Shdr *s;
864
+ char *secstrings;
865
+ int symindex = -1;
880866 Elf_Sym *newptr, *oldptr;
881867 Elf_Shdr *symhdr = NULL;
882868 #ifdef DEBUG
....@@ -903,6 +889,7 @@
903889 if(sechdrs[i].sh_type == SHT_SYMTAB
904890 && (sechdrs[i].sh_flags & SHF_ALLOC)) {
905891 int strindex = sechdrs[i].sh_link;
892
+ symindex = i;
906893 /* FIXME: AWFUL HACK
907894 * The cast is to drop the const from
908895 * the sechdrs pointer */
....@@ -912,7 +899,7 @@
912899 }
913900 }
914901
915
- DEBUGP("module %s: strtab %p, symhdr %p\n",
902
+ pr_debug("module %s: strtab %p, symhdr %p\n",
916903 me->name, strtab, symhdr);
917904
918905 if(me->arch.got_count > MAX_GOTS) {
....@@ -931,7 +918,7 @@
931918 oldptr = (void *)symhdr->sh_addr;
932919 newptr = oldptr + 1; /* we start counting at 1 */
933920 nsyms = symhdr->sh_size / sizeof(Elf_Sym);
934
- DEBUGP("OLD num_symtab %lu\n", nsyms);
921
+ pr_debug("OLD num_symtab %lu\n", nsyms);
935922
936923 for (i = 1; i < nsyms; i++) {
937924 oldptr++; /* note, count starts at 1 so preincrement */
....@@ -946,8 +933,39 @@
946933
947934 }
948935 nsyms = newptr - (Elf_Sym *)symhdr->sh_addr;
949
- DEBUGP("NEW num_symtab %lu\n", nsyms);
936
+ pr_debug("NEW num_symtab %lu\n", nsyms);
950937 symhdr->sh_size = nsyms * sizeof(Elf_Sym);
938
+
939
+ /* find .altinstructions section */
940
+ secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
941
+ for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
942
+ void *aseg = (void *) s->sh_addr;
943
+ char *secname = secstrings + s->sh_name;
944
+
945
+ if (!strcmp(".altinstructions", secname))
946
+ /* patch .altinstructions */
947
+ apply_alternatives(aseg, aseg + s->sh_size, me->name);
948
+
949
+#ifdef CONFIG_DYNAMIC_FTRACE
950
+ /* For 32 bit kernels we're compiling modules with
951
+ * -ffunction-sections so we must relocate the addresses in the
952
+ * ftrace callsite section.
953
+ */
954
+ if (symindex != -1 && !strcmp(secname, FTRACE_CALLSITE_SECTION)) {
955
+ int err;
956
+ if (s->sh_type == SHT_REL)
957
+ err = apply_relocate((Elf_Shdr *)sechdrs,
958
+ strtab, symindex,
959
+ s - sechdrs, me);
960
+ else if (s->sh_type == SHT_RELA)
961
+ err = apply_relocate_add((Elf_Shdr *)sechdrs,
962
+ strtab, symindex,
963
+ s - sechdrs, me);
964
+ if (err)
965
+ return err;
966
+ }
967
+#endif
968
+ }
951969 return 0;
952970 }
953971