1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
9 #include <asm/orc_types.h>
10 #include <asm-generic/module.h>
12 #define RELA_STACK_DEPTH 16
20 struct mod_arch_specific
{
21 struct mod_section got
;
22 struct mod_section plt
;
23 struct mod_section plt_idx
;
25 #ifdef CONFIG_UNWINDER_ORC
26 unsigned int num_orcs
;
28 struct orc_entry
*orc_unwind
;
31 /* For CONFIG_DYNAMIC_FTRACE */
32 struct plt_entry
*ftrace_trampolines
;
46 struct plt_idx_entry
{
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
);
53 static inline struct got_entry
emit_got_entry(Elf_Addr val
)
55 return (struct got_entry
) { val
};
58 static inline struct plt_entry
emit_plt_entry(unsigned long val
)
60 u32 lu12iw
, lu32id
, lu52id
, jirl
;
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
));
67 return (struct plt_entry
) { lu12iw
, lu32id
, lu52id
, jirl
};
70 static inline struct plt_idx_entry
emit_plt_idx_entry(unsigned long val
)
72 return (struct plt_idx_entry
) { val
};
75 static inline int get_plt_idx(unsigned long val
, Elf_Shdr
*sechdrs
, const struct mod_section
*sec
)
78 struct plt_idx_entry
*plt_idx
= (struct plt_idx_entry
*)sechdrs
[sec
->shndx
].sh_addr
;
80 for (i
= 0; i
< sec
->num_entries
; i
++) {
81 if (plt_idx
[i
].symbol_addr
== val
)
88 static inline struct plt_entry
*get_plt_entry(unsigned long val
,
90 const struct mod_section
*sec_plt
,
91 const struct mod_section
*sec_plt_idx
)
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
;
102 static inline struct got_entry
*get_got_entry(Elf_Addr val
,
104 const struct mod_section
*sec
)
107 struct got_entry
*got
= (struct got_entry
*)sechdrs
[sec
->shndx
].sh_addr
;
109 for (i
= 0; i
< sec
->num_entries
; i
++)
110 if (got
[i
].symbol_addr
== val
)
115 #endif /* _ASM_MODULE_H */