aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/riscv
diff options
context:
space:
mode:
authorVincent Chen <vincent.chen@sifive.com>2020-12-15 17:16:40 +0800
committerDJ Delorie <dj@redhat.com>2021-01-10 21:25:16 -0500
commit313bfd505e7c6a70c508ba9b2e2c0ff6e901c2a0 (patch)
tree6d1e34ef9b63bd754ab44ebfcd40121d74dc3a4e /sysdeps/riscv
parentc31b1f52311e10a37b85604b43de81dff205637e (diff)
downloadglibc-313bfd505e7c6a70c508ba9b2e2c0ff6e901c2a0.zip
glibc-313bfd505e7c6a70c508ba9b2e2c0ff6e901c2a0.tar.gz
glibc-313bfd505e7c6a70c508ba9b2e2c0ff6e901c2a0.tar.bz2
riscv: Initialize $gp before resolving the IRELATIVE relocation
The $gp register may be used to access the global variable in the PDE program, so the $gp register should be initialized before executing the IFUNC resolver of PDE program to avoid unexpected error occurs.
Diffstat (limited to 'sysdeps/riscv')
-rw-r--r--sysdeps/riscv/dl-machine.h22
1 files changed, 21 insertions, 1 deletions
diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
index 59140c4..aedf69f 100644
--- a/sysdeps/riscv/dl-machine.h
+++ b/sysdeps/riscv/dl-machine.h
@@ -339,8 +339,28 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
gotplt[0] = (ElfW(Addr)) &_dl_runtime_resolve;
gotplt[1] = (ElfW(Addr)) l;
}
-#endif
+ if (l->l_type == lt_executable)
+ {
+ /* The __global_pointer$ may not be defined by the linker if the
+ $gp register does not be used to access the global variable
+ in the executable program. Therefore, the search symbol is
+ set to a weak symbol to avoid we error out if the
+ __global_pointer$ is not found. */
+ ElfW(Sym) gp_sym = { 0 };
+ gp_sym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE));
+
+ const ElfW(Sym) *ref = &gp_sym;
+ _dl_lookup_symbol_x ("__global_pointer$", l, &ref,
+ l->l_scope, NULL, 0, 0, NULL);
+ if (ref)
+ asm (
+ "mv gp, %0\n"
+ :
+ : "r" (ref->st_value)
+ );
+ }
+#endif
return lazy;
}