svn commit: r233674 - head/libexec/rtld-elf

Konstantin Belousov kostikbel at gmail.com
Thu Mar 29 18:11:40 UTC 2012


On Thu, Mar 29, 2012 at 05:50:01PM +0000, Konstantin Belousov wrote:
> Author: kib
> Date: Thu Mar 29 17:50:01 2012
> New Revision: 233674
> URL: http://svn.freebsd.org/changeset/base/233674
> 
> Log:
>   Fix ia64 build after r233655.
>   
>   MFC after:	1 week
> 
> Modified:
>   head/libexec/rtld-elf/rtld.c
> 
> Modified: head/libexec/rtld-elf/rtld.c
> ==============================================================================
> --- head/libexec/rtld-elf/rtld.c	Thu Mar 29 17:39:18 2012	(r233673)
> +++ head/libexec/rtld-elf/rtld.c	Thu Mar 29 17:50:01 2012	(r233674)
> @@ -2618,7 +2618,9 @@ do_dlsym(void *handle, const char *name,
>      const Elf_Sym *def;
>      SymLook req;
>      RtldLockState lockstate;
> +#ifndef __ia64__
>      tls_index ti;
> +#endif
>      int res;
>  
>      def = NULL;
> @@ -2734,9 +2736,13 @@ do_dlsym(void *handle, const char *name,
>  	else if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC)
>  	    return (rtld_resolve_ifunc(defobj, def));
>  	else if (ELF_ST_TYPE(def->st_info) == STT_TLS) {
> +#ifdef __ia64__
> +	    return (__tls_get_addr(defobj->tlsindex, def->st_value));
> +#else
>  	    ti.ti_module = defobj->tlsindex;
>  	    ti.ti_offset = def->st_value;
>  	    return (__tls_get_addr(&ti));
> +#endif
>  	} else
>  	    return (defobj->relocbase + def->st_value);
>      }
While this band-aid fixes the build, the change is obviously bad.
The reason to have this #ifdef is that ia64 is the only architecture
that declares __tls_get_addr() as

void *__tls_get_addr(unsigned long module, unsigned long offset);

while all other architectures do

typedef struct {
    unsigned long ti_module;
    unsigned long ti_offset;
} tls_index;
void *__tls_get_addr(tls_index *ti);

But e.g. on amd64 the ABI of both declarations is the same. From my
cursory look at ia64 ABI document, the same hold for ia64.

Can anybody with ia64 clue and test machine confirm that the following
works, i.e. ABI is not broken ?

diff --git a/libexec/rtld-elf/ia64/reloc.c b/libexec/rtld-elf/ia64/reloc.c
index 01e20b8..31319f3 100644
--- a/libexec/rtld-elf/ia64/reloc.c
+++ b/libexec/rtld-elf/ia64/reloc.c
@@ -650,9 +650,9 @@ allocate_initial_tls(Obj_Entry *list)
     __asm __volatile("mov r13 = %0" :: "r"(tpval));
 }
 
-void *__tls_get_addr(unsigned long module, unsigned long offset)
+void *__tls_get_addr(tls_index *ti)
 {
     register Elf_Addr** tp __asm__("r13");
 
-    return tls_get_addr_common(tp, module, offset);
+    return tls_get_addr_common(tp, ti->ti_module, ti->ti_offset);
 }
diff --git a/libexec/rtld-elf/ia64/rtld_machdep.h b/libexec/rtld-elf/ia64/rtld_machdep.h
index 4a68ff7..df877f2 100644
--- a/libexec/rtld-elf/ia64/rtld_machdep.h
+++ b/libexec/rtld-elf/ia64/rtld_machdep.h
@@ -64,7 +64,12 @@ void call_init_pointer(const struct Struct_Obj_Entry *, Elf_Addr);
 	round(prev_offset + prev_size, align)
 #define calculate_tls_end(off, size) 	((off) + (size))
 
-extern void *__tls_get_addr(unsigned long module, unsigned long offset);
+typedef struct {
+    unsigned long ti_module;
+    unsigned long ti_offset;
+} tls_index;
+
+extern void *__tls_get_addr(tls_index *ti);
 
 #define	RTLD_DEFAULT_STACK_PF_EXEC	0
 #define	RTLD_DEFAULT_STACK_EXEC		0
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index d3ce3c6..828b8b4 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2618,9 +2618,7 @@ do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve,
     const Elf_Sym *def;
     SymLook req;
     RtldLockState lockstate;
-#ifndef __ia64__
     tls_index ti;
-#endif
     int res;
 
     def = NULL;
@@ -2736,13 +2734,9 @@ do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve,
 	else if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC)
 	    return (rtld_resolve_ifunc(defobj, def));
 	else if (ELF_ST_TYPE(def->st_info) == STT_TLS) {
-#ifdef __ia64__
-	    return (__tls_get_addr(defobj->tlsindex, def->st_value));
-#else
 	    ti.ti_module = defobj->tlsindex;
 	    ti.ti_offset = def->st_value;
 	    return (__tls_get_addr(&ti));
-#endif
 	} else
 	    return (defobj->relocbase + def->st_value);
     }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-ia64/attachments/20120329/2166eefe/attachment.pgp


More information about the freebsd-ia64 mailing list