This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


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

duplicate -mdisable-got with gcc-3.0


Hi!

Using this [1] patch I got a gcc-3 for arm-uclinux, it seems to work
except for one thing: I can't duplicate the effect of disable-got (or
no-got) [patch by Vladimir Lebedev], so my programs will crash
immediately...

The specific problem is that, when using -fpic, the gcc tries (of
course) to look up the jump adress of a function in a got - which is
non-existant on uclinux with statically linked libraries/flat file
format.

When not using -fpic, gcc hard-codes the funtion address in the object
file, which also is not the desired effect.

What I need is 
 - all code is called pc-relative (the linker can do all relocating, we
link everything statically)
 - all data is adressed relative to a base register (the loader supplies
the start address of the data segment in r10 - but I could probably
modify the startup code in the library and/or the kernel.)

As an example, __uClibc_main in 3 variants:
 - compiled with the old compiler, working:
00000004 <__uClibc_main>:
   4:	e59fc044 	ldr	ip, [pc, #44]	; 50 <__uClibc_main+0x4c>
   8:	e59f3044 	ldr	r3, [pc, #44]	; 54 <__uClibc_main+0x50>
	...
  18:	e08f3003 	add	r3, pc, r3
	...
  28:	e1a0f003 	mov	pc, r3
	...
where the constant in 54 needs no adjusting, as the whole thing is
pc-relative.

 - compiled with 3.0.2, -fpic -msingle-pic-base -mpic-register=r9:
00000004 <__uClibc_main>:
	...
  14:	e59f3034 	ldr	r3, [pc, #34]	; 50 <__uClibc_main+0x4c>
	...
  28:	e799f003 	ldr	pc, [r9, r3]
	...
where the constant in 50 will have to be an offset in the got. r9 is
apparently set up to point to the (still: non-existing) got. It get's
set to r10 (which is the start of the data segment) minus some constant
the linker supplies.

 - compiled without -fpic:
00000004 <__uClibc_main>:
	...
  14:	e59f3030 	ldr	r3, [pc, #30]	; 4c <__uClibc_main+0x48>
	...
  24:	e1a0f003 	mov	pc, r3
	...
is just a direct jump to a hardcoded address - which does not serve
anybody.

Ok, this was quite long. I hope anybody out there has a similar
environment and knows how to help me.
 
greets from Zürich
-- vbi

[1]
diff -rudN gcc-3.0.2.orig/config.sub gcc-3.0.2/config.sub
--- gcc-3.0.2.orig/config.sub	Mon Jul 16 12:04:04 2001
+++ gcc-3.0.2/config.sub	Tue Oct 30 15:34:49 2001
@@ -1035,7 +1035,8 @@
 	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* \
+	      | -its* | -os2* | -uclinux*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
diff -rudN gcc-3.0.2.orig/gcc/config/arm/linux-gas.h
gcc-3.0.2/gcc/config/arm/linux-gas.h
--- gcc-3.0.2.orig/gcc/config/arm/linux-gas.h	Tue Jan  2 14:38:41 2001
+++ gcc-3.0.2/gcc/config/arm/linux-gas.h	Tue Oct 30 15:34:49 2001
@@ -74,6 +74,7 @@
 
 /* Clear the instruction cache from `beg' to `end'.  This makes an
    inline system call to SYS_cacheflush.  */
+#ifndef __THUMBEL__
 #define CLEAR_INSN_CACHE(BEG, END)					\
 {									\
   register unsigned long _beg __asm ("a1") = (unsigned long) (BEG);	\
@@ -83,3 +84,22 @@
 		    : "=r" (_beg)					\
 		    : "0" (_beg), "r" (_end), "r" (_flg));		\
 }
+#else
+#define CLEAR_INSN_CACHE(BEG, END)					\
+{									\
+  register unsigned long _beg __asm ("a1") = (unsigned long) (BEG);	\
+  register unsigned long _end __asm ("a2") = (unsigned long) (END);	\
+  register unsigned long _flg __asm ("a3") = 0;				
\
+  unsigned long temp;							\
+  __asm __volatile (							\
+	"adr	%1, 0f\n"						\
+"	bx	%1\n"							\
+"	.code 32\n"							\
+"0:	swi 0x9f0002		@ sys_cacheflush\n"			\
+"	adr	%1, 0b + 13\n"						\
+"	bx	%1\n"							\
+"	.code 16"							\
+		    : "=r" (_beg), "=r" (temp)				\
+		    : "0" (_beg), "r" (_end), "r" (_flg));		\
+}
+#endif
diff -rudN gcc-3.0.2.orig/gcc/config/arm/t-arm-elf
gcc-3.0.2/gcc/config/arm/t-arm-elf
--- gcc-3.0.2.orig/gcc/config/arm/t-arm-elf	Thu Sep 21 19:36:19 2000
+++ gcc-3.0.2/gcc/config/arm/t-arm-elf	Tue Oct 30 15:37:32 2001
@@ -37,9 +37,9 @@
 # MULTILIB_OPTIONS    += mapcs-32/mapcs-26
 # MULTILIB_DIRNAMES   += 32bit 26bit
 # 
-# MULTILIB_OPTIONS    += mno-thumb-interwork/mthumb-interwork
-# MULTILIB_DIRNAMES   += normal interwork
-# MULTILIB_EXCEPTIONS += *mapcs-26/*mthumb-interwork*
+MULTILIB_OPTIONS    += mno-thumb-interwork/mthumb-interwork
+MULTILIB_DIRNAMES   += normal interwork
+MULTILIB_EXCEPTIONS += *mapcs-26/*mthumb-interwork*
 # 
 # MULTILIB_OPTIONS    += fno-leading-underscore/fleading-underscore
 # MULTILIB_DIRNAMES   += elf under
@@ -69,6 +69,9 @@
 # MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm620
 
 EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
+
+# for uclinux:
+MULTILIB_EXTRA_OPTS = fpic msingle-pic-base mpic-register=r9
 
 # If EXTRA_MULTILIB_PARTS is not defined above then define EXTRA_PARTS
here
 # EXTRA_PARTS = crtbegin.o crtend.o


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