.Lsda2e = .-.LCTOC1
.long __SBSS2_END__ /* end of .sdata2/.sbss2 section */
+#ifdef _RELOCATABLE
+.Lgots = .-.LCTOC1
+ .long __GOT_START__ /* Global offset table start */
+
+.Lgotm1 = .-.LCTOC1
+ .long _GLOBAL_OFFSET_TABLE_-4 /* end of GOT ptrs before BLCL + 3 reserved words */
+
+.Lgotm2 = .-.LCTOC1
+ .long _GLOBAL_OFFSET_TABLE_+12 /* start of GOT ptrs after BLCL + 3 reserved words */
+
+.Lgote = .-.LCTOC1
+ .long __GOT_END__ /* Global offset table end */
+
.Lgot2s = .-.LCTOC1
.long __GOT2_START__ /* -mrelocatable GOT pointers start */
.Linit = .-.LCTOC1
.long .Linit_p /* address of variable to say we've been called */
+ .text
+ .align 2
+.Lptr:
+ .long .LCTOC1-.Laddr /* PC relative pointer to .got2 */
+#endif
+
.data
.align 2
.Linit_p:
.long 0
.text
-#ifdef _RELOCATABLE
-.Lptr:
- .long .LCTOC1-.Laddr /* PC relative pointer to .got2 */
-#endif
FUNC_START(__eabi)
be assembled with other assemblers than GAS, such as the Solaris PowerPC
assembler. */
-#ifdef _RELOCATABLE
+#ifndef _RELOCATABLE
+ addis 10,0,.Linit_p@ha /* init flag */
+ addis 11,0,.LCTOC1@ha /* load address of .LCTOC1 */
+ lwz 9,.Linit_p@l(10) /* init flag */
+ addi 11,11,.LCTOC1@l
+ cmplwi 2,9,0 /* init flag != 0? */
+ bnelr 2 /* return now, if we've been called already */
+ stw 1,.Linit_p@l(10) /* store a non-zero value in the done flag */
+
+#else /* -mrelocatable */
mflr 0
bl .Laddr /* get current address */
.Laddr:
lwz 10,.Linit(11) /* address of init flag */
subf. 12,12,11 /* calculate difference */
lwzx 9,10,12 /* done flag */
- mtlr 0 /* restore link register */
cmplwi 2,9,0 /* init flag != 0? */
bnelr 2 /* return now, if we've been called already */
stwx 1,10,12 /* store a non-zero value in the done flag */
- bne- 0,.Lreloc /* skip if we need to relocate */
-
-#else /* !-mrelocatable */
- addis 10,0,.Linit_p@ha /* init flag */
- addis 11,0,.LCTOC1@ha /* load address of .LCTOC1 */
- lwz 9,.Linit_p@l(10) /* init flag */
- addi 11,11,.LCTOC1@l
- cmplwi 2,9,0 /* init flag != 0? */
- bnelr 2 /* return now, if we've been called already */
- stw 1,.Linit_p@l(10) /* store a non-zero value in the done flag */
-
-#endif /* !-mrelocatable */
-
-/* Only load up register 13 if there is a .sdata and/or .sbss section */
-
- lwz 3,.Lsdas(11) /* start of .sdata/.sbss section */
- lwz 4,.Lsdae(11) /* end of .sdata/.sbss section */
- cmpw 1,3,4 /* .sdata/.sbss section non-empty? */
- beq- 1,.Lsda2l /* skip loading r13 */
-
- lwz 13,.Lsda(11) /* load r13 with _SDA_BASE address */
-
-/* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */
-
-.Lsda2l:
- lwz 3,.Lsda2s(11) /* start of .sdata/.sbss section */
- lwz 4,.Lsda2e(11) /* end of .sdata/.sbss section */
- cmpw 1,3,4 /* .sdata/.sbss section non-empty? */
- beq+ 1,.Ldone /* skip loading r2 */
-
- lwz 2,.Lsda2(11) /* load r2 with _SDA2_BASE address */
- b FUNC_NAME(__do_global_ctors) /* do any C++ global constructors (which returns to caller) */
+ beq+ 0,.Lsdata /* skip if we don't need to relocate */
+/* We need to relocate the .got2 pointers. */
-#ifdef _RELOCATABLE
-.Lreloc:
-/* We need to relocate the .got2 pointers. Don't load registers 2 or 13 */
-
- lwz 3,.Lgot2s(11) /* GOT pointers start */
- lwz 4,.Lgot2e(11) /* GOT pointers end */
+ lwz 3,.Lgot2s(11) /* GOT2 pointers start */
+ lwz 4,.Lgot2e(11) /* GOT2 pointers end */
add 3,12,3 /* adjust pointers */
add 4,12,4
-
- cmpw 1,3,4 /* any pointers to adjust */
- bc 12,6,.Lctor
-
-.Lloop:
- lwz 5,0(3) /* next pointer */
- add 5,5,12 /* adjust */
- stw 5,0(3)
- addi 3,3,4 /* bump to next word */
- cmpw 1,3,4 /* more pointers to adjust? */
- bc 4,6,.Lloop
+ bl FUNC_NAME(__eabi_convert) /* convert pointers in .got2 section */
/* Fixup the .ctor section for static constructors */
-.Lctor:
lwz 3,.Lctors(11) /* constructors pointers start */
lwz 4,.Lctore(11) /* constructors pointers end */
-
- cmpw 1,3,4 /* any pointers to adjust */
- bc 12,6,.Ldtor
-
-.Lcloop:
- lwz 5,0(3) /* next pointer */
- add 5,5,12 /* adjust */
- stw 5,0(3)
- addi 3,3,4 /* bump to next word */
- cmpw 1,3,4 /* more pointers to adjust? */
- bc 4,6,.Lcloop
+ bl FUNC_NAME(__eabi_convert) /* convert constructors */
/* Fixup the .dtor section for static destructors */
-.Ldtor:
lwz 3,.Ldtors(11) /* destructors pointers start */
lwz 4,.Ldtore(11) /* destructors pointers end */
-
- cmpw 1,3,4 /* any pointers to adjust */
- bc 12,6,.Lexcept
-
-.Ldloop:
- lwz 5,0(3) /* next pointer */
- add 5,5,12 /* adjust */
- stw 5,0(3)
- addi 3,3,4 /* bump to next word */
- cmpw 1,3,4 /* more pointers to adjust? */
- bc 4,6,.Ldloop
+ bl FUNC_NAME(__eabi_convert) /* convert destructors */
/* Fixup the .gcc_except_table section for G++ exceptions */
-.Lexcept:
lwz 3,.Lexcepts(11) /* exception table pointers start */
lwz 4,.Lexcepte(11) /* exception table pointers end */
+ bl FUNC_NAME(__eabi_convert) /* convert exceptions */
- cmpw 1,3,4 /* any pointers to adjust */
- bc 12,6,.Lfix
+/* Fixup the the addresses in the GOT below _GLOBAL_OFFSET_TABLE_-4 */
-.Leloop:
- lwz 5,0(3) /* next pointer */
- addi 3,3,4 /* bump to next word */
- cmpi 1,5,0
- beq 1,.Leloop /* if NULL pointer, don't adjust */
- add 5,5,12 /* adjust */
- stw 5,-4(3)
- cmpw 1,3,4 /* more pointers to adjust? */
- bc 4,6,.Leloop
+ lwz 3,.Lgots(11) /* GOT table pointers start */
+ lwz 4,.Lgotm1(11) /* GOT table pointers below _GLOBAL_OFFSET_TABLE-4 */
+ bl FUNC_NAME(__eabi_convert) /* convert lower GOT */
+
+/* Fixup the the addresses in the GOT above _GLOBAL_OFFSET_TABLE_+12 */
+
+ lwz 3,.Lgotm2(11) /* GOT table pointers above _GLOBAL_OFFSET_TABLE+12 */
+ lwz 4,.Lgote(11) /* GOT table pointers end */
+ bl FUNC_NAME(__eabi_convert) /* convert lower GOT */
/* Fixup any user initialized pointers now (the compiler drops pointers to */
/* each of the relocs that it does in the .fixup section). */
.Lfix:
lwz 3,.Lfixups(11) /* fixup pointers start */
lwz 4,.Lfixupe(11) /* fixup pointers end */
+ bl FUNC_NAME(__eabi_uconvert) /* convert user initialized pointers */
- cmpw 1,3,4 /* any user pointers to adjust */
- bc 12,6,.Ldone
-
-.Lfloop:
- lwz 5,0(3) /* next pointer */
- add 5,5,12 /* adjust pointer */
- lwz 6,0(5) /* get the pointer it points to */
- stw 5,0(3) /* store adjusted pointer */
- add 6,6,12 /* adjust */
- stw 6,0(5)
- addi 3,3,4 /* bump to next word */
- cmpw 1,3,4 /* more pointers to adjust? */
- bc 4,6,.Lfloop
+.Lsdata:
+ mtlr 0 /* restore link register */
#endif /* _RELOCATABLE */
-/* Done adjusting pointers, return */
+/* Only load up register 13 if there is a .sdata and/or .sbss section */
+ lwz 3,.Lsdas(11) /* start of .sdata/.sbss section */
+ lwz 4,.Lsdae(11) /* end of .sdata/.sbss section */
+ cmpw 1,3,4 /* .sdata/.sbss section non-empty? */
+ beq- 1,.Lsda2l /* skip loading r13 */
+
+ lwz 13,.Lsda(11) /* load r13 with _SDA_BASE_ address */
+
+/* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */
+
+.Lsda2l:
+ lwz 3,.Lsda2s(11) /* start of .sdata/.sbss section */
+ lwz 4,.Lsda2e(11) /* end of .sdata/.sbss section */
+ cmpw 1,3,4 /* .sdata/.sbss section non-empty? */
+ beq+ 1,.Ldone /* skip loading r2 */
+
+ lwz 2,.Lsda2(11) /* load r2 with _SDA2_BASE_ address */
+
+/* Done adjusting pointers, return by way of doing the C++ global constructors. */
.Ldone:
b FUNC_NAME(__do_global_ctors) /* do any C++ global constructors (which returns to caller) */
FUNC_END(__eabi)
+/* Special subroutine to convert a bunch of pointers directly.
+ r0 has original link register
+ r3 has low pointer to convert
+ r4 has high pointer to convert
+ r5 .. r10 are scratch registers
+ r11 has the address of .LCTOC1 in it.
+ r12 has the value to add to each pointer
+ r13 .. r31 are unchanged */
+
+FUNC_START(__eabi_convert)
+ cmplw 1,3,4 /* any pointers to convert? */
+ subf 5,3,4 /* calculate number of words to convert */
+ bclr 4,4 /* return if no pointers */
+
+ srawi 5,5,2
+ addi 3,3,-4 /* start-4 for use with lwzu */
+ mtctr 5
+
+.Lcvt:
+ lwzu 6,4(3) /* pointer to convert */
+ cmpi 0,6,0
+ beq- .Lcvt2 /* if pointer is null, don't convert */
+
+ add 6,6,12 /* convert pointer */
+ stw 6,0(3)
+.Lcvt2:
+ bdnz+ .Lcvt
+ blr
+
+FUNC_END(__eabi_convert)
+
+/* Special subroutine to convert the pointers the user has initialized. The
+ compiler has placed the address of the initialized pointer into the .fixup
+ section.
+
+ r0 has original link register
+ r3 has low pointer to convert
+ r4 has high pointer to convert
+ r5 .. r10 are scratch registers
+ r11 has the address of .LCTOC1 in it.
+ r12 has the value to add to each pointer
+ r13 .. r31 are unchanged */
+
+FUNC_START(__eabi_uconvert)
+ cmplw 1,3,4 /* any pointers to convert? */
+ subf 5,3,4 /* calculate number of words to convert */
+ bclr 4,4 /* return if no pointers */
+
+ srawi 5,5,2
+ addi 3,3,-4 /* start-4 for use with lwzu */
+ mtctr 5
+
+.Lucvt:
+ lwzu 6,4(3) /* next pointer to pointer to convert */
+ add 6,6,12 /* adjust pointer */
+ lwz 7,0(6) /* get the pointer it points to */
+ stw 6,0(3) /* store adjusted pointer */
+ add 7,7,12 /* adjust */
+ stw 7,0(6)
+ bdnz+ .Lucvt
+ blr
+
+FUNC_END(__eabi_uconvert)
+
/* Routines for saving floating point registers, called by the compiler. */
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the floating point save area. */
} \
else if (TARGET_SDATA) \
rs6000_sdata = (TARGET_EABI) ? SDATA_EABI : SDATA_SYSV; \
- else if (!TARGET_RELOCATABLE && !flag_pic && DEFAULT_ABI == ABI_V4) \
+ else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \
{ \
rs6000_sdata = SDATA_DATA; \
target_flags |= MASK_SDATA; \
if (TARGET_RELOCATABLE && \
(rs6000_sdata == SDATA_EABI || rs6000_sdata == SDATA_SYSV)) \
{ \
- target_flags &= ~MASK_SDATA; \
- rs6000_sdata = SDATA_NONE; \
+ rs6000_sdata = SDATA_DATA; \
error ("-mrelocatable and -msdata are incompatible."); \
} \
\
- if (TARGET_RELOCATABLE && !TARGET_EABI) \
- { \
- target_flags |= ~MASK_EABI; \
- error ("-mrelocatable and -mno-eabi are incompatible."); \
- } \
- \
if (TARGET_SDATA && DEFAULT_ABI != ABI_V4 \
&& DEFAULT_ABI != ABI_SOLARIS) \
{ \
target_flags &= ~MASK_SDATA; \
- error ("-msdata and -mcall-aix are incompatible."); \
+ error ("-msdata and -mcall-%s are incompatible.", rs6000_abi_name); \
} \
\
if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \
#undef CPP_SYSV_SPEC
#define CPP_SYSV_SPEC \
"%{mrelocatable*: -D_RELOCATABLE} \
+%{fpic: -D__PIC__=1 -D__pic__=1} \
+%{fPIC: -D__PIC__=2 -D__pic__=2} \
%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \
%{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \
%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: %(cpp_sysv_default) }}}} \
#undef CPP_SYSV_DEFAULT_SPEC
#define CPP_SYSV_DEFAULT_SPEC "-D_CALL_SYSV"
+#ifndef CPP_ENDIAN_BIG_SPEC
+#define CPP_ENDIAN_BIG_SPEC "-D_BIG_ENDIAN -D__BIG_ENDIAN__ -Amachine(bigendian)"
+#endif
+
+#ifndef CPP_ENDIAN_LITTLE_SPEC
+#define CPP_ENDIAN_LITTLE_SPEC "-D_LITTLE_ENDIAN -D__LITTLE_ENDIAN__ -Amachine(littleendian)"
+#endif
+
+#ifndef CPP_ENDIAN_SOLARIS_SPEC
+#define CPP_ENDIAN_SOLARIS_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)"
+#endif
+
/* For solaris, don't define _LITTLE_ENDIAN, it conflicts with a header file. */
#undef CPP_ENDIAN_SPEC
#define CPP_ENDIAN_SPEC \
-"%{mlittle: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
-%{mlittle-endian: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
-%{mbig: -D_BIG_ENDIAN -Amachine(bigendian)} \
-%{mbig-endian: -D_BIG_ENDIAN -Amachine(bigendian)} \
+"%{mlittle: %(cpp_endian_little) } \
+%{mlittle-endian: %(cpp_endian_little) } \
+%{mbig: %(cpp_endian_big) } \
+%{mbig-endian: %(cpp_endian_big) } \
%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
- %{mcall-solaris: -Amachine(littleendian)} \
- %{mcall-nt: -D_LITTLE_ENDIAN -Amachine(littleendian)} \
- %{mcall-linux: -D_BIG_ENDIAN -Amachine(bigendian)} \
- %{mcall-aixdesc: -D_BIG_ENDIAN -Amachine(bigendian)} \
+ %{mcall-solaris: %(cpp_endian_solaris) } \
+ %{mcall-nt: %(cpp_endian_little) } \
+ %{mcall-linux: %(cpp_endian_big) } \
+ %{mcall-aixdesc: %(cpp_endian_big) } \
%{!mcall-solaris: %{!mcall-linux: %{!mcall-nt: %{!mcall-aixdesc: %(cpp_endian_default) }}}}}}}}"
#undef CPP_ENDIAN_DEFAULT_SPEC
-#define CPP_ENDIAN_DEFAULT_SPEC "-D_BIG_ENDIAN -Amachine(bigendian)"
+#define CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_big)"
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) %(cpp_endian) %(cpp_cpu) \
{ "link_os_linux", LINK_OS_LINUX_SPEC }, \
{ "link_os_solaris", LINK_OS_SOLARIS_SPEC }, \
{ "link_os_default", LINK_OS_DEFAULT_SPEC }, \
+ { "cpp_endian_big", CPP_ENDIAN_BIG_SPEC }, \
+ { "cpp_endian_little", CPP_ENDIAN_LITTLE_SPEC }, \
+ { "cpp_endian_solaris", CPP_ENDIAN_SOLARIS_SPEC }, \
{ "cpp_os_mvme", CPP_OS_MVME_SPEC }, \
{ "cpp_os_sim", CPP_OS_SIM_SPEC }, \
{ "cpp_os_linux", CPP_OS_LINUX_SPEC }, \