This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] tile: support very large shared objects


Changelog:
2012-11-02  Chris Metcalf  <cmetcalf@tilera.com>

	* config.make.in (config-cflags-mcmodel-large): Define.
	* configure.in: Add libc_cv_cc_mcmodel_large.
	* configure: Regenerate.
	* elf/elf.h (R_TILEGX_IMM16_X[01]_HW[012]_(|LAST_)PLT_PCREL): Add.

ports/Changelog.tile:
2012-11-02  Chris Metcalf  <cmetcalf@tilera.com>

	* sysdeps/tile/Makefile [$(config-cflags-mcmodel-large) = yes]:
	Build elf-init.c with -mcmodel=large.
	* sysdeps/tile/crti.S: Support large memory model.
	* sysdeps/tile/start.S: Likewise.
	* sysdeps/tile/tilegx/tilegx64/configure.in: Test -mcmodel=large.
	* sysdeps/tile/tilegx/tilegx64/configure: Regenerate.

With gcc 4.8 tilegx has support for -mcmodel=large, to tolerate very
large shared objects.  This option changes the compiler output to
not include direct jump instructions, which have a range of only
2^30, i.e +/- 512MB.  Instead the compiler marshalls the target PCs
into registers and then uses jump- or call-to-register instructions.

For glibc, the upshot is that we need to add some additional
relocations (pc-relative PLT) and we need to arrange for a few
functions to tolerate the possibility of a large range between the
PC and the target.  In particular, the crti.S and start.S code needs
to be able to reach from .init to the PLT, and the elf-init code
similarly needs to be built with -mcmodel=large.  Note that libc.so
et al don't need any changes; the only changes are for code that
is statically linked into user code built with -mcmodel=large.

For the assembly code, I just rewrote it so that it unconditionally
uses the large model.  To be able to pass -mcmodel=large to
csu/elf-init.c, I need to check to see if the compiler supports
that flag, since gcc 4.7 doesn't; I added the support pretty
mechanically in the same way as libc_cv_cc_nofma, etc., are supported.
---
 config.make.in                                  |    1 +
 configure                                       |    2 ++
 configure.in                                    |    1 +
 elf/elf.h                                       |   17 +++++++++++++---
 ports/sysdeps/tile/Makefile                     |    8 ++++++++
 ports/sysdeps/tile/crti.S                       |   24 ++++++++++++++++++-----
 ports/sysdeps/tile/start.S                      |   23 +++++++++++++++-------
 ports/sysdeps/tile/tilegx/tilegx64/configure    |   21 ++++++++++++++++++++
 ports/sysdeps/tile/tilegx/tilegx64/configure.in |    7 +++++++
 11 files changed, 103 insertions(+), 15 deletions(-)
 create mode 100644 ports/sysdeps/tile/tilegx/tilegx64/configure
 create mode 100644 ports/sysdeps/tile/tilegx/tilegx64/configure.in

diff --git a/config.make.in b/config.make.in
index c22acf4..3b28f33 100644
--- a/config.make.in
+++ b/config.make.in
@@ -41,6 +41,7 @@ config-cflags-avx = @libc_cv_cc_avx@
 config-cflags-sse2avx = @libc_cv_cc_sse2avx@
 config-cflags-novzeroupper = @libc_cv_cc_novzeroupper@
 config-cflags-nofma = @libc_cv_cc_nofma@
+config-cflags-mcmodel-large = @libc_cv_cc_mcmodel_large@
 config-asflags-i686 = @libc_cv_as_i686@
 
 defines = @DEFINES@
diff --git a/configure b/configure
index 35b06c1..457173a 100755
--- a/configure
+++ b/configure
@@ -583,6 +583,7 @@ ldd_rewrite_script
 use_ldconfig
 libc_cv_sparc_as_vis3
 libc_cv_as_i686
+libc_cv_cc_mcmodel_large
 libc_cv_cc_nofma
 libc_cv_cc_fma4
 libc_cv_cc_novzeroupper
@@ -7510,6 +7511,7 @@ fi
 
 
 
+
 if test x$use_ldconfig = xyes; then
   $as_echo "#define USE_LDCONFIG 1" >>confdefs.h
 
diff --git a/configure.in b/configure.in
index 928b7b6..ca56686 100644
--- a/configure.in
+++ b/configure.in
@@ -2169,6 +2169,7 @@ AC_SUBST(libc_cv_cc_sse2avx)
 AC_SUBST(libc_cv_cc_novzeroupper)
 AC_SUBST(libc_cv_cc_fma4)
 AC_SUBST(libc_cv_cc_nofma)
