configure.in: Check for ld.
* configure.in: Check for ld. (HAVE_LD_EH_FRAME_HDR): Define if ld supports --eh-frame-hdr option. * configure, config.in: Rebuilt. * config.gcc: Add crtbeginT.o to extra_parts where needed. * config/t-linux (LIB2ADDEH, LIB2ADDEHDEP): Use unwind-dw2-fde-glibc frame unwinding on Linux. * config/t-linux-gnulibc1 (LIB2ADDEH, LIB2ADDEHDEP): Use unwind-dw2-fde frame unwinding. * config/linux.h (STARTFILE_SPEC): Use crtbeginT.o for -static. (LINK_EH_SPEC): Define. * config/i386/gnu.h (STARTFILE_SPEC): Use crtbeginT.o for -static. * config/ia64/linux.h (STARTFILE_SPEC, LINK_EH_SPEC): Define. * config/ia64/fde-glibc.c (_Unwind_IteratePhdrCallback): Don't iterate further if pc falls into current library, but fde was not found. * config/sparc/linux.h (STARTFILE_SPEC): Use crtbeginT.o for -static if using glibc. (LINK_EH_SPEC): Define. * config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64): Use crtbeginT.o for -static. (LINK_EH_SPEC): Define. * config/sparc/t-linux64 (EXTRA_MULTILIB_PARTS): Add crtbeginT.o. * Makefile.in (crtbeginT.o): Add rule. * gcc.c (init_gcc_specs): For -static-libgcc, use -lgcc -lgcc_eh. If neither -static-libgcc nor -shared-libgcc is passed and -shared, use -lgcc if LINK_EH_SPEC is defined and -lgcc_s -lgcc if not. If none of the above switches are passed, use -lgcc -lgcc_eh. (init_spec): If LINK_EH_SPEC is defined, prepend it to link_spec. * mklibgcc.in: Don't include LIB2ADDEH objects into libgcc.a if creating libgcc_s.so, put them into separate libgcc_eh.a instead. * unwind-dw2-fde.c: Don't include any headers if this file is included from other .c file. * unwind-dw2-fde-glibc.c: New file. * crtstuff.c (USE_PT_GNU_EH_FRAME, USE_EH_FRAME_REGISTRY): Define. Use it instead of EH_FRAME_SECTION_NAME where appropriate. From-SVN: r48039
This commit is contained in:
parent
861ef92859
commit
275b60d6d8
@ -1,3 +1,41 @@
|
||||
2001-12-15 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* configure.in: Check for ld.
|
||||
(HAVE_LD_EH_FRAME_HDR): Define if ld supports --eh-frame-hdr option.
|
||||
* configure, config.in: Rebuilt.
|
||||
* config.gcc: Add crtbeginT.o to extra_parts where needed.
|
||||
* config/t-linux (LIB2ADDEH, LIB2ADDEHDEP): Use unwind-dw2-fde-glibc
|
||||
frame unwinding on Linux.
|
||||
* config/t-linux-gnulibc1 (LIB2ADDEH, LIB2ADDEHDEP): Use unwind-dw2-fde
|
||||
frame unwinding.
|
||||
* config/linux.h (STARTFILE_SPEC): Use crtbeginT.o for -static.
|
||||
(LINK_EH_SPEC): Define.
|
||||
* config/i386/gnu.h (STARTFILE_SPEC): Use crtbeginT.o for -static.
|
||||
* config/ia64/linux.h (STARTFILE_SPEC, LINK_EH_SPEC): Define.
|
||||
* config/ia64/fde-glibc.c (_Unwind_IteratePhdrCallback): Don't
|
||||
iterate further if pc falls into current library, but fde was not
|
||||
found.
|
||||
* config/sparc/linux.h (STARTFILE_SPEC): Use crtbeginT.o for -static
|
||||
if using glibc.
|
||||
(LINK_EH_SPEC): Define.
|
||||
* config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64):
|
||||
Use crtbeginT.o for -static.
|
||||
(LINK_EH_SPEC): Define.
|
||||
* config/sparc/t-linux64 (EXTRA_MULTILIB_PARTS): Add crtbeginT.o.
|
||||
* Makefile.in (crtbeginT.o): Add rule.
|
||||
* gcc.c (init_gcc_specs): For -static-libgcc, use -lgcc -lgcc_eh.
|
||||
If neither -static-libgcc nor -shared-libgcc is passed and -shared,
|
||||
use -lgcc if LINK_EH_SPEC is defined and -lgcc_s -lgcc if not.
|
||||
If none of the above switches are passed, use -lgcc -lgcc_eh.
|
||||
(init_spec): If LINK_EH_SPEC is defined, prepend it to link_spec.
|
||||
* mklibgcc.in: Don't include LIB2ADDEH objects into libgcc.a if
|
||||
creating libgcc_s.so, put them into separate libgcc_eh.a instead.
|
||||
* unwind-dw2-fde.c: Don't include any headers if this file
|
||||
is included from other .c file.
|
||||
* unwind-dw2-fde-glibc.c: New file.
|
||||
* crtstuff.c (USE_PT_GNU_EH_FRAME, USE_EH_FRAME_REGISTRY): Define.
|
||||
Use it instead of EH_FRAME_SECTION_NAME where appropriate.
|
||||
|
||||
2001-12-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* builtins.c (expand_builtin_memcmp): Mark parameter with
|
||||
|
@ -1106,6 +1106,15 @@ $(T)crtendS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
|
||||
-c $(srcdir)/crtstuff.c -DCRT_END -DCRTSTUFFS_O \
|
||||
-o $(T)crtendS$(objext)
|
||||
|
||||
# This is a version of crtbegin for -static links.
|
||||
$(T)crtbeginT.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
|
||||
gbl-ctors.h stmp-int-hdrs tsystem.h
|
||||
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
|
||||
-finhibit-size-directive -fno-inline-functions \
|
||||
-fno-exceptions $(CRTSTUFF_T_CFLAGS) @inhibit_libc@ \
|
||||
-c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFT_O \
|
||||
-o $(T)crtbeginT$(objext)
|
||||
|
||||
# Compile the start modules crt0.o and mcrt0.o that are linked with
|
||||
# every program
|
||||
crt0.o: s-crt0 ; @true
|
||||
@ -2384,7 +2393,7 @@ mostlyclean: $(INTL_MOSTLYCLEAN) lang.mostlyclean
|
||||
# that don't exist in the distribution.
|
||||
INTL_CLEAN = intl.clean
|
||||
clean: mostlyclean $(INTL_CLEAN) lang.clean
|
||||
-rm -f libgcc.a libgcc_s$(SHLIB_EXT) libgcc_s$(SHLIB_EXT).1
|
||||
-rm -f libgcc.a libgcc_eh.a libgcc_s$(SHLIB_EXT) libgcc_s$(SHLIB_EXT).1
|
||||
-rm -f config.h tconfig.h hconfig.h tm_p.h
|
||||
-rm -f cs-*
|
||||
-rm -rf libgcc
|
||||
@ -3140,11 +3149,15 @@ stage1-start:
|
||||
-if [ -f as$(exeext) ] ; then (cd stage1 && $(LN_S) ../as$(exeext) .) ; else true ; fi
|
||||
-if [ -f ld$(exeext) ] ; then (cd stage1 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
|
||||
-if [ -f collect-ld$(exeext) ] ; then (cd stage1 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
|
||||
-rm -f stage1/libgcc.a
|
||||
-rm -f stage1/libgcc.a stage1/libgcc_eh.a
|
||||
-cp libgcc.a stage1
|
||||
-if $(RANLIB_TEST_FOR_TARGET) ; then \
|
||||
$(RANLIB_FOR_TARGET) stage1/libgcc.a; \
|
||||
else true; fi
|
||||
-if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage1; \
|
||||
if $(RANLIB_TEST_FOR_TARGET) ; then \
|
||||
$(RANLIB_FOR_TARGET) stage1/libgcc_eh.a; \
|
||||
else true; fi; fi
|
||||
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
|
||||
cp stage1/$${f} . ; \
|
||||
else true; \
|
||||
@ -3165,11 +3178,15 @@ stage2-start:
|
||||
-if [ -f as$(exeext) ] ; then (cd stage2 && $(LN_S) ../as$(exeext) .) ; else true ; fi
|
||||
-if [ -f ld$(exeext) ] ; then (cd stage2 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
|
||||
-if [ -f collect-ld$(exeext) ] ; then (cd stage2 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
|
||||
-rm -f stage2/libgcc.a
|
||||
-rm -f stage2/libgcc.a stage2/libgcc_eh.a
|
||||
-cp libgcc.a stage2
|
||||
-if $(RANLIB_TEST_FOR_TARGET) ; then \
|
||||
$(RANLIB_FOR_TARGET) stage2/libgcc.a; \
|
||||
else true; fi
|
||||
-if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage2; \
|
||||
if $(RANLIB_TEST_FOR_TARGET) ; then \
|
||||
$(RANLIB_FOR_TARGET) stage2/libgcc_eh.a; \
|
||||
else true; fi; fi
|
||||
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
|
||||
cp stage2/$${f} . ; \
|
||||
else true; \
|
||||
@ -3190,11 +3207,15 @@ stage3-start:
|
||||
-if [ -f as$(exeext) ] ; then (cd stage3 && $(LN_S) ../as$(exeext) .) ; else true ; fi
|
||||
-if [ -f ld$(exeext) ] ; then (cd stage3 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
|
||||
-if [ -f collect-ld$(exeext) ] ; then (cd stage3 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
|
||||
-rm -f stage3/libgcc.a
|
||||
-rm -f stage3/libgcc.a stage3/libgcc_eh.a
|
||||
-cp libgcc.a stage3
|
||||
-if $(RANLIB_TEST_FOR_TARGET) ; then \
|
||||
$(RANLIB_FOR_TARGET) stage3/libgcc.a; \
|
||||
else true; fi
|
||||
-if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage3; \
|
||||
if $(RANLIB_TEST_FOR_TARGET) ; then \
|
||||
$(RANLIB_FOR_TARGET) stage3/libgcc_eh.a; \
|
||||
else true; fi; fi
|
||||
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
|
||||
cp stage3/$${f} . ; \
|
||||
else true; \
|
||||
@ -3215,11 +3236,15 @@ stage4-start:
|
||||
-if [ -f as$(exeext) ] ; then (cd stage4 && $(LN_S) ../as$(exeext) .) ; else true ; fi
|
||||
-if [ -f ld$(exeext) ] ; then (cd stage4 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
|
||||
-if [ -f collect-ld$(exeext) ] ; then (cd stage4 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
|
||||
-rm -f stage4/libgcc.a
|
||||
-rm -f stage4/libgcc.a stage4/libgcc_eh.a
|
||||
-cp libgcc.a stage4
|
||||
-if $(RANLIB_TEST_FOR_TARGET) ; then \
|
||||
$(RANLIB_FOR_TARGET) stage4/libgcc.a; \
|
||||
else true; fi
|
||||
-if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage4; \
|
||||
if $(RANLIB_TEST_FOR_TARGET) ; then \
|
||||
$(RANLIB_FOR_TARGET) stage4/libgcc_eh.a; \
|
||||
else true; fi; fi
|
||||
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
|
||||
cp stage4/$${f} . ; \
|
||||
else true; \
|
||||
|
@ -276,7 +276,7 @@ case $machine in
|
||||
# support are matched above and just set $cpu_type.
|
||||
xm_defines=POSIX
|
||||
tm_file="${cpu_type}/gnu.h"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
|
||||
# GNU always uses ELF.
|
||||
elf=yes
|
||||
# GNU tools are the only tools.
|
||||
@ -700,7 +700,7 @@ cris-*-elf | cris-*-none)
|
||||
cris-*-linux*)
|
||||
tm_file="dbxelf.h elfos.h svr4.h ${tm_file} linux.h cris/linux.h"
|
||||
tmake_file="cris/t-cris t-slibgcc-elf-ver cris/t-linux"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
case x${enable_threads} in
|
||||
x | xyes | xpthreads | xposix)
|
||||
thread_file=posix
|
||||
@ -750,7 +750,7 @@ hppa*-*-linux* | parisc*-*-linux*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h pa/pa-linux.h \
|
||||
pa/pa32-regs.h pa/pa32-linux.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux pa/t-linux"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gas=yes gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
@ -981,7 +981,7 @@ i370-*-linux*)
|
||||
tm_file="dbxelf.h elfos.h svr4.h linux.h i370/linux.h ${tm_file}"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux"
|
||||
# broken_install=yes
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
# extra_parts="crtbegin.o crtend.o"
|
||||
gnu_ld=yes
|
||||
gas=yes
|
||||
@ -1178,7 +1178,7 @@ i[34567]86-*-linux*) # Intel 80386's running GNU/Linux
|
||||
# aka GNU/Linux C library 6
|
||||
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/linux.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux i386/t-crtstuff"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
float_format=i386
|
||||
if test x$enable_threads = xyes; then
|
||||
@ -1189,7 +1189,7 @@ x86_64-*-linux*)
|
||||
tm_file="i386/biarch64.h i386/i386.h i386/att.h dbxelf.h elfos.h svr4.h linux.h \
|
||||
i386/x86-64.h i386/linux64.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux i386/t-crtstuff"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
float_format=i386
|
||||
if test x$enable_threads = xyes; then
|
||||
@ -2280,7 +2280,7 @@ mips*-*-linux*) # Linux MIPS, either endian.
|
||||
;;
|
||||
esac
|
||||
tmake_file="t-slibgcc-elf-ver t-linux"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
gas=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
@ -2867,7 +2867,7 @@ rs6000-*-lynxos*)
|
||||
s390-*-linux*)
|
||||
tm_file="s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
@ -2878,7 +2878,7 @@ s390x-*-linux*)
|
||||
md_file=s390/s390.md
|
||||
out_file=s390/s390.c
|
||||
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
@ -2982,7 +2982,7 @@ sparc-*-linux*libc1*) # Sparc's running GNU/Linux, libc5
|
||||
sparc-*-linux*) # Sparc's running GNU/Linux, libc6
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
@ -3177,7 +3177,7 @@ sparc64-*-elf*)
|
||||
sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux
|
||||
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-linux64"
|
||||
tm_file="sparc/sparc_bi.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux64.h"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
|
@ -551,6 +551,9 @@
|
||||
/* Define if your assembler supports the --gstabs option. */
|
||||
#undef HAVE_AS_GSTABS_DEBUG_FLAG
|
||||
|
||||
/* Define if your linker supports --eh-frame-hdr option. */
|
||||
#undef HAVE_LD_EH_FRAME_HDR
|
||||
|
||||
/* Define 0/1 to force the choice for exception handling model. */
|
||||
#undef CONFIG_SJLJ_EXCEPTIONS
|
||||
|
||||
|
@ -29,7 +29,8 @@
|
||||
%{!static: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
|
||||
%{static:crt0.o%s}} \
|
||||
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
|
||||
crti.o%s %{static:crtbeginT.o%s}\
|
||||
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
|
||||
|
||||
/* FIXME: Is a Hurd-specific fallback mechanism necessary? */
|
||||
#undef MD_FALLBACK_FRAME_STATE_FOR
|
||||
|
@ -110,7 +110,9 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
else
|
||||
goto found;
|
||||
}
|
||||
return 0;
|
||||
/* No need to search for further libraries when we know pc is contained
|
||||
in this library. */
|
||||
return 1;
|
||||
|
||||
found:
|
||||
*data->segment_base = seg_base;
|
||||
|
@ -18,6 +18,15 @@
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic}"
|
||||
|
||||
/* Need to override linux.h STARTFILE_SPEC, since it has crtbeginT.o in. */
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!shared: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
|
||||
%{!p:%{profile:gcrt1.o%s} \
|
||||
%{!profile:crt1.o%s}}}} \
|
||||
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
|
||||
|
||||
/* Similar to standard Linux, but adding -ffast-math support. */
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC \
|
||||
@ -45,4 +54,10 @@
|
||||
#undef PROFILE_BEFORE_PROLOGUE
|
||||
#define PROFILE_BEFORE_PROLOGUE 1
|
||||
|
||||
/* Override linux.h LINK_EH_SPEC definition.
|
||||
Signalize that because we have fde-glibc, we don't need all C shared libs
|
||||
linked against -lgcc_s. */
|
||||
#undef LINK_EH_SPEC
|
||||
#define LINK_EH_SPEC ""
|
||||
|
||||
/* End of linux.h */
|
||||
|
@ -50,12 +50,22 @@ Boston, MA 02111-1307, USA. */
|
||||
object constructed before entering `main'. */
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#ifdef USE_GNULIBC_1
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!shared: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
|
||||
%{!p:%{profile:gcrt1.o%s} \
|
||||
%{!profile:crt1.o%s}}}} \
|
||||
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
|
||||
#else
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!shared: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
|
||||
%{!p:%{profile:gcrt1.o%s} \
|
||||
%{!profile:crt1.o%s}}}} \
|
||||
crti.o%s %{static:crtbeginT.o%s}\
|
||||
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
|
||||
#endif
|
||||
|
||||
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
|
||||
the GNU/Linux magical crtend.o file (see crtstuff.c) which
|
||||
@ -98,5 +108,9 @@ Boston, MA 02111-1307, USA. */
|
||||
%{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}"
|
||||
#endif
|
||||
|
||||
#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
|
||||
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
/* Define this so we can compile MS code for use with WINE. */
|
||||
#define HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
|
@ -44,10 +44,17 @@ Boston, MA 02111-1307, USA. */
|
||||
object constructed before entering `main'. */
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#ifdef USE_GNULIBC_1
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!shared: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
|
||||
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
|
||||
#else
|
||||
"%{!shared: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
|
||||
crti.o%s %{static:crtbeginT.o%s}\
|
||||
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
|
||||
#endif
|
||||
|
||||
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
|
||||
the GNU/Linux magical crtend.o file (see crtstuff.c) which
|
||||
@ -242,4 +249,8 @@ do { \
|
||||
#else
|
||||
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
|
||||
#endif
|
||||
|
||||
#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
|
||||
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
|
@ -59,13 +59,15 @@ Boston, MA 02111-1307, USA. */
|
||||
#define STARTFILE_SPEC32 \
|
||||
"%{!shared: \
|
||||
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
|
||||
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
|
||||
crti.o%s %{static:crtbeginT.o%s}\
|
||||
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
|
||||
|
||||
#define STARTFILE_SPEC64 \
|
||||
"%{!shared: \
|
||||
%{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} %{!p:/usr/lib64/crt1.o%s}}}\
|
||||
/usr/lib64/crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
|
||||
|
||||
/usr/lib64/crti.o%s %{static:crtbeginT.o%s}\
|
||||
%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
|
||||
|
||||
#ifdef SPARC_BI_ARCH
|
||||
|
||||
#if DEFAULT_ARCH32_P
|
||||
@ -367,4 +369,8 @@ do { \
|
||||
RELATIVE relocations. */
|
||||
|
||||
/* #define DWARF_OFFSET_SIZE PTR_SIZE */
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
|
@ -7,4 +7,4 @@ MULTILIB_EXCLUSIONS = m32/!m64/mno-app-regs m32/!m64/mcmodel=medany
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
||||
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o
|
||||
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
|
||||
|
@ -9,3 +9,8 @@ TARGET_LIBGCC2_CFLAGS = -fPIC
|
||||
# Override t-slibgcc-elf-ver to export some libgcc symbols with
|
||||
# the symbol versions that glibc used.
|
||||
SHLIB_MAPFILES += $(srcdir)/config/libgcc-glibc.ver
|
||||
|
||||
# Use unwind-dw2-fde-glibc
|
||||
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
|
||||
$(srcdir)/unwind-sjlj.c
|
||||
LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
|
||||
|
@ -1,2 +1,7 @@
|
||||
# We are building for the Linux C library 5.
|
||||
T_CFLAGS = -DUSE_GNULIBC_1
|
||||
|
||||
# Use unwind-dw2-fde
|
||||
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
|
||||
$(srcdir)/unwind-sjlj.c
|
||||
LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h
|
||||
|
107
gcc/configure
vendored
107
gcc/configure
vendored
@ -6904,6 +6904,92 @@ else
|
||||
echo "$ac_t""$gcc_cv_as" 1>&6
|
||||
fi
|
||||
|
||||
# Figure out what linker we will be using.
|
||||
echo $ac_n "checking what linker to use""... $ac_c" 1>&6
|
||||
echo "configure:6904: checking what linker to use" >&5
|
||||
gcc_cv_ld=
|
||||
gcc_cv_gld_major_version=
|
||||
gcc_cv_gld_minor_version=
|
||||
gcc_cv_ld_gld_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/ld
|
||||
gcc_cv_ld_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
|
||||
if test -x "$DEFAULT_LINKER"; then
|
||||
gcc_cv_ld="$DEFAULT_LINKER"
|
||||
elif test -x "$LD"; then
|
||||
gcc_cv_ld="$LD"
|
||||
elif test -x ld$host_exeext; then
|
||||
# Build using linker in the current directory.
|
||||
gcc_cv_ld=./ld$host_exeext
|
||||
elif test -f $gcc_cv_ld_gld_srcdir/configure.in -a -f ../ld/Makefile; then
|
||||
# Single tree build which includes ld.
|
||||
for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
|
||||
do
|
||||
gcc_cv_gld_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
|
||||
if test x$gcc_cv_gld_version != x; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
|
||||
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
|
||||
fi
|
||||
|
||||
if test "x$gcc_cv_ld" = x -a x$host = x$target; then
|
||||
# Native build.
|
||||
# Search the same directories that the installed compiler will
|
||||
# search. Else we may find the wrong linker and lose. If we
|
||||
# do not find a suitable linker binary, then try the user's
|
||||
# path.
|
||||
#
|
||||
# Also note we have to check MD_EXEC_PREFIX before checking the
|
||||
# user's path. Unfortunately, there is no good way to get at the
|
||||
# value of MD_EXEC_PREFIX here. So we do a brute force search
|
||||
# through all the known MD_EXEC_PREFIX values. Ugh. This needs
|
||||
# to be fixed as part of the make/configure rewrite too.
|
||||
|
||||
if test "x$exec_prefix" = xNONE; then
|
||||
if test "x$prefix" = xNONE; then
|
||||
test_prefix=/usr/local
|
||||
else
|
||||
test_prefix=$prefix
|
||||
fi
|
||||
else
|
||||
test_prefix=$exec_prefix
|
||||
fi
|
||||
|
||||
# If the loop below does not find an linker, then use whatever
|
||||
# one we can find in the users's path.
|
||||
# user's path.
|
||||
gcc_cv_ld=ld$host_exeext
|
||||
|
||||
test_dirs="$test_prefix/lib/gcc-lib/$target/$gcc_version \
|
||||
$test_prefix/lib/gcc-lib/$target \
|
||||
/usr/lib/gcc/$target/$gcc_version \
|
||||
/usr/lib/gcc/$target \
|
||||
$test_prefix/$target/bin/$target/$gcc_version \
|
||||
$test_prefix/$target/bin \
|
||||
/usr/libexec \
|
||||
/usr/ccs/gcc \
|
||||
/usr/ccs/bin \
|
||||
/udk/usr/ccs/bin \
|
||||
/bsd43/usr/lib/cmplrs/cc \
|
||||
/usr/cross64/usr/bin \
|
||||
/usr/lib/cmplrs/cc \
|
||||
/sysv/usr/lib/cmplrs/cc \
|
||||
/svr4/usr/lib/cmplrs/cc \
|
||||
/usr/bin"
|
||||
|
||||
for dir in $test_dirs; do
|
||||
if test -f $dir/ld$host_exeext; then
|
||||
gcc_cv_ld=$dir/ld$host_exeext
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
|
||||
echo "$ac_t"""newly built ld"" 1>&6
|
||||
else
|
||||
echo "$ac_t""$gcc_cv_ld" 1>&6
|
||||
fi
|
||||
|
||||
# Figure out what nm we will be using.
|
||||
echo $ac_n "checking what nm to use""... $ac_c" 1>&6
|
||||
echo "configure:6910: checking what nm to use" >&5
|
||||
@ -7526,6 +7612,27 @@ EOF
|
||||
fi
|
||||
echo "$ac_t""$gcc_cv_as_gstabs_flag" 1>&6
|
||||
|
||||
echo $ac_n "checking linker PT_GNU_EH_FRAME support""... $ac_c" 1>&6
|
||||
echo "configure:7611: checking linker PT_GNU_EH_FRAME support" >&5
|
||||
gcc_cv_ld_eh_frame_hdr=no
|
||||
if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
|
||||
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then
|
||||
gcc_cv_ld_eh_frame_hdr=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports --eh-frame-hdr option
|
||||
if $gcc_cv_ld --help 2>/dev/null | grep eh-frame-hdr > /dev/null; then
|
||||
gcc_cv_ld_eh_frame_hdr=yes
|
||||
fi
|
||||
fi
|
||||
if test x"$gcc_cv_ld_eh_frame_hdr" = xyes; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define HAVE_LD_EH_FRAME_HDR 1
|
||||
EOF
|
||||
|
||||
fi
|
||||
echo "$ac_t""$gcc_cv_ld_eh_frame_hdr" 1>&6
|
||||
|
||||
if test "$prefix" != "/usr" && test "$prefix" != "/usr/local" ; then
|
||||
cat >> confdefs.h <<EOF
|
||||
#define PREFIX_INCLUDE_DIR "$prefix/include"
|
||||
|
109
gcc/configure.in
109
gcc/configure.in
@ -1257,6 +1257,95 @@ else
|
||||
AC_MSG_RESULT($gcc_cv_as)
|
||||
fi
|
||||
|
||||
# Figure out what linker we will be using.
|
||||
AC_MSG_CHECKING(what linker to use)
|
||||
gcc_cv_ld=
|
||||
gcc_cv_gld_major_version=
|
||||
gcc_cv_gld_minor_version=
|
||||
gcc_cv_ld_gld_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/ld
|
||||
gcc_cv_ld_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
|
||||
if test -x "$DEFAULT_LINKER"; then
|
||||
gcc_cv_ld="$DEFAULT_LINKER"
|
||||
elif test -x "$LD"; then
|
||||
gcc_cv_ld="$LD"
|
||||
elif test -x ld$host_exeext; then
|
||||
# Build using linker in the current directory.
|
||||
gcc_cv_ld=./ld$host_exeext
|
||||
elif test -f $gcc_cv_ld_gld_srcdir/configure.in -a -f ../ld/Makefile; then
|
||||
# Single tree build which includes ld.
|
||||
for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
|
||||
do
|
||||
changequote(,)dnl
|
||||
gcc_cv_gld_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
|
||||
changequote([,])dnl
|
||||
if test x$gcc_cv_gld_version != x; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
changequote(,)dnl
|
||||
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
|
||||
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
|
||||
changequote([,])dnl
|
||||
fi
|
||||
|
||||
if test "x$gcc_cv_ld" = x -a x$host = x$target; then
|
||||
# Native build.
|
||||
# Search the same directories that the installed compiler will
|
||||
# search. Else we may find the wrong linker and lose. If we
|
||||
# do not find a suitable linker binary, then try the user's
|
||||
# path.
|
||||
#
|
||||
# Also note we have to check MD_EXEC_PREFIX before checking the
|
||||
# user's path. Unfortunately, there is no good way to get at the
|
||||
# value of MD_EXEC_PREFIX here. So we do a brute force search
|
||||
# through all the known MD_EXEC_PREFIX values. Ugh. This needs
|
||||
# to be fixed as part of the make/configure rewrite too.
|
||||
|
||||
if test "x$exec_prefix" = xNONE; then
|
||||
if test "x$prefix" = xNONE; then
|
||||
test_prefix=/usr/local
|
||||
else
|
||||
test_prefix=$prefix
|
||||
fi
|
||||
else
|
||||
test_prefix=$exec_prefix
|
||||
fi
|
||||
|
||||
# If the loop below does not find an linker, then use whatever
|
||||
# one we can find in the users's path.
|
||||
# user's path.
|
||||
gcc_cv_ld=ld$host_exeext
|
||||
|
||||
test_dirs="$test_prefix/lib/gcc-lib/$target/$gcc_version \
|
||||
$test_prefix/lib/gcc-lib/$target \
|
||||
/usr/lib/gcc/$target/$gcc_version \
|
||||
/usr/lib/gcc/$target \
|
||||
$test_prefix/$target/bin/$target/$gcc_version \
|
||||
$test_prefix/$target/bin \
|
||||
/usr/libexec \
|
||||
/usr/ccs/gcc \
|
||||
/usr/ccs/bin \
|
||||
/udk/usr/ccs/bin \
|
||||
/bsd43/usr/lib/cmplrs/cc \
|
||||
/usr/cross64/usr/bin \
|
||||
/usr/lib/cmplrs/cc \
|
||||
/sysv/usr/lib/cmplrs/cc \
|
||||
/svr4/usr/lib/cmplrs/cc \
|
||||
/usr/bin"
|
||||
|
||||
for dir in $test_dirs; do
|
||||
if test -f $dir/ld$host_exeext; then
|
||||
gcc_cv_ld=$dir/ld$host_exeext
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
|
||||
AC_MSG_RESULT("newly built ld")
|
||||
else
|
||||
AC_MSG_RESULT($gcc_cv_ld)
|
||||
fi
|
||||
|
||||
# Figure out what nm we will be using.
|
||||
AC_MSG_CHECKING(what nm to use)
|
||||
if test -x nm$host_exeext; then
|
||||
@ -1533,7 +1622,7 @@ if test x"$gcc_cv_as_shf_merge" = xyes; then
|
||||
fi
|
||||
AC_MSG_RESULT($gcc_cv_as_shf_merge)
|
||||
|
||||
case "$target" in
|
||||
case "$target" in
|
||||
sparc*-*-*)
|
||||
AC_CACHE_CHECK([assembler .register pseudo-op support],
|
||||
gcc_cv_as_register_pseudo_op, [
|
||||
@ -1800,6 +1889,24 @@ if test x"$gcc_cv_as_gstabs_flag" = xyes; then
|
||||
fi
|
||||
AC_MSG_RESULT($gcc_cv_as_gstabs_flag)
|
||||
|
||||
AC_MSG_CHECKING(linker PT_GNU_EH_FRAME support)
|
||||
gcc_cv_ld_eh_frame_hdr=no
|
||||
if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
|
||||
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then
|
||||
gcc_cv_ld_eh_frame_hdr=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports --eh-frame-hdr option
|
||||
if $gcc_cv_ld --help 2>/dev/null | grep eh-frame-hdr > /dev/null; then
|
||||
gcc_cv_ld_eh_frame_hdr=yes
|
||||
fi
|
||||
fi
|
||||
if test x"$gcc_cv_ld_eh_frame_hdr" = xyes; then
|
||||
AC_DEFINE(HAVE_LD_EH_FRAME_HDR, 1,
|
||||
[Define if your linker supports --eh-frame-hdr option.])
|
||||
fi
|
||||
AC_MSG_RESULT($gcc_cv_ld_eh_frame_hdr)
|
||||
|
||||
if test "$prefix" != "/usr" && test "$prefix" != "/usr/local" ; then
|
||||
AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include")
|
||||
fi
|
||||
|
@ -66,6 +66,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
# define CRT_CALL_STATIC_FUNCTION(func) func ()
|
||||
#endif
|
||||
|
||||
#if defined(OBJECT_FORMAT_ELF) && defined(HAVE_LD_EH_FRAME_HDR) \
|
||||
&& !defined(CRTSTUFFT_O) \
|
||||
&& defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
#include <link.h>
|
||||
# if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
|
||||
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
|
||||
# define USE_PT_GNU_EH_FRAME
|
||||
# endif
|
||||
#endif
|
||||
#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME)
|
||||
# define USE_EH_FRAME_REGISTRY
|
||||
#endif
|
||||
|
||||
/* We do not want to add the weak attribute to the declarations of these
|
||||
routines in unwind-dw2-fde.h because that will cause the definition of
|
||||
these symbols to be weak as well.
|
||||
@ -245,7 +258,7 @@ __do_global_dtors_aux (void)
|
||||
f ();
|
||||
}
|
||||
|
||||
#ifdef EH_FRAME_SECTION_NAME
|
||||
#ifdef USE_EH_FRAME_REGISTRY
|
||||
#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
|
||||
/* If we used the new __register_frame_info_bases interface,
|
||||
make sure that we deregister from the same place. */
|
||||
@ -274,7 +287,7 @@ fini_dummy (void)
|
||||
asm (TEXT_SECTION_ASM_OP);
|
||||
}
|
||||
|
||||
#if defined(EH_FRAME_SECTION_NAME) || defined(JCR_SECTION_NAME)
|
||||
#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
|
||||
/* Stick a call to __register_frame_info into the .init section. For some
|
||||
reason calls with no arguments work more reliably in .init, so stick the
|
||||
call in another function. */
|
||||
@ -282,7 +295,7 @@ fini_dummy (void)
|
||||
static void
|
||||
frame_dummy (void)
|
||||
{
|
||||
#ifdef EH_FRAME_SECTION_NAME
|
||||
#ifdef USE_EH_FRAME_REGISTRY
|
||||
static struct object object;
|
||||
#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
|
||||
void *tbase, *dbase;
|
||||
@ -386,13 +399,13 @@ __do_global_dtors (void)
|
||||
for (p = __DTOR_LIST__ + 1; (f = *p); p++)
|
||||
f ();
|
||||
|
||||
#ifdef EH_FRAME_SECTION_NAME
|
||||
#ifdef USE_EH_FRAME_REGISTRY
|
||||
if (__deregister_frame_info)
|
||||
__deregister_frame_info (__EH_FRAME_BEGIN__);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(EH_FRAME_SECTION_NAME) || defined(JCR_SECTION_NAME)
|
||||
#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
|
||||
/* A helper function for __do_global_ctors, which is in crtend.o. Here
|
||||
in crtbegin.o, we can reference a couple of symbols not visible there.
|
||||
Plus, since we're before libgcc.a, we have no problems referencing
|
||||
@ -400,7 +413,7 @@ __do_global_dtors (void)
|
||||
void
|
||||
__do_global_ctors_1(void)
|
||||
{
|
||||
#ifdef EH_FRAME_SECTION_NAME
|
||||
#ifdef USE_EH_FRAME_REGISTRY
|
||||
static struct object object;
|
||||
if (__register_frame_info)
|
||||
__register_frame_info (__EH_FRAME_BEGIN__, &object);
|
||||
@ -547,7 +560,7 @@ void
|
||||
__do_global_ctors (void)
|
||||
{
|
||||
func_ptr *p;
|
||||
#if defined(EH_FRAME_SECTION_NAME) || defined(JCR_SECTION_NAME)
|
||||
#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
|
||||
__do_global_ctors_1();
|
||||
#endif
|
||||
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
|
||||
|
38
gcc/gcc.c
38
gcc/gcc.c
@ -323,7 +323,7 @@ static void clear_args PARAMS ((void));
|
||||
static void fatal_error PARAMS ((int));
|
||||
#ifdef ENABLE_SHARED_LIBGCC
|
||||
static void init_gcc_specs PARAMS ((struct obstack *,
|
||||
const char *,
|
||||
const char *, const char *,
|
||||
const char *));
|
||||
#endif
|
||||
#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
|
||||
@ -1416,28 +1416,36 @@ static struct spec_list *specs = (struct spec_list *) 0;
|
||||
|
||||
#ifdef ENABLE_SHARED_LIBGCC
|
||||
static void
|
||||
init_gcc_specs (obstack, shared_name, static_name)
|
||||
init_gcc_specs (obstack, shared_name, static_name, eh_name)
|
||||
struct obstack *obstack;
|
||||
const char *shared_name;
|
||||
const char *static_name;
|
||||
const char *eh_name;
|
||||
{
|
||||
char buffer[128];
|
||||
const char *p;
|
||||
|
||||
/* If we see -shared-libgcc, then use the shared version. */
|
||||
sprintf (buffer, "%%{shared-libgcc:%s %s}", shared_name, static_name);
|
||||
obstack_grow (obstack, buffer, strlen (buffer));
|
||||
/* If we see -static-libgcc, then use the static version. */
|
||||
sprintf (buffer, "%%{static-libgcc:%s}", static_name);
|
||||
sprintf (buffer, "%%{static-libgcc:%s %s}", static_name, eh_name);
|
||||
obstack_grow (obstack, buffer, strlen (buffer));
|
||||
/* Otherwise, if we see -shared, then use the shared version. */
|
||||
sprintf (buffer,
|
||||
"%%{!shared-libgcc:%%{!static-libgcc:%%{shared:%s %s}}}",
|
||||
shared_name, static_name);
|
||||
/* Otherwise, if we see -shared, then use the shared version
|
||||
if using EH registration routines or static version without
|
||||
exception handling routines otherwise. */
|
||||
p = "%{!shared-libgcc:%{!static-libgcc:%{shared:";
|
||||
obstack_grow (obstack, p, strlen (p));
|
||||
#ifdef LINK_EH_SPEC
|
||||
sprintf (buffer, "%s}}}", static_name);
|
||||
#else
|
||||
sprintf (buffer, "%s %s}}}", shared_name, static_name);
|
||||
#endif
|
||||
obstack_grow (obstack, buffer, strlen (buffer));
|
||||
/* Otherwise, use the static version. */
|
||||
sprintf (buffer,
|
||||
"%%{!shared-libgcc:%%{!static-libgcc:%%{!shared:%s}}}",
|
||||
static_name);
|
||||
"%%{!shared-libgcc:%%{!static-libgcc:%%{!shared:%s %s}}}",
|
||||
static_name, eh_name);
|
||||
obstack_grow (obstack, buffer, strlen (buffer));
|
||||
}
|
||||
#endif /* ENABLE_SHARED_LIBGCC */
|
||||
@ -1525,7 +1533,8 @@ init_spec ()
|
||||
"-lgcc_s%M"
|
||||
#endif
|
||||
,
|
||||
"-lgcc");
|
||||
"-lgcc",
|
||||
"-lgcc_eh");
|
||||
p += 5;
|
||||
in_sep = 0;
|
||||
}
|
||||
@ -1540,7 +1549,8 @@ init_spec ()
|
||||
"-lgcc_s%M"
|
||||
#endif
|
||||
,
|
||||
"libgcc.a%s");
|
||||
"libgcc.a%s",
|
||||
"libgcc_eh.a%s");
|
||||
p += 10;
|
||||
in_sep = 0;
|
||||
}
|
||||
@ -1565,6 +1575,12 @@ init_spec ()
|
||||
asm_spec = obstack_finish (&obstack);
|
||||
}
|
||||
#endif
|
||||
#ifdef LINK_EH_SPEC
|
||||
/* Prepend LINK_EH_SPEC to whatever link_spec we had before. */
|
||||
obstack_grow (&obstack, LINK_EH_SPEC, sizeof(LINK_EH_SPEC) - 1);
|
||||
obstack_grow0 (&obstack, link_spec, strlen (link_spec));
|
||||
link_spec = obstack_finish (&obstack);
|
||||
#endif
|
||||
|
||||
specs = sl;
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ done
|
||||
|
||||
libgcc2_objs=""
|
||||
libgcc2_st_objs=""
|
||||
libgcc2_eh_objs=""
|
||||
|
||||
for name in $LIB2FUNCS; do
|
||||
for ml in $MULTILIBS; do
|
||||
@ -200,7 +201,11 @@ for file in $LIB2ADDEH; do
|
||||
echo $out: stmp-dirs $file
|
||||
echo " $gcc_compile" $flags -fexceptions -c $file -o $out
|
||||
done
|
||||
libgcc2_objs="$libgcc2_objs ${oname}${objext}"
|
||||
if [ "$SHLIB_LINK" ]; then
|
||||
libgcc2_eh_objs="$libgcc2_eh_objs ${oname}${objext}"
|
||||
else
|
||||
libgcc2_objs="$libgcc2_objs ${oname}${objext}"
|
||||
fi
|
||||
done
|
||||
|
||||
for file in $LIB2ADD_ST; do
|
||||
@ -228,13 +233,18 @@ for ml in $MULTILIBS; do
|
||||
flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
|
||||
|
||||
libgcc_objs=""
|
||||
libgcc_eh_objs=""
|
||||
for o in $libgcc1_objs; do
|
||||
libgcc_objs="$libgcc_objs libgcc/${dir}/$o"
|
||||
done
|
||||
for o in $libgcc2_objs; do
|
||||
libgcc_objs="$libgcc_objs libgcc/${dir}/$o"
|
||||
done
|
||||
shlib_deps="$libgcc_objs"
|
||||
for o in $libgcc2_eh_objs; do
|
||||
libgcc_eh_objs="$libgcc_eh_objs libgcc/${dir}/$o"
|
||||
done
|
||||
libgcc_sh_objs="$libgcc_objs $libgcc_eh_objs"
|
||||
shlib_deps="$libgcc_sh_objs"
|
||||
|
||||
libgcc_st_objs=""
|
||||
for o in $libgcc2_st_objs; do
|
||||
@ -244,8 +254,8 @@ for ml in $MULTILIBS; do
|
||||
if [ "$SHLIB_LINK" -a "$SHLIB_MKMAP" -a -z "$mapfile" ]; then
|
||||
mapfile="libgcc.map"
|
||||
echo ""
|
||||
echo "${mapfile}: $SHLIB_MKMAP $SHLIB_MAPFILES $libgcc_objs"
|
||||
echo ' { $(NM_FOR_TARGET)'" $SHLIB_NM_FLAGS $libgcc_objs; echo %%; cat $SHLIB_MAPFILES; } | "'$(AWK)'" -f $SHLIB_MKMAP > "'tmp-$@'
|
||||
echo "${mapfile}: $SHLIB_MKMAP $SHLIB_MAPFILES $libgcc_sh_objs"
|
||||
echo ' { $(NM_FOR_TARGET)'" $SHLIB_NM_FLAGS $libgcc_sh_objs; echo %%; cat $SHLIB_MAPFILES; } | "'$(AWK)'" -f $SHLIB_MKMAP > "'tmp-$@'
|
||||
echo ' mv tmp-$@ $@'
|
||||
fi
|
||||
shlib_deps="$shlib_deps $mapfile"
|
||||
@ -265,6 +275,15 @@ for ml in $MULTILIBS; do
|
||||
echo ' else true; fi;'
|
||||
|
||||
if [ "$SHLIB_LINK" ]; then
|
||||
|
||||
echo ""
|
||||
echo "${dir}/libgcc_eh.a: $libgcc_eh_objs"
|
||||
echo " -rm -rf ${dir}/libgcc_eh.a"
|
||||
echo ' $(AR_CREATE_FOR_TARGET)' ${dir}/libgcc_eh.a $libgcc_eh_objs
|
||||
echo ' if $(RANLIB_TEST_FOR_TARGET) ; then' \\
|
||||
echo ' $(RANLIB_FOR_TARGET)' ${dir}/libgcc_eh.a ';' \\
|
||||
echo ' else true; fi;'
|
||||
|
||||
if [ -z "$SHLIB_MULTILIB" ]; then
|
||||
if [ "$dir" = "." ]; then
|
||||
shlib_base_name="libgcc_s";
|
||||
@ -276,7 +295,7 @@ for ml in $MULTILIBS; do
|
||||
echo " $SHLIB_LINK" \
|
||||
| sed -e "s%@multilib_flags@%$flags%g" \
|
||||
-e "s%@multilib_dir@%$dir%g" \
|
||||
-e "s%@shlib_objs@%$libgcc_objs%g" \
|
||||
-e "s%@shlib_objs@%$libgcc_sh_objs%g" \
|
||||
-e "s%@shlib_base_name@%$shlib_base_name%g" \
|
||||
-e "s%@shlib_map_file@%$mapfile%g"
|
||||
elif [ "$SHLIB_MULTILIB" = "$dir" ]; then
|
||||
@ -286,7 +305,7 @@ for ml in $MULTILIBS; do
|
||||
echo " $SHLIB_LINK" \
|
||||
| sed -e "s%@multilib_flags@%$flags%g" \
|
||||
-e "s%@multilib_dir@%$dir%g" \
|
||||
-e "s%@shlib_objs@%$libgcc_objs%g" \
|
||||
-e "s%@shlib_objs@%$libgcc_sh_objs%g" \
|
||||
-e "s%@shlib_base_name@%$shlib_base_name%g" \
|
||||
-e "s%@shlib_map_file@%$mapfile%g"
|
||||
fi
|
||||
@ -320,6 +339,7 @@ for ml in $MULTILIBS; do
|
||||
fi
|
||||
all="$all ${dir}/libgcc.a"
|
||||
if [ "$SHLIB_LINK" ]; then
|
||||
all="$all ${dir}/libgcc_eh.a"
|
||||
if [ -z "$SHLIB_MULTILIB" ]; then
|
||||
if [ "$dir" = "." ]; then
|
||||
suff="";
|
||||
@ -379,6 +399,9 @@ for ml in $MULTILIBS; do
|
||||
echo ' $(RANLIB_FOR_TARGET)' ${ldir}/libgcc.a
|
||||
|
||||
if [ "$SHLIB_LINK" ]; then
|
||||
echo ' $(INSTALL_DATA)' ${dir}/libgcc_eh.a ${ldir}/
|
||||
echo ' $(RANLIB_FOR_TARGET)' ${ldir}/libgcc_eh.a
|
||||
|
||||
if [ -z "$SHLIB_MULTILIB" ]; then
|
||||
if [ "$dir" = "." ]; then
|
||||
shlib_base_name="libgcc_s";
|
||||
|
291
gcc/unwind-dw2-fde-glibc.c
Normal file
291
gcc/unwind-dw2-fde-glibc.c
Normal file
@ -0,0 +1,291 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with other files,
|
||||
some of which are compiled with GCC, to produce an executable,
|
||||
this library does not by itself cause the resulting executable
|
||||
to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
/* Locate the FDE entry for a given address, using PT_GNU_EH_FRAME ELF
|
||||
segment and dl_iterate_phdr to avoid register/deregister calls at
|
||||
DSO load/unload. */
|
||||
|
||||
#include "auto-host.h" /* For HAVE_LD_EH_FRAME_HDR. */
|
||||
#include "tconfig.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <link.h>
|
||||
#include "tsystem.h"
|
||||
#include "dwarf2.h"
|
||||
#include "unwind.h"
|
||||
#define NO_BASE_OF_ENCODED_VALUE
|
||||
#include "unwind-pe.h"
|
||||
#include "unwind-dw2-fde.h"
|
||||
#include "gthr.h"
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR) \
|
||||
&& (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
|
||||
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
|
||||
|
||||
static fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases *bases);
|
||||
|
||||
#define _Unwind_Find_FDE _Unwind_Find_registered_FDE
|
||||
#include "unwind-dw2-fde.c"
|
||||
#undef _Unwind_Find_FDE
|
||||
|
||||
#ifndef PT_GNU_EH_FRAME
|
||||
#define PT_GNU_EH_FRAME (PT_LOOS + 0x474e550)
|
||||
#endif
|
||||
|
||||
struct unw_eh_callback_data
|
||||
{
|
||||
_Unwind_Ptr pc;
|
||||
void *tbase;
|
||||
void *dbase;
|
||||
void *func;
|
||||
fde *ret;
|
||||
};
|
||||
|
||||
struct unw_eh_frame_hdr
|
||||
{
|
||||
unsigned char version;
|
||||
unsigned char eh_frame_ptr_enc;
|
||||
unsigned char fde_count_enc;
|
||||
unsigned char table_enc;
|
||||
};
|
||||
|
||||
/* Like base_of_encoded_value, but take the base from a struct object
|
||||
instead of an _Unwind_Context. */
|
||||
|
||||
static _Unwind_Ptr
|
||||
base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data)
|
||||
{
|
||||
if (encoding == DW_EH_PE_omit)
|
||||
return 0;
|
||||
|
||||
switch (encoding & 0x70)
|
||||
{
|
||||
case DW_EH_PE_absptr:
|
||||
case DW_EH_PE_pcrel:
|
||||
case DW_EH_PE_aligned:
|
||||
return 0;
|
||||
|
||||
case DW_EH_PE_textrel:
|
||||
return (_Unwind_Ptr) data->tbase;
|
||||
case DW_EH_PE_datarel:
|
||||
return (_Unwind_Ptr) data->dbase;
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
|
||||
static int
|
||||
_Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
{
|
||||
struct unw_eh_callback_data *data = (struct unw_eh_callback_data *) ptr;
|
||||
const ElfW(Phdr) *phdr, *p_eh_frame_hdr, *p_dynamic;
|
||||
long n, match;
|
||||
_Unwind_Ptr load_base;
|
||||
const unsigned char *p;
|
||||
const struct unw_eh_frame_hdr *hdr;
|
||||
_Unwind_Ptr eh_frame;
|
||||
struct object ob;
|
||||
|
||||
/* Make sure struct dl_phdr_info is at least as big as we need. */
|
||||
if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
|
||||
+ sizeof (info->dlpi_phnum))
|
||||
return -1;
|
||||
|
||||
match = 0;
|
||||
phdr = info->dlpi_phdr;
|
||||
load_base = info->dlpi_addr;
|
||||
p_eh_frame_hdr = NULL;
|
||||
p_dynamic = NULL;
|
||||
|
||||
/* See if PC falls into one of the loaded segments. Find the eh_frame
|
||||
segment at the same time. */
|
||||
for (n = info->dlpi_phnum; --n >= 0; phdr++)
|
||||
{
|
||||
if (phdr->p_type == PT_LOAD)
|
||||
{
|
||||
_Unwind_Ptr vaddr = phdr->p_vaddr + load_base;
|
||||
if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz)
|
||||
match = 1;
|
||||
}
|
||||
else if (phdr->p_type == PT_GNU_EH_FRAME)
|
||||
p_eh_frame_hdr = phdr;
|
||||
else if (phdr->p_type == PT_DYNAMIC)
|
||||
p_dynamic = phdr;
|
||||
}
|
||||
if (!match || !p_eh_frame_hdr)
|
||||
return 0;
|
||||
|
||||
/* Read .eh_frame_hdr header. */
|
||||
hdr = (const struct unw_eh_frame_hdr *)
|
||||
(p_eh_frame_hdr->p_vaddr + load_base);
|
||||
if (hdr->version != 1)
|
||||
return 1;
|
||||
|
||||
#ifdef CRT_GET_RFIB_DATA
|
||||
# ifdef __i386__
|
||||
data->dbase = NULL;
|
||||
if (p_dynamic)
|
||||
{
|
||||
/* For dynamicly linked executables and shared libraries,
|
||||
DT_PLTGOT is the gp value for that object. */
|
||||
ElfW(Dyn) *dyn = (ElfW(Dyn) *)(p_dynamic->p_vaddr + load_base);
|
||||
for (; dyn->d_tag != DT_NULL ; dyn++)
|
||||
if (dyn->d_tag == DT_PLTGOT)
|
||||
{
|
||||
/* On IA-32, _DYNAMIC is writable and GLIBC has relocated it. */
|
||||
data->dbase = (void *) dyn->d_un.d_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
# else
|
||||
# error What is DW_EH_PE_datarel base on this platform?
|
||||
# endif
|
||||
#endif
|
||||
#ifdef CRT_GET_RFIB_TEXT
|
||||
# error What is DW_EH_PE_textrel base on this platform?
|
||||
#endif
|
||||
|
||||
p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc,
|
||||
base_from_cb_data (hdr->eh_frame_ptr_enc,
|
||||
data),
|
||||
(const unsigned char *) (hdr + 1),
|
||||
&eh_frame);
|
||||
|
||||
/* We require here specific table encoding to speed things up.
|
||||
Also, DW_EH_PE_datarel here means using PT_GNU_EH_FRAME start
|
||||
as base, not the processor specific DW_EH_PE_datarel. */
|
||||
if (hdr->fde_count_enc != DW_EH_PE_omit
|
||||
&& hdr->table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
|
||||
{
|
||||
_Unwind_Ptr fde_count;
|
||||
|
||||
p = read_encoded_value_with_base (hdr->fde_count_enc,
|
||||
base_from_cb_data (hdr->fde_count_enc,
|
||||
data),
|
||||
p, &fde_count);
|
||||
/* Shouldn't happen. */
|
||||
if (fde_count == 0)
|
||||
return 1;
|
||||
if ((((_Unwind_Ptr) p) & 3) == 0)
|
||||
{
|
||||
struct fde_table {
|
||||
signed initial_loc __attribute__ ((mode (SI)));
|
||||
signed fde __attribute__ ((mode (SI)));
|
||||
};
|
||||
const struct fde_table *table = (const struct fde_table *) p;
|
||||
size_t lo, hi, mid;
|
||||
_Unwind_Ptr data_base = (_Unwind_Ptr) hdr;
|
||||
fde *f;
|
||||
unsigned int f_enc, f_enc_size;
|
||||
_Unwind_Ptr range;
|
||||
|
||||
mid = fde_count - 1;
|
||||
if (data->pc < table[0].initial_loc + data_base)
|
||||
return 1;
|
||||
else if (data->pc < table[mid].initial_loc + data_base)
|
||||
{
|
||||
lo = 0;
|
||||
hi = mid;
|
||||
|
||||
while (lo < hi)
|
||||
{
|
||||
mid = (lo + hi) / 2;
|
||||
if (data->pc < table[mid].initial_loc + data_base)
|
||||
hi = mid;
|
||||
else if (data->pc >= table[mid + 1].initial_loc + data_base)
|
||||
lo = mid + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (lo >= hi)
|
||||
__gxx_abort ();
|
||||
}
|
||||
|
||||
f = (fde *) (table[mid].fde + data_base);
|
||||
f_enc = get_fde_encoding (f);
|
||||
f_enc_size = size_of_encoded_value (f_enc);
|
||||
read_encoded_value_with_base (f_enc & 0x0f, 0,
|
||||
&f->pc_begin[f_enc_size], &range);
|
||||
if (data->pc < table[mid].initial_loc + data_base + range)
|
||||
data->ret = f;
|
||||
data->func = (void *) (table[mid].initial_loc + data_base);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* We have no sorted search table, so need to go the slow way.
|
||||
As soon as GLIBC will provide API so to notify that a library has been
|
||||
removed, we could cache this (and thus use search_object). */
|
||||
ob.pc_begin = NULL;
|
||||
ob.tbase = data->tbase;
|
||||
ob.dbase = data->dbase;
|
||||
ob.u.single = (fde *) eh_frame;
|
||||
ob.s.i = 0;
|
||||
ob.s.b.mixed_encoding = 1; /* Need to assume worst case. */
|
||||
data->ret = linear_search_fdes (&ob, (fde *) eh_frame, (void *) data->pc);
|
||||
if (data->ret != NULL)
|
||||
{
|
||||
unsigned int encoding = get_fde_encoding (data->ret);
|
||||
read_encoded_value_with_base (encoding,
|
||||
base_from_cb_data (encoding, data),
|
||||
data->ret->pc_begin,
|
||||
(_Unwind_Ptr *)&data->func);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
fde *
|
||||
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
{
|
||||
struct unw_eh_callback_data data;
|
||||
fde *ret;
|
||||
|
||||
ret = _Unwind_Find_registered_FDE (pc, bases);
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
|
||||
data.pc = (_Unwind_Ptr) pc;
|
||||
data.tbase = NULL;
|
||||
data.dbase = NULL;
|
||||
data.func = NULL;
|
||||
data.ret = NULL;
|
||||
|
||||
if (dl_iterate_phdr (_Unwind_IteratePhdrCallback, &data) < 0)
|
||||
return NULL;
|
||||
|
||||
if (data.ret)
|
||||
{
|
||||
bases->tbase = data.tbase;
|
||||
bases->dbase = data.dbase;
|
||||
bases->func = data.func;
|
||||
}
|
||||
return data.ret;
|
||||
}
|
||||
|
||||
#else
|
||||
#include "unwind-dw2-fde.c"
|
||||
#endif
|
@ -28,6 +28,7 @@ along with GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#ifndef _Unwind_Find_FDE
|
||||
#include "tconfig.h"
|
||||
#include "tsystem.h"
|
||||
#include "dwarf2.h"
|
||||
@ -36,6 +37,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "unwind-pe.h"
|
||||
#include "unwind-dw2-fde.h"
|
||||
#include "gthr.h"
|
||||
#endif
|
||||
|
||||
/* The unseen_objects list contains objects that have been registered
|
||||
but not yet categorized in any way. The seen_objects list has had
|
||||
|
Loading…
Reference in New Issue
Block a user