module-sections.c 4.3 KB

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