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

TOMOYO Linux Cross Reference
Linux/arch/loongarch/include/asm/module.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4  */
  5 #ifndef _ASM_MODULE_H
  6 #define _ASM_MODULE_H
  7 
  8 #include <asm/inst.h>
  9 #include <asm/orc_types.h>
 10 #include <asm-generic/module.h>
 11 
 12 #define RELA_STACK_DEPTH 16
 13 
 14 struct mod_section {
 15         int shndx;
 16         int num_entries;
 17         int max_entries;
 18 };
 19 
 20 struct mod_arch_specific {
 21         struct mod_section got;
 22         struct mod_section plt;
 23         struct mod_section plt_idx;
 24 
 25 #ifdef CONFIG_UNWINDER_ORC
 26         unsigned int num_orcs;
 27         int *orc_unwind_ip;
 28         struct orc_entry *orc_unwind;
 29 #endif
 30 
 31         /* For CONFIG_DYNAMIC_FTRACE */
 32         struct plt_entry *ftrace_trampolines;
 33 };
 34 
 35 struct got_entry {
 36         Elf_Addr symbol_addr;
 37 };
 38 
 39 struct plt_entry {
 40         u32 inst_lu12iw;
 41         u32 inst_lu32id;
 42         u32 inst_lu52id;
 43         u32 inst_jirl;
 44 };
 45 
 46 struct plt_idx_entry {
 47         Elf_Addr symbol_addr;
 48 };
 49 
 50 Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val);
 51 Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val);
 52 
 53 static inline struct got_entry emit_got_entry(Elf_Addr val)
 54 {
 55         return (struct got_entry) { val };
 56 }
 57 
 58 static inline struct plt_entry emit_plt_entry(unsigned long val)
 59 {
 60         u32 lu12iw, lu32id, lu52id, jirl;
 61 
 62         lu12iw = larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW));
 63         lu32id = larch_insn_gen_lu32id(LOONGARCH_GPR_T1, ADDR_IMM(val, LU32ID));
 64         lu52id = larch_insn_gen_lu52id(LOONGARCH_GPR_T1, LOONGARCH_GPR_T1, ADDR_IMM(val, LU52ID));
 65         jirl = larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, ADDR_IMM(val, ORI));
 66 
 67         return (struct plt_entry) { lu12iw, lu32id, lu52id, jirl };
 68 }
 69 
 70 static inline struct plt_idx_entry emit_plt_idx_entry(unsigned long val)
 71 {
 72         return (struct plt_idx_entry) { val };
 73 }
 74 
 75 static inline int get_plt_idx(unsigned long val, Elf_Shdr *sechdrs, const struct mod_section *sec)
 76 {
 77         int i;
 78         struct plt_idx_entry *plt_idx = (struct plt_idx_entry *)sechdrs[sec->shndx].sh_addr;
 79 
 80         for (i = 0; i < sec->num_entries; i++) {
 81                 if (plt_idx[i].symbol_addr == val)
 82                         return i;
 83         }
 84 
 85         return -1;
 86 }
 87 
 88 static inline struct plt_entry *get_plt_entry(unsigned long val,
 89                                               Elf_Shdr *sechdrs,
 90                                               const struct mod_section *sec_plt,
 91                                               const struct mod_section *sec_plt_idx)
 92 {
 93         int plt_idx = get_plt_idx(val, sechdrs, sec_plt_idx);
 94         struct plt_entry *plt = (struct plt_entry *)sechdrs[sec_plt->shndx].sh_addr;
 95 
 96         if (plt_idx < 0)
 97                 return NULL;
 98 
 99         return plt + plt_idx;
100 }
101 
102 static inline struct got_entry *get_got_entry(Elf_Addr val,
103                                               Elf_Shdr *sechdrs,
104                                               const struct mod_section *sec)
105 {
106         int i;
107         struct got_entry *got = (struct got_entry *)sechdrs[sec->shndx].sh_addr;
108 
109         for (i = 0; i < sec->num_entries; i++)
110                 if (got[i].symbol_addr == val)
111                         return &got[i];
112         return NULL;
113 }
114 
115 #endif /* _ASM_MODULE_H */
116 

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php