+AC_SUBST(libc_cv_cc_mcmodel_large)
 AC_SUBST(libc_cv_as_i686)
 AC_SUBST(libc_cv_sparc_as_vis3)
 
diff --git a/elf/elf.h b/elf/elf.h
index 41fc3bd..2524924 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -2986,12 +2986,18 @@ typedef Elf32_Addr Elf32_Conflict;
 #define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
 #define R_TILEGX_IMM16_X0_HW0_GOT 64	/* X0 pipe hword 0 GOT offset */
 #define R_TILEGX_IMM16_X1_HW0_GOT 65	/* X1 pipe hword 0 GOT offset */
-/* Relocs 66-71 are currently not defined.  */
+#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
 #define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
 #define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
 #define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
 #define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
-/* Relocs 76-77 are currently not defined.  */
+#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
 #define R_TILEGX_IMM16_X0_HW0_TLS_GD 78	/* X0 pipe hword 0 TLS GD offset */
 #define R_TILEGX_IMM16_X1_HW0_TLS_GD 79	/* X1 pipe hword 0 TLS GD offset */
 #define R_TILEGX_IMM16_X0_HW0_TLS_LE 80	/* X0 pipe hword 0 TLS LE offset */
@@ -3007,7 +3013,12 @@ typedef Elf32_Addr Elf32_Conflict;
 /* Relocs 90-91 are currently not defined.  */
 #define R_TILEGX_IMM16_X0_HW0_TLS_IE 92	/* X0 pipe hword 0 TLS IE offset */
 #define R_TILEGX_IMM16_X1_HW0_TLS_IE 93	/* X1 pipe hword 0 TLS IE offset */
-/* Relocs 94-99 are currently not defined.  */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
 #define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
 #define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
 #define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
diff --git a/ports/sysdeps/tile/Makefile b/ports/sysdeps/tile/Makefile
index 3cd4d1e..eb04627 100644
--- a/ports/sysdeps/tile/Makefile
+++ b/ports/sysdeps/tile/Makefile
@@ -11,3 +11,11 @@ ifeq ($(subdir),elf)
 # Extra shared linker files to link only into dl-allobjs.so.
 sysdep-rtld-routines += dl-start __tls_get_addr
 endif
+
+ifeq ($(subdir),csu)
+ifeq (yes,$(config-cflags-mcmodel-large))
+# Support largest code model since the init code at the start of the
+# linked shared object has to reach the .plt at the end of the object.
+CFLAGS-elf-init.c += -mcmodel=large
+endif
+endif
diff --git a/ports/sysdeps/tile/crti.S b/ports/sysdeps/tile/crti.S
index ccb4464..de87f4c 100644
--- a/ports/sysdeps/tile/crti.S
+++ b/ports/sysdeps/tile/crti.S
@@ -40,6 +40,7 @@
 
 #include <libc-symbols.h>
 #include <sysdep.h>
+#include <bits/wordsize.h>
 
 #ifndef PREINIT_FUNCTION
 # define PREINIT_FUNCTION __gmon_start__
@@ -70,16 +71,17 @@ _init:
 #if PREINIT_FUNCTION_WEAK
 	lnk r2
 0:
-#ifdef __tilegx__
+# ifdef __tilegx__
+	moveli r1, hw2_last(_GLOBAL_OFFSET_TABLE_ - 0b)
 	{
-	 moveli r1, hw1_last(_GLOBAL_OFFSET_TABLE_ - 0b)
+	 shl16insli r1, r1, hw1(_GLOBAL_OFFSET_TABLE_ - 0b)
 	 moveli r0, hw1_last_got(PREINIT_FUNCTION)
 	}
 	{
 	 shl16insli r1, r1, hw0(_GLOBAL_OFFSET_TABLE_ - 0b)
 	 shl16insli r0, r0, hw0_got(PREINIT_FUNCTION)
 	}
-#else
+# else
 	{
 	 moveli r1, lo16(_GLOBAL_OFFSET_TABLE_ - 0b)
 	 moveli r0, got_lo16(PREINIT_FUNCTION)
@@ -88,13 +90,25 @@ _init:
 	 auli r1, r1, ha16(_GLOBAL_OFFSET_TABLE_ - 0b)
 	 auli r0, r0, got_ha16(PREINIT_FUNCTION)
 	}
-#endif
+# endif
 	ADD_PTR r0, r0, r1
 	ADD_PTR r0, r0, r2
 	LD_PTR r0, r0
 	BEQZ r0, .Lno_weak_fn
-#endif
+	jalr r0
+#elif __WORDSIZE == 64
+	/* Since we are calling from the start of the object to the PLT,
+	   use the -mcmodel=large call model.  */
+	lnk r2
+0:
+	moveli r0, hw2_last_plt(PREINIT_FUNCTION - 0b)
+	shl16insli r0, r0, hw1_plt(PREINIT_FUNCTION - 0b)
+	shl16insli r0, r0, hw0_plt(PREINIT_FUNCTION - 0b)
+	add r0, r0, r2
+	jalr r0
+#else
 	jal plt(PREINIT_FUNCTION)
+#endif
 .Lno_weak_fn:
 
 	.section .fini,"ax",@progbits
diff --git a/ports/sysdeps/tile/start.S b/ports/sysdeps/tile/start.S
index 999bb53..54f015f 100644
--- a/ports/sysdeps/tile/start.S
+++ b/ports/sysdeps/tile/start.S
@@ -126,27 +126,37 @@ _start:
 	 moveli r0, hw2_last(main - .Lmy_pc)
 	}
 	{
-	 moveli r3, hw2_last(__libc_csu_init - .Lmy_pc)
 	 shl16insli r0, r0, hw1(main - .Lmy_pc)
+	 moveli r3, hw2_last(__libc_csu_init - .Lmy_pc)
 	}
 	{
-	 shl16insli r3, r3, hw1(__libc_csu_init - .Lmy_pc)
 	 shl16insli r0, r0, hw0(main - .Lmy_pc)
+	 shl16insli r3, r3, hw1(__libc_csu_init - .Lmy_pc)
 	}
 	{
+	 ADD_PTR r0, r0, r13
 	 shl16insli r3, r3, hw0(__libc_csu_init - .Lmy_pc)
+	}
+	{
+	 moveli r12, hw2_last_plt(__libc_start_main - .Lmy_pc)
+	 ADD_PTR r3, r3, r13
+	}
+	{
+	 shl16insli r12, r12, hw1_plt(__libc_start_main - .Lmy_pc)
 	 moveli r4, hw2_last(__libc_csu_fini - .Lmy_pc)
 	}
 	{
-	 ADD_PTR r0, r0, r13
+	 shl16insli r12, r12, hw0_plt(__libc_start_main - .Lmy_pc)
 	 shl16insli r4, r4, hw1(__libc_csu_fini - .Lmy_pc)
 	}
 	{
-	 ADD_PTR r3, r3, r13
+	 ADD_PTR r12, r12, r13
 	 shl16insli r4, r4, hw0(__libc_csu_fini - .Lmy_pc)
 	}
 	{
 	 ADD_PTR r4, r4, r13
+	 jalr r12
+	}
 #else
 	 addli r0, r13, lo16(main - .Lmy_pc)
 	}
@@ -160,13 +170,12 @@ _start:
 	}
 	{
 	 auli r4, r4, ha16(__libc_csu_fini - .Lmy_pc)
-
-#endif
-
 	 /* Call the user's main function, and exit with its value.
 	    But let the libc call main. */
 	 j plt(__libc_start_main)
 	}
+#endif
+
 	{
 	 /* Tell backtracer to give up (_start has no caller). */
 	 info INFO_OP_CANNOT_BACKTRACE
diff --git a/ports/sysdeps/tile/tilegx/tilegx64/configure b/ports/sysdeps/tile/tilegx/tilegx64/configure
new file mode 100644
index 0000000..dbe0a87
--- /dev/null
+++ b/ports/sysdeps/tile/tilegx/tilegx64/configure
@@ -0,0 +1,21 @@
+# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/tile/tilegx/tilegx64.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for large memory model support" >&5
+$as_echo_n "checking for large memory model support... " >&6; }
+if ${libc_cv_cc_mcmodel_large+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if { ac_try='${CC-cc} -mcmodel=large -xc /dev/null -S -o /dev/null'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  libc_cv_cc_mcmodel_large=yes
+else
+  libc_cv_cc_mcmodel_large=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_mcmodel_large" >&5
+$as_echo "$libc_cv_cc_mcmodel_large" >&6; }
diff --git a/ports/sysdeps/tile/tilegx/tilegx64/configure.in b/ports/sysdeps/tile/tilegx/tilegx64/configure.in
new file mode 100644
index 0000000..5a7e912
--- /dev/null
+++ b/ports/sysdeps/tile/tilegx/tilegx64/configure.in
@@ -0,0 +1,7 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/tile/tilegx/tilegx64.
+
+dnl Check if -mcmodel=large exists (gcc 4.8 and later).
+AC_CACHE_CHECK(for large memory model support, libc_cv_cc_mcmodel_large, [dnl
+LIBC_TRY_CC_OPTION([-mcmodel=large], [libc_cv_cc_mcmodel_large=yes], dnl
+[libc_cv_cc_mcmodel_large=no])])
-- 
1.7.10.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]