lkml.org 
[lkml]   [2022]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH 3/5] LoongArch: Support relocation against _GLOBAL_OFFSET_TABLE_
From
Date
With the stack-based relocations, the assembler emits three relocations
to push the PC-relative offset of a GOT entry:

R_LARCH_SOP_PUSH_PCREL _GLOBAL_OFFSET_TABLE_
R_LARCH_SOP_PUSH_GPREL foo
R_LARCH_SOP_ADD

"_GLOBAL_OFFSET_TABLE_" does not really exist in the symtab and the BFD
linker handles it with special hack. Implement a similar hack for
kernel so we will be able to really use R_LARCH_SOP_PUSH_GPREL
relocation.

Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
arch/loongarch/kernel/module-sections.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kernel/module-sections.c
index 509c0b86b1e9..73976addbf60 100644
--- a/arch/loongarch/kernel/module-sections.c
+++ b/arch/loongarch/kernel/module-sections.c
@@ -89,6 +89,9 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
char *secstrings, struct module *mod)
{
unsigned int i, num_plts = 0, num_gots = 0;
+ Elf_Shdr *symtab = NULL;
+ Elf_Sym *symbols;
+ char *strings;

/*
* Find the empty .plt sections.
@@ -100,6 +103,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
mod->arch.plt_idx.shdr = sechdrs + i;
else if (!strcmp(secstrings + sechdrs[i].sh_name, ".got"))
mod->arch.got.shdr = sechdrs + i;
+ else if (sechdrs[i].sh_type == SHT_SYMTAB)
+ symtab = sechdrs + i;
}

if (!mod->arch.plt.shdr) {
@@ -115,6 +120,22 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
return -ENOEXEC;
}

+ if (!symtab) {
+ pr_err("%s: module symbol table missing\n", mod->name);
+ return -ENOEXEC;
+ }
+
+ symbols = (void *) ehdr + symtab->sh_offset;
+ strings = (void *) ehdr + sechdrs[symtab->sh_link].sh_offset;
+
+ for (i = 0; i < symtab->sh_size / sizeof(Elf_Sym); i++)
+ if (symbols[i].st_shndx == SHN_UNDEF &&
+ strcmp(strings + symbols[i].st_name,
+ "_GLOBAL_OFFSET_TABLE_") == 0) {
+ symbols[i].st_shndx = mod->arch.got.shdr - sechdrs;
+ symbols[i].st_value = 0;
+ }
+
/* Calculate the maxinum number of entries */
for (i = 0; i < ehdr->e_shnum; i++) {
int num_rela = sechdrs[i].sh_size / sizeof(Elf_Rela);
--
2.37.0

\
 
 \ /
  Last update: 2022-07-27 18:40    [W:0.137 / U:0.448 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site