module.h (1869B)
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-generic/module.h> 10 11#define RELA_STACK_DEPTH 16 12 13struct mod_section { 14 Elf_Shdr *shdr; 15 int num_entries; 16 int max_entries; 17}; 18 19struct mod_arch_specific { 20 struct mod_section plt; 21 struct mod_section plt_idx; 22}; 23 24struct plt_entry { 25 u32 inst_lu12iw; 26 u32 inst_lu32id; 27 u32 inst_lu52id; 28 u32 inst_jirl; 29}; 30 31struct plt_idx_entry { 32 unsigned long symbol_addr; 33}; 34 35Elf_Addr module_emit_plt_entry(struct module *mod, unsigned long val); 36 37static inline struct plt_entry emit_plt_entry(unsigned long val) 38{ 39 u32 lu12iw, lu32id, lu52id, jirl; 40 41 lu12iw = (lu12iw_op << 25 | (((val >> 12) & 0xfffff) << 5) | LOONGARCH_GPR_T1); 42 lu32id = larch_insn_gen_lu32id(LOONGARCH_GPR_T1, ADDR_IMM(val, LU32ID)); 43 lu52id = larch_insn_gen_lu52id(LOONGARCH_GPR_T1, LOONGARCH_GPR_T1, ADDR_IMM(val, LU52ID)); 44 jirl = larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, 0, (val & 0xfff)); 45 46 return (struct plt_entry) { lu12iw, lu32id, lu52id, jirl }; 47} 48 49static inline struct plt_idx_entry emit_plt_idx_entry(unsigned long val) 50{ 51 return (struct plt_idx_entry) { val }; 52} 53 54static inline int get_plt_idx(unsigned long val, const struct mod_section *sec) 55{ 56 int i; 57 struct plt_idx_entry *plt_idx = (struct plt_idx_entry *)sec->shdr->sh_addr; 58 59 for (i = 0; i < sec->num_entries; i++) { 60 if (plt_idx[i].symbol_addr == val) 61 return i; 62 } 63 64 return -1; 65} 66 67static inline struct plt_entry *get_plt_entry(unsigned long val, 68 const struct mod_section *sec_plt, 69 const struct mod_section *sec_plt_idx) 70{ 71 int plt_idx = get_plt_idx(val, sec_plt_idx); 72 struct plt_entry *plt = (struct plt_entry *)sec_plt->shdr->sh_addr; 73 74 if (plt_idx < 0) 75 return NULL; 76 77 return plt + plt_idx; 78} 79 80#endif /* _ASM_MODULE_H */