module-sections.c 4.5 KB

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