^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) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2014-2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2018 Andes Technology Corporation <zong@andestech.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/moduleloader.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) unsigned long module_emit_got_entry(struct module *mod, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct mod_section *got_sec = &mod->arch.got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int i = got_sec->num_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct got_entry *got = get_got_entry(val, got_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) if (got)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) return (unsigned long)got;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* There is no duplicate entry, create a new one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) got = (struct got_entry *)got_sec->shdr->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) got[i] = emit_got_entry(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) got_sec->num_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) BUG_ON(got_sec->num_entries > got_sec->max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return (unsigned long)&got[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned long module_emit_plt_entry(struct module *mod, unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct mod_section *got_plt_sec = &mod->arch.got_plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct got_entry *got_plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct mod_section *plt_sec = &mod->arch.plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct plt_entry *plt = get_plt_entry(val, plt_sec, got_plt_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int i = plt_sec->num_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (plt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return (unsigned long)plt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* There is no duplicate entry, create a new one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) got_plt = (struct got_entry *)got_plt_sec->shdr->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) got_plt[i] = emit_got_entry(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) plt = (struct plt_entry *)plt_sec->shdr->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) plt[i] = emit_plt_entry(val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) (unsigned long)&plt[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) (unsigned long)&got_plt[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) plt_sec->num_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) got_plt_sec->num_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) BUG_ON(plt_sec->num_entries > plt_sec->max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return (unsigned long)&plt[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int is_rela_equal(const Elf_Rela *x, const Elf_Rela *y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return x->r_info == y->r_info && x->r_addend == y->r_addend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static bool duplicate_rela(const Elf_Rela *rela, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) for (i = 0; i < idx; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (is_rela_equal(&rela[i], &rela[idx]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static void count_max_entries(Elf_Rela *relas, int num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) unsigned int *plts, unsigned int *gots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned int type, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) type = ELF_RISCV_R_TYPE(relas[i].r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (type == R_RISCV_CALL_PLT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (!duplicate_rela(relas, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) (*plts)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) } else if (type == R_RISCV_GOT_HI20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!duplicate_rela(relas, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) (*gots)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) char *secstrings, struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned int num_plts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned int num_gots = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Find the empty .got and .plt sections.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) for (i = 0; i < ehdr->e_shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mod->arch.plt.shdr = sechdrs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) else if (!strcmp(secstrings + sechdrs[i].sh_name, ".got"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) mod->arch.got.shdr = sechdrs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) else if (!strcmp(secstrings + sechdrs[i].sh_name, ".got.plt"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mod->arch.got_plt.shdr = sechdrs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!mod->arch.plt.shdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) pr_err("%s: module PLT section(s) missing\n", mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!mod->arch.got.shdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) pr_err("%s: module GOT section(s) missing\n", mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (!mod->arch.got_plt.shdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) pr_err("%s: module GOT.PLT section(s) missing\n", mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* Calculate the maxinum number of entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) for (i = 0; i < ehdr->e_shnum; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) Elf_Rela *relas = (void *)ehdr + sechdrs[i].sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int num_rela = sechdrs[i].sh_size / sizeof(Elf_Rela);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) Elf_Shdr *dst_sec = sechdrs + sechdrs[i].sh_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (sechdrs[i].sh_type != SHT_RELA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* ignore relocations that operate on non-exec sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!(dst_sec->sh_flags & SHF_EXECINSTR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) count_max_entries(relas, num_rela, &num_plts, &num_gots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) mod->arch.plt.shdr->sh_type = SHT_NOBITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) mod->arch.plt.shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) mod->arch.plt.shdr->sh_addralign = L1_CACHE_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mod->arch.plt.shdr->sh_size = (num_plts + 1) * sizeof(struct plt_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mod->arch.plt.num_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mod->arch.plt.max_entries = num_plts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) mod->arch.got.shdr->sh_type = SHT_NOBITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mod->arch.got.shdr->sh_flags = SHF_ALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) mod->arch.got.shdr->sh_addralign = L1_CACHE_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mod->arch.got.shdr->sh_size = (num_gots + 1) * sizeof(struct got_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) mod->arch.got.num_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) mod->arch.got.max_entries = num_gots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mod->arch.got_plt.shdr->sh_type = SHT_NOBITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) mod->arch.got_plt.shdr->sh_flags = SHF_ALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mod->arch.got_plt.shdr->sh_addralign = L1_CACHE_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mod->arch.got_plt.shdr->sh_size = (num_plts + 1) * sizeof(struct got_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) mod->arch.got_plt.num_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) mod->arch.got_plt.max_entries = num_plts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }