summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2002-08-20 00:24:33 +0000
committermarcel <marcel@FreeBSD.org>2002-08-20 00:24:33 +0000
commit1e66a9327a1510eaa511a19a0865a273f2a4d9ec (patch)
tree3a28efd10af7305f61e2290cc4c3ca60ff25ef56 /libexec/rtld-elf/ia64
parenta9dd424f2f6857d017d1eee26b2335f629e897d3 (diff)
downloadFreeBSD-src-1e66a9327a1510eaa511a19a0865a273f2a4d9ec.zip
FreeBSD-src-1e66a9327a1510eaa511a19a0865a273f2a4d9ec.tar.gz
Add support for the R_IA64_IPLTLSB relocation in non-PLT context.
This relocation creates a function descriptor at the specified address and is commonly used for C++ to create virtual function tables.
Diffstat (limited to 'libexec/rtld-elf/ia64')
-rw-r--r--libexec/rtld-elf/ia64/reloc.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/libexec/rtld-elf/ia64/reloc.c b/libexec/rtld-elf/ia64/reloc.c
index 5a054c8..ea58f07 100644
--- a/libexec/rtld-elf/ia64/reloc.c
+++ b/libexec/rtld-elf/ia64/reloc.c
@@ -170,6 +170,36 @@ reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
break;
}
+ case R_IA64_IPLTLSB: {
+ /*
+ * Relocation typically used to populate C++ virtual function
+ * tables. It creates a 128-bit function descriptor at the
+ * specified memory address.
+ */
+ const Elf_Sym *def;
+ const Obj_Entry *defobj;
+ struct fptr *fptr;
+ Elf_Addr target, gp;
+
+ def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
+ false, cache);
+ if (def == NULL)
+ return -1;
+
+ if (def->st_shndx != SHN_UNDEF) {
+ target = (Elf_Addr)(defobj->relocbase + def->st_value);
+ gp = (Elf_Addr)defobj->pltgot;
+ } else {
+ target = 0;
+ gp = 0;
+ }
+
+ fptr = (void*)where;
+ store64(&fptr->target, target);
+ store64(&fptr->gp, gp);
+ break;
+ }
+
default:
_rtld_error("%s: Unsupported relocation type %d"
" in non-PLT relocations\n", obj->path,
OpenPOWER on IntegriCloud