diff options
Diffstat (limited to 'newlib/libc/sys/linux/dl')
41 files changed, 0 insertions, 9967 deletions
diff --git a/newlib/libc/sys/linux/dl/Makefile.am b/newlib/libc/sys/linux/dl/Makefile.am deleted file mode 100644 index d4a2fa636..000000000 --- a/newlib/libc/sys/linux/dl/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -## Process this file with automake to generate Makefile.in - -AUTOMAKE_OPTIONS = cygnus - -INCLUDES = -DSHARED -D_GNU_SOURCE $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -I$(srcdir)/.. - -LIB_SOURCES = \ - dl-addr.c dl-deps.c dl-init.c dl-load.c dl-misc.c dl-profile.c dl-runtime.c dl-version.c \ - dl-close.c dl-error.c dl-iteratephdr.c dl-lookup.c dl-object.c dl-profstub.c dl-support.c \ - dl-debug.c dl-fini.c dl-libc.c dl-open.c dl-reloc.c dl-sym.c dl-cache.c - -AM_CFLAGS = -D_GNU_SOURCE -D__strerror_r=strerror_r -libdl_la_LDFLAGS = -Xcompiler -nostdlib - -if USE_LIBTOOL -noinst_LTLIBRARIES = libdl.la -libdl_la_SOURCES = $(LIB_SOURCES) -noinst_DATA = objectlist.awk.in -else -noinst_LIBRARIES = lib.a -lib_a_SOURCES = $(LIB_SOURCES) -lib_a_CFLAGS = $(AM_CFLAGS) -noinst_DATA = -endif # USE_LIBTOOL - -include $(srcdir)/../../../../Makefile.shared diff --git a/newlib/libc/sys/linux/dl/Makefile.in b/newlib/libc/sys/linux/dl/Makefile.in deleted file mode 100644 index d32972fd9..000000000 --- a/newlib/libc/sys/linux/dl/Makefile.in +++ /dev/null @@ -1,610 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = .. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -DIST_COMMON = $(srcdir)/../../../../Makefile.shared \ - $(srcdir)/Makefile.in $(srcdir)/Makefile.am -subdir = dl -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../../../../libtool.m4 \ - $(top_srcdir)/../../../../ltoptions.m4 \ - $(top_srcdir)/../../../../ltsugar.m4 \ - $(top_srcdir)/../../../../ltversion.m4 \ - $(top_srcdir)/../../../../lt~obsolete.m4 \ - $(top_srcdir)/../../../acinclude.m4 \ - $(top_srcdir)/../../../confsubdir.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs -CONFIG_CLEAN_FILES = -LIBRARIES = $(noinst_LIBRARIES) -ARFLAGS = cru -lib_a_AR = $(AR) $(ARFLAGS) -lib_a_LIBADD = -am__objects_1 = lib_a-dl-addr.$(OBJEXT) lib_a-dl-deps.$(OBJEXT) \ - lib_a-dl-init.$(OBJEXT) lib_a-dl-load.$(OBJEXT) \ - lib_a-dl-misc.$(OBJEXT) lib_a-dl-profile.$(OBJEXT) \ - lib_a-dl-runtime.$(OBJEXT) lib_a-dl-version.$(OBJEXT) \ - lib_a-dl-close.$(OBJEXT) lib_a-dl-error.$(OBJEXT) \ - lib_a-dl-iteratephdr.$(OBJEXT) lib_a-dl-lookup.$(OBJEXT) \ - lib_a-dl-object.$(OBJEXT) lib_a-dl-profstub.$(OBJEXT) \ - lib_a-dl-support.$(OBJEXT) lib_a-dl-debug.$(OBJEXT) \ - lib_a-dl-fini.$(OBJEXT) lib_a-dl-libc.$(OBJEXT) \ - lib_a-dl-open.$(OBJEXT) lib_a-dl-reloc.$(OBJEXT) \ - lib_a-dl-sym.$(OBJEXT) lib_a-dl-cache.$(OBJEXT) -@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) -lib_a_OBJECTS = $(am_lib_a_OBJECTS) -LTLIBRARIES = $(noinst_LTLIBRARIES) -libdl_la_LIBADD = -am__objects_2 = dl-addr.lo dl-deps.lo dl-init.lo dl-load.lo dl-misc.lo \ - dl-profile.lo dl-runtime.lo dl-version.lo dl-close.lo \ - dl-error.lo dl-iteratephdr.lo dl-lookup.lo dl-object.lo \ - dl-profstub.lo dl-support.lo dl-debug.lo dl-fini.lo dl-libc.lo \ - dl-open.lo dl-reloc.lo dl-sym.lo dl-cache.lo -@USE_LIBTOOL_TRUE@am_libdl_la_OBJECTS = $(am__objects_2) -libdl_la_OBJECTS = $(am_libdl_la_OBJECTS) -@USE_LIBTOOL_TRUE@am_libdl_la_rpath = -DEFAULT_INCLUDES = -I. -I$(srcdir) -depcomp = -am__depfiles_maybe = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(lib_a_SOURCES) $(libdl_la_SOURCES) -DATA = $(noinst_DATA) -ETAGS = etags -CTAGS = ctags -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCAS = @CCAS@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ELIX_LEVEL_0_FALSE = @ELIX_LEVEL_0_FALSE@ -ELIX_LEVEL_0_TRUE = @ELIX_LEVEL_0_TRUE@ -ELIX_LEVEL_1_FALSE = @ELIX_LEVEL_1_FALSE@ -ELIX_LEVEL_1_TRUE = @ELIX_LEVEL_1_TRUE@ -ELIX_LEVEL_2_FALSE = @ELIX_LEVEL_2_FALSE@ -ELIX_LEVEL_2_TRUE = @ELIX_LEVEL_2_TRUE@ -ELIX_LEVEL_3_FALSE = @ELIX_LEVEL_3_FALSE@ -ELIX_LEVEL_3_TRUE = @ELIX_LEVEL_3_TRUE@ -ELIX_LEVEL_4_FALSE = @ELIX_LEVEL_4_FALSE@ -ELIX_LEVEL_4_TRUE = @ELIX_LEVEL_4_TRUE@ -EXEEXT = @EXEEXT@ -EXTRA_SUBDIRS = @EXTRA_SUBDIRS@ -EXTRA_SUBLIBS = @EXTRA_SUBLIBS@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LINUX_MACH_LIB = @LINUX_MACH_LIB@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ -MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ -MAKEINFO = @MAKEINFO@ -MAY_SUPPLY_SYSCALLS_FALSE = @MAY_SUPPLY_SYSCALLS_FALSE@ -MAY_SUPPLY_SYSCALLS_TRUE = @MAY_SUPPLY_SYSCALLS_TRUE@ -NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -READELF = @READELF@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -USE_LIBTOOL_FALSE = @USE_LIBTOOL_FALSE@ -USE_LIBTOOL_TRUE = @USE_LIBTOOL_TRUE@ -VERSION = @VERSION@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_AS = @ac_ct_AS@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DLLTOOL = @ac_ct_DLLTOOL@ -ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -ac_ct_LIPO = @ac_ct_LIPO@ -ac_ct_NMEDIT = @ac_ct_NMEDIT@ -ac_ct_OBJDUMP = @ac_ct_OBJDUMP@ -ac_ct_OTOOL = @ac_ct_OTOOL@ -ac_ct_OTOOL64 = @ac_ct_OTOOL64@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_READELF = @ac_ct_READELF@ -ac_ct_STRIP = @ac_ct_STRIP@ -aext = @aext@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -datadir = @datadir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -libm_machine_dir = @libm_machine_dir@ -localstatedir = @localstatedir@ -lpfx = @lpfx@ -lt_ECHO = @lt_ECHO@ -machine_dir = @machine_dir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -newlib_basedir = @newlib_basedir@ -oext = @oext@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -subdirs = @subdirs@ -sys_dir = @sys_dir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -AUTOMAKE_OPTIONS = cygnus -INCLUDES = -DSHARED -D_GNU_SOURCE $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -I$(srcdir)/.. -LIB_SOURCES = \ - dl-addr.c dl-deps.c dl-init.c dl-load.c dl-misc.c dl-profile.c dl-runtime.c dl-version.c \ - dl-close.c dl-error.c dl-iteratephdr.c dl-lookup.c dl-object.c dl-profstub.c dl-support.c \ - dl-debug.c dl-fini.c dl-libc.c dl-open.c dl-reloc.c dl-sym.c dl-cache.c - -AM_CFLAGS = -D_GNU_SOURCE -D__strerror_r=strerror_r -libdl_la_LDFLAGS = -Xcompiler -nostdlib -@USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = libdl.la -@USE_LIBTOOL_TRUE@libdl_la_SOURCES = $(LIB_SOURCES) -@USE_LIBTOOL_FALSE@noinst_DATA = -@USE_LIBTOOL_TRUE@noinst_DATA = objectlist.awk.in -@USE_LIBTOOL_FALSE@noinst_LIBRARIES = lib.a -@USE_LIBTOOL_FALSE@lib_a_SOURCES = $(LIB_SOURCES) -@USE_LIBTOOL_FALSE@lib_a_CFLAGS = $(AM_CFLAGS) -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../../../../Makefile.shared $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus dl/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --cygnus dl/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) - -rm -f lib.a - $(lib_a_AR) lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) - $(RANLIB) lib.a - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libdl.la: $(libdl_la_OBJECTS) $(libdl_la_DEPENDENCIES) - $(LINK) $(am_libdl_la_rpath) $(libdl_la_LDFLAGS) $(libdl_la_OBJECTS) $(libdl_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -.c.o: - $(COMPILE) -c $< - -.c.obj: - $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: - $(LTCOMPILE) -c -o $@ $< - -lib_a-dl-addr.o: dl-addr.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-addr.o `test -f 'dl-addr.c' || echo '$(srcdir)/'`dl-addr.c - -lib_a-dl-addr.obj: dl-addr.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-addr.obj `if test -f 'dl-addr.c'; then $(CYGPATH_W) 'dl-addr.c'; else $(CYGPATH_W) '$(srcdir)/dl-addr.c'; fi` - -lib_a-dl-deps.o: dl-deps.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-deps.o `test -f 'dl-deps.c' || echo '$(srcdir)/'`dl-deps.c - -lib_a-dl-deps.obj: dl-deps.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-deps.obj `if test -f 'dl-deps.c'; then $(CYGPATH_W) 'dl-deps.c'; else $(CYGPATH_W) '$(srcdir)/dl-deps.c'; fi` - -lib_a-dl-init.o: dl-init.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-init.o `test -f 'dl-init.c' || echo '$(srcdir)/'`dl-init.c - -lib_a-dl-init.obj: dl-init.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-init.obj `if test -f 'dl-init.c'; then $(CYGPATH_W) 'dl-init.c'; else $(CYGPATH_W) '$(srcdir)/dl-init.c'; fi` - -lib_a-dl-load.o: dl-load.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-load.o `test -f 'dl-load.c' || echo '$(srcdir)/'`dl-load.c - -lib_a-dl-load.obj: dl-load.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-load.obj `if test -f 'dl-load.c'; then $(CYGPATH_W) 'dl-load.c'; else $(CYGPATH_W) '$(srcdir)/dl-load.c'; fi` - -lib_a-dl-misc.o: dl-misc.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-misc.o `test -f 'dl-misc.c' || echo '$(srcdir)/'`dl-misc.c - -lib_a-dl-misc.obj: dl-misc.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-misc.obj `if test -f 'dl-misc.c'; then $(CYGPATH_W) 'dl-misc.c'; else $(CYGPATH_W) '$(srcdir)/dl-misc.c'; fi` - -lib_a-dl-profile.o: dl-profile.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-profile.o `test -f 'dl-profile.c' || echo '$(srcdir)/'`dl-profile.c - -lib_a-dl-profile.obj: dl-profile.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-profile.obj `if test -f 'dl-profile.c'; then $(CYGPATH_W) 'dl-profile.c'; else $(CYGPATH_W) '$(srcdir)/dl-profile.c'; fi` - -lib_a-dl-runtime.o: dl-runtime.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-runtime.o `test -f 'dl-runtime.c' || echo '$(srcdir)/'`dl-runtime.c - -lib_a-dl-runtime.obj: dl-runtime.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-runtime.obj `if test -f 'dl-runtime.c'; then $(CYGPATH_W) 'dl-runtime.c'; else $(CYGPATH_W) '$(srcdir)/dl-runtime.c'; fi` - -lib_a-dl-version.o: dl-version.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-version.o `test -f 'dl-version.c' || echo '$(srcdir)/'`dl-version.c - -lib_a-dl-version.obj: dl-version.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-version.obj `if test -f 'dl-version.c'; then $(CYGPATH_W) 'dl-version.c'; else $(CYGPATH_W) '$(srcdir)/dl-version.c'; fi` - -lib_a-dl-close.o: dl-close.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-close.o `test -f 'dl-close.c' || echo '$(srcdir)/'`dl-close.c - -lib_a-dl-close.obj: dl-close.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-close.obj `if test -f 'dl-close.c'; then $(CYGPATH_W) 'dl-close.c'; else $(CYGPATH_W) '$(srcdir)/dl-close.c'; fi` - -lib_a-dl-error.o: dl-error.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-error.o `test -f 'dl-error.c' || echo '$(srcdir)/'`dl-error.c - -lib_a-dl-error.obj: dl-error.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-error.obj `if test -f 'dl-error.c'; then $(CYGPATH_W) 'dl-error.c'; else $(CYGPATH_W) '$(srcdir)/dl-error.c'; fi` - -lib_a-dl-iteratephdr.o: dl-iteratephdr.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-iteratephdr.o `test -f 'dl-iteratephdr.c' || echo '$(srcdir)/'`dl-iteratephdr.c - -lib_a-dl-iteratephdr.obj: dl-iteratephdr.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-iteratephdr.obj `if test -f 'dl-iteratephdr.c'; then $(CYGPATH_W) 'dl-iteratephdr.c'; else $(CYGPATH_W) '$(srcdir)/dl-iteratephdr.c'; fi` - -lib_a-dl-lookup.o: dl-lookup.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-lookup.o `test -f 'dl-lookup.c' || echo '$(srcdir)/'`dl-lookup.c - -lib_a-dl-lookup.obj: dl-lookup.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-lookup.obj `if test -f 'dl-lookup.c'; then $(CYGPATH_W) 'dl-lookup.c'; else $(CYGPATH_W) '$(srcdir)/dl-lookup.c'; fi` - -lib_a-dl-object.o: dl-object.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-object.o `test -f 'dl-object.c' || echo '$(srcdir)/'`dl-object.c - -lib_a-dl-object.obj: dl-object.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-object.obj `if test -f 'dl-object.c'; then $(CYGPATH_W) 'dl-object.c'; else $(CYGPATH_W) '$(srcdir)/dl-object.c'; fi` - -lib_a-dl-profstub.o: dl-profstub.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-profstub.o `test -f 'dl-profstub.c' || echo '$(srcdir)/'`dl-profstub.c - -lib_a-dl-profstub.obj: dl-profstub.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-profstub.obj `if test -f 'dl-profstub.c'; then $(CYGPATH_W) 'dl-profstub.c'; else $(CYGPATH_W) '$(srcdir)/dl-profstub.c'; fi` - -lib_a-dl-support.o: dl-support.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-support.o `test -f 'dl-support.c' || echo '$(srcdir)/'`dl-support.c - -lib_a-dl-support.obj: dl-support.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-support.obj `if test -f 'dl-support.c'; then $(CYGPATH_W) 'dl-support.c'; else $(CYGPATH_W) '$(srcdir)/dl-support.c'; fi` - -lib_a-dl-debug.o: dl-debug.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-debug.o `test -f 'dl-debug.c' || echo '$(srcdir)/'`dl-debug.c - -lib_a-dl-debug.obj: dl-debug.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-debug.obj `if test -f 'dl-debug.c'; then $(CYGPATH_W) 'dl-debug.c'; else $(CYGPATH_W) '$(srcdir)/dl-debug.c'; fi` - -lib_a-dl-fini.o: dl-fini.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-fini.o `test -f 'dl-fini.c' || echo '$(srcdir)/'`dl-fini.c - -lib_a-dl-fini.obj: dl-fini.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-fini.obj `if test -f 'dl-fini.c'; then $(CYGPATH_W) 'dl-fini.c'; else $(CYGPATH_W) '$(srcdir)/dl-fini.c'; fi` - -lib_a-dl-libc.o: dl-libc.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-libc.o `test -f 'dl-libc.c' || echo '$(srcdir)/'`dl-libc.c - -lib_a-dl-libc.obj: dl-libc.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-libc.obj `if test -f 'dl-libc.c'; then $(CYGPATH_W) 'dl-libc.c'; else $(CYGPATH_W) '$(srcdir)/dl-libc.c'; fi` - -lib_a-dl-open.o: dl-open.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-open.o `test -f 'dl-open.c' || echo '$(srcdir)/'`dl-open.c - -lib_a-dl-open.obj: dl-open.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-open.obj `if test -f 'dl-open.c'; then $(CYGPATH_W) 'dl-open.c'; else $(CYGPATH_W) '$(srcdir)/dl-open.c'; fi` - -lib_a-dl-reloc.o: dl-reloc.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-reloc.o `test -f 'dl-reloc.c' || echo '$(srcdir)/'`dl-reloc.c - -lib_a-dl-reloc.obj: dl-reloc.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-reloc.obj `if test -f 'dl-reloc.c'; then $(CYGPATH_W) 'dl-reloc.c'; else $(CYGPATH_W) '$(srcdir)/dl-reloc.c'; fi` - -lib_a-dl-sym.o: dl-sym.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-sym.o `test -f 'dl-sym.c' || echo '$(srcdir)/'`dl-sym.c - -lib_a-dl-sym.obj: dl-sym.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-sym.obj `if test -f 'dl-sym.c'; then $(CYGPATH_W) 'dl-sym.c'; else $(CYGPATH_W) '$(srcdir)/dl-sym.c'; fi` - -lib_a-dl-cache.o: dl-cache.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-cache.o `test -f 'dl-cache.c' || echo '$(srcdir)/'`dl-cache.c - -lib_a-dl-cache.obj: dl-cache.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-dl-cache.obj `if test -f 'dl-cache.c'; then $(CYGPATH_W) 'dl-cache.c'; else $(CYGPATH_W) '$(srcdir)/dl-cache.c'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -check-am: -check: check-am -all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(DATA) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ - clean-noinstLTLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ - ctags distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-exec install-exec-am install-info install-info-am \ - install-man install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-info-am - -objectlist.awk.in: $(noinst_LTLIBRARIES) - -rm -f objectlist.awk.in - for i in `ls *.lo` ; \ - do \ - echo $$i `pwd`/$$i >> objectlist.awk.in ; \ - done -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/newlib/libc/sys/linux/dl/abi-tag.h b/newlib/libc/sys/linux/dl/abi-tag.h deleted file mode 100644 index 85db374c6..000000000 --- a/newlib/libc/sys/linux/dl/abi-tag.h +++ /dev/null @@ -1,4 +0,0 @@ -#define __ABI_TAG_OS 0 -#ifndef __ABI_TAG_VERSION -# define __ABI_TAG_VERSION 2,0,0 -#endif diff --git a/newlib/libc/sys/linux/dl/atomicity.h b/newlib/libc/sys/linux/dl/atomicity.h deleted file mode 100644 index 3dbd00689..000000000 --- a/newlib/libc/sys/linux/dl/atomicity.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Low-level functions for atomic operations. ix86 version, x >= 4. - Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _ATOMICITY_H -#define _ATOMICITY_H 1 - - - -static inline uint32_t -__attribute__ ((unused)) -exchange_and_add (volatile uint32_t *mem, uint32_t val) -{ - register uint32_t result; - __asm__ __volatile__ ("lock; xaddl %0,%1" - : "=r" (result), "=m" (*mem) : "m" (val), "1" (*mem)); - return result; -} - -static inline void -__attribute__ ((unused)) -atomic_add (volatile uint32_t *mem, int val) -{ - __asm__ __volatile__ ("lock; addl %1,%0" - : "=m" (*mem) : "ir" (val), "m" (*mem)); -} - -static inline char -__attribute__ ((unused)) -compare_and_swap (volatile long int *p, long int oldval, long int newval) -{ - char ret; - long int readval; - - __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0" - : "=q" (ret), "=m" (*p), "=a" (readval) - : "r" (newval), "1" (*p), "a" (oldval)); - return ret; -} - -#endif /* atomicity.h */ diff --git a/newlib/libc/sys/linux/dl/dl-addr.c b/newlib/libc/sys/linux/dl/dl-addr.c deleted file mode 100644 index 23867491f..000000000 --- a/newlib/libc/sys/linux/dl/dl-addr.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Locate the shared object symbol nearest a given address. - Copyright (C) 1996-2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <dlfcn.h> -#include <stddef.h> -#include <ldsodefs.h> - -int -internal_function -_dl_addr (const void *address, Dl_info *info) -{ - const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address); - struct link_map *l, *match; - const ElfW(Sym) *symtab, *matchsym; - const char *strtab; - ElfW(Word) strtabsize; - - /* Find the highest-addressed object that ADDRESS is not below. */ - match = NULL; - for (l = _dl_loaded; l; l = l->l_next) - if (addr >= l->l_map_start && addr < l->l_map_end) - { - /* We know ADDRESS lies within L if in any shared object. - Make sure it isn't past the end of L's segments. */ - size_t n = l->l_phnum; - if (n > 0) - { - do - --n; - while (l->l_phdr[n].p_type != PT_LOAD); - if (addr >= (l->l_addr + - l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz)) - /* Off the end of the highest-addressed shared object. */ - continue; - } - - match = l; - break; - } - - if (match == NULL) - return 0; - - /* Now we know what object the address lies in. */ - info->dli_fname = match->l_name; - info->dli_fbase = (void *) match->l_addr; - - /* If this is the main program the information is incomplete. */ - if (__builtin_expect (info->dli_fbase == NULL, 0)) - { - info->dli_fname = _dl_argv[0]; - info->dli_fbase = (void *) match->l_map_start; - } - - symtab = (const void *) D_PTR (match, l_info[DT_SYMTAB]); - strtab = (const void *) D_PTR (match, l_info[DT_STRTAB]); - strtabsize = match->l_info[DT_STRSZ]->d_un.d_val; - - /* We assume that the string table follows the symbol table, because - there is no way in ELF to know the size of the dynamic symbol table!! */ - for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab) - if (addr >= match->l_addr + symtab->st_value - && ((symtab->st_size == 0 && addr == match->l_addr + symtab->st_value) - || addr < match->l_addr + symtab->st_value + symtab->st_size) - && symtab->st_name < strtabsize - && (matchsym == NULL || matchsym->st_value < symtab->st_value) - && (ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL - || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)) - matchsym = symtab; - - if (matchsym) - { - /* We found a symbol close by. Fill in its name and exact address. */ - info->dli_sname = strtab + matchsym->st_name; - info->dli_saddr = (void *) (match->l_addr + matchsym->st_value); - } - else - { - /* No symbol matches. We return only the containing object. */ - info->dli_sname = NULL; - info->dli_saddr = NULL; - } - - return 1; -} diff --git a/newlib/libc/sys/linux/dl/dl-cache.c b/newlib/libc/sys/linux/dl/dl-cache.c deleted file mode 100644 index 9511da13f..000000000 --- a/newlib/libc/sys/linux/dl/dl-cache.c +++ /dev/null @@ -1,271 +0,0 @@ -/* Support for reading /etc/ld.so.cache files written by Linux ldconfig. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <assert.h> -#include <unistd.h> -#include <ldsodefs.h> -#include <sys/mman.h> -#include <dl-cache.h> -#include <machine/dl-procinfo.h> -#include <machine/weakalias.h> - -extern const char *_dl_platform; - -#ifndef _DL_PLATFORMS_COUNT -# define _DL_PLATFORMS_COUNT 0 -#endif - -/* This is the starting address and the size of the mmap()ed file. */ -static struct cache_file *cache; -static struct cache_file_new *cache_new; -static size_t cachesize; - -/* 1 if cache_data + PTR points into the cache. */ -#define _dl_cache_verify_ptr(ptr) (ptr < cache_data_size) - -/* This is the cache ID we expect. Normally it is 3 for glibc linked - binaries. */ -int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID; - -#define SEARCH_CACHE(cache) \ -/* We use binary search since the table is sorted in the cache file. \ - The first matching entry in the table is returned. \ - It is important to use the same algorithm as used while generating \ - the cache file. */ \ -do \ - { \ - left = 0; \ - right = cache->nlibs - 1; \ - \ - while (left <= right) \ - { \ - __typeof__ (cache->libs[0].key) key; \ - \ - middle = (left + right) / 2; \ - \ - key = cache->libs[middle].key; \ - \ - /* Make sure string table indices are not bogus before using \ - them. */ \ - if (! _dl_cache_verify_ptr (key)) \ - { \ - cmpres = 1; \ - break; \ - } \ - \ - /* Actually compare the entry with the key. */ \ - cmpres = _dl_cache_libcmp (name, cache_data + key); \ - if (__builtin_expect (cmpres == 0, 0)) \ - { \ - /* Found it. LEFT now marks the last entry for which we \ - know the name is correct. */ \ - left = middle; \ - \ - /* There might be entries with this name before the one we \ - found. So we have to find the beginning. */ \ - while (middle > 0) \ - { \ - __typeof__ (cache->libs[0].key) key; \ - \ - key = cache->libs[middle - 1].key; \ - /* Make sure string table indices are not bogus before \ - using them. */ \ - if (! _dl_cache_verify_ptr (key) \ - /* Actually compare the entry. */ \ - || _dl_cache_libcmp (name, cache_data + key) != 0) \ - break; \ - --middle; \ - } \ - \ - do \ - { \ - int flags; \ - __typeof__ (cache->libs[0]) *lib = &cache->libs[middle]; \ - \ - /* Only perform the name test if necessary. */ \ - if (middle > left \ - /* We haven't seen this string so far. Test whether the \ - index is ok and whether the name matches. Otherwise \ - we are done. */ \ - && (! _dl_cache_verify_ptr (lib->key) \ - || (_dl_cache_libcmp (name, cache_data + lib->key) \ - != 0))) \ - break; \ - \ - flags = lib->flags; \ - if (_dl_cache_check_flags (flags) \ - && _dl_cache_verify_ptr (lib->value)) \ - { \ - if (best == NULL || flags == _dl_correct_cache_id) \ - { \ - HWCAP_CHECK; \ - best = cache_data + lib->value; \ - \ - if (flags == _dl_correct_cache_id) \ - /* We've found an exact match for the shared \ - object and no general `ELF' release. Stop \ - searching. */ \ - break; \ - } \ - } \ - } \ - while (++middle <= right); \ - break; \ - } \ - \ - if (cmpres < 0) \ - left = middle + 1; \ - else \ - right = middle - 1; \ - } \ - } \ -while (0) - - - -/* Look up NAME in ld.so.cache and return the file name stored there, - or null if none is found. */ - -const char * -internal_function -_dl_load_cache_lookup (const char *name) -{ - int left, right, middle; - int cmpres; - const char *cache_data; - uint32_t cache_data_size; - const char *best; - - if (cache == NULL) - { - /* Read the contents of the file. */ - void *file = _dl_sysdep_read_whole_file (LD_SO_CACHE, &cachesize, - PROT_READ); - - /* We can handle three different cache file formats here: - - the old libc5/glibc2.0/2.1 format - - the old format with the new format in it - - only the new format - The following checks if the cache contains any of these formats. */ - if (file != MAP_FAILED && cachesize > sizeof *cache - && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0) - { - size_t offset; - /* Looks ok. */ - cache = file; - - /* Check for new version. */ - offset = ALIGN_CACHE (sizeof (struct cache_file) - + cache->nlibs * sizeof (struct file_entry)); - - cache_new = (struct cache_file_new *) ((void *) cache + offset); - if (cachesize < (offset + sizeof (struct cache_file_new)) - || memcmp (cache_new->magic, CACHEMAGIC_VERSION_NEW, - sizeof CACHEMAGIC_VERSION_NEW - 1) != 0) - cache_new = (void *) -1; - } - else if (file != MAP_FAILED && cachesize > sizeof *cache_new - && memcmp (file, CACHEMAGIC_VERSION_NEW, - sizeof CACHEMAGIC_VERSION_NEW - 1) == 0) - { - cache_new = file; - cache = file; - } - else - { - if (file != MAP_FAILED) - munmap (file, cachesize); - cache = (void *) -1; - } - - assert (cache != NULL); - } - - if (cache == (void *) -1) - /* Previously looked for the cache file and didn't find it. */ - return NULL; - - best = NULL; - - if (cache_new != (void *) -1) - { - /* This file ends in static libraries where we don't have a hwcap. */ - unsigned long int *hwcap; - uint64_t platform; - #pragma weak _dl_hwcap - - /* This is where the strings start. */ - cache_data = (const char *) cache_new; - - /* Now we can compute how large the string table is. */ - cache_data_size = (const char *) cache + cachesize - cache_data; - - hwcap = &_dl_hwcap; - platform = _dl_string_platform (_dl_platform); - if (platform != -1) - platform = 1ULL << platform; - - /* Only accept hwcap if it's for the right platform. */ -#define HWCAP_CHECK \ - if (_dl_osversion && cache_new->libs[middle].osversion > _dl_osversion) \ - continue; \ - if (_DL_PLATFORMS_COUNT && platform != -1 \ - && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0 \ - && (lib->hwcap & _DL_HWCAP_PLATFORM) != platform) \ - continue; \ - if (hwcap \ - && ((lib->hwcap & *hwcap & ~_DL_HWCAP_PLATFORM) > *hwcap)) \ - continue - SEARCH_CACHE (cache_new); - } - else - { - /* This is where the strings start. */ - cache_data = (const char *) &cache->libs[cache->nlibs]; - - /* Now we can compute how large the string table is. */ - cache_data_size = (const char *) cache + cachesize - cache_data; - -#undef HWCAP_CHECK -#define HWCAP_CHECK do {} while (0) - SEARCH_CACHE (cache); - } - - /* Print our result if wanted. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0) && best != NULL) - _dl_debug_printf (" trying file=%s\n", best); - - return best; -} - -#ifndef MAP_COPY -/* If the system does not support MAP_COPY we cannot leave the file open - all the time since this would create problems when the file is replaced. - Therefore we provide this function to close the file and open it again - once needed. */ -void -_dl_unload_cache (void) -{ - if (cache != NULL && cache != (struct cache_file *) -1) - { - munmap (cache, cachesize); - cache = NULL; - } -} -#endif diff --git a/newlib/libc/sys/linux/dl/dl-cache.h b/newlib/libc/sys/linux/dl/dl-cache.h deleted file mode 100644 index 0699853e7..000000000 --- a/newlib/libc/sys/linux/dl/dl-cache.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Support for reading /etc/ld.so.cache files written by Linux ldconfig. - Copyright (C) 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <stdint.h> - -#ifndef _DL_CACHE_DEFAULT_ID -# define _DL_CACHE_DEFAULT_ID 3 -#endif - -#ifndef _dl_cache_check_flags -# define _dl_cache_check_flags(flags) \ - ((flags) == 1 || (flags) == _DL_CACHE_DEFAULT_ID) -#endif - -#ifndef SYSCONFDIR -# define SYSCONFDIR "/etc" -#endif - -#ifndef LD_SO_CACHE -# define LD_SO_CACHE SYSCONFDIR "/ld.so.cache" -#endif - -#define CACHEMAGIC "ld.so-1.7.0" - -/* libc5 and glibc 2.0/2.1 use the same format. For glibc 2.2 another - format has been added in a compatible way: - The beginning of the string table is used for the new table: - old_magic - nlibs - libs[0] - ... - libs[nlibs-1] - pad, new magic needs to be aligned - - this is string[0] for the old format - new magic - this is string[0] for the new format - newnlibs - ... - newlibs[0] - ... - newlibs[newnlibs-1] - string 1 - string 2 - ... -*/ -struct file_entry -{ - int flags; /* This is 1 for an ELF library. */ - unsigned int key, value; /* String table indices. */ -}; - -struct cache_file -{ - char magic[sizeof CACHEMAGIC - 1]; - unsigned int nlibs; - struct file_entry libs[0]; -}; - -#define CACHEMAGIC_NEW "glibc-ld.so.cache" -#define CACHE_VERSION "1.1" -#define CACHEMAGIC_VERSION_NEW CACHEMAGIC_NEW CACHE_VERSION - - -struct file_entry_new -{ - int32_t flags; /* This is 1 for an ELF library. */ - uint32_t key, value; /* String table indices. */ - uint32_t osversion; /* Required OS version. */ - uint64_t hwcap; /* Hwcap entry. */ -}; - -struct cache_file_new -{ - char magic[sizeof CACHEMAGIC_NEW - 1]; - char version[sizeof CACHE_VERSION - 1]; - uint32_t nlibs; /* Number of entries. */ - uint32_t len_strings; /* Size of string table. */ - uint32_t unused[5]; /* Leave space for future extensions - and align to 8 byte boundary. */ - struct file_entry_new libs[0]; /* Entries describing libraries. */ - /* After this the string table of size len_strings is found. */ -}; - -/* Used to align cache_file_new. */ -#define ALIGN_CACHE(addr) \ -(((addr) + __alignof__ (struct cache_file_new) -1) \ - & (~(__alignof__ (struct cache_file_new) - 1))) - -static int -_dl_cache_libcmp (const char *p1, const char *p2) -{ - while (*p1 != '\0') - { - if (*p1 >= '0' && *p1 <= '9') - { - if (*p2 >= '0' && *p2 <= '9') - { - /* Must compare this numerically. */ - int val1; - int val2; - - val1 = *p1++ - '0'; - val2 = *p2++ - '0'; - while (*p1 >= '0' && *p1 <= '9') - val1 = val1 * 10 + *p1++ - '0'; - while (*p2 >= '0' && *p2 <= '9') - val2 = val2 * 10 + *p2++ - '0'; - if (val1 != val2) - return val1 - val2; - } - else - return 1; - } - else if (*p2 >= '0' && *p2 <= '9') - return -1; - else if (*p1 != *p2) - return *p1 - *p2; - else - { - ++p1; - ++p2; - } - } - return *p1 - *p2; -} diff --git a/newlib/libc/sys/linux/dl/dl-close.c b/newlib/libc/sys/linux/dl/dl-close.c deleted file mode 100644 index ef53868d9..000000000 --- a/newlib/libc/sys/linux/dl/dl-close.c +++ /dev/null @@ -1,334 +0,0 @@ -/* Close a shared object opened by `_dl_open'. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <assert.h> -#include <dlfcn.h> -#include <libintl.h> -#include <stdlib.h> -#include <string.h> -#include <bits/libc-lock.h> -#include <ldsodefs.h> -#include <sys/types.h> -#include <sys/mman.h> - - -/* Type of the constructor functions. */ -typedef void (*fini_t) (void); - - -void -internal_function -_dl_close (void *_map) -{ - struct reldep_list - { - struct link_map **rellist; - unsigned int nrellist; - struct reldep_list *next; - } *reldeps = NULL; - struct link_map **list; - struct link_map *map = _map; - unsigned int i; - unsigned int *new_opencount; - - /* First see whether we can remove the object at all. */ - if (__builtin_expect (map->l_flags_1 & DF_1_NODELETE, 0) - && map->l_init_called) - /* Nope. Do nothing. */ - return; - - if (__builtin_expect (map->l_opencount, 1) == 0) - _dl_signal_error (0, map->l_name, NULL, N_("shared object not open")); - - /* Acquire the lock. */ -#ifdef HAVE_DD_LOCK - __lock_acquire(_dl_load_lock); -#endif - - - /* Decrement the reference count. */ - if (map->l_opencount > 1 || map->l_type != lt_loaded) - { - /* There are still references to this object. Do nothing more. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) - _dl_debug_printf ("\nclosing file=%s; opencount == %u\n", - map->l_name, map->l_opencount); - - /* One decrement the object itself, not the dependencies. */ - --map->l_opencount; - -#ifdef HAVE_DD_LOCK - __lock_release(_dl_load_lock); -#endif - - return; - } - - list = map->l_initfini; - - /* Compute the new l_opencount values. */ - i = map->l_searchlist.r_nlist; - if (__builtin_expect (i == 0, 0)) - /* This can happen if we handle relocation dependencies for an - object which wasn't loaded directly. */ - for (i = 1; list[i] != NULL; ++i) - ; - - new_opencount = (unsigned int *) alloca (i * sizeof (unsigned int)); - - for (i = 0; list[i] != NULL; ++i) - { - list[i]->l_idx = i; - new_opencount[i] = list[i]->l_opencount; - } - --new_opencount[0]; - for (i = 1; list[i] != NULL; ++i) - if ((! (list[i]->l_flags_1 & DF_1_NODELETE) || ! list[i]->l_init_called) - /* Decrement counter. */ - && --new_opencount[i] == 0 - /* Test whether this object was also loaded directly. */ - && list[i]->l_searchlist.r_list != NULL) - { - /* In this case we have the decrement all the dependencies of - this object. They are all in MAP's dependency list. */ - unsigned int j; - struct link_map **dep_list = list[i]->l_searchlist.r_list; - - for (j = 1; j < list[i]->l_searchlist.r_nlist; ++j) - if (! (dep_list[j]->l_flags_1 & DF_1_NODELETE) - || ! dep_list[j]->l_init_called) - { - assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist); - --new_opencount[dep_list[j]->l_idx]; - } - } - assert (new_opencount[0] == 0); - - /* Call all termination functions at once. */ - for (i = 0; list[i] != NULL; ++i) - { - struct link_map *imap = list[i]; - if (new_opencount[i] == 0 && imap->l_type == lt_loaded - && (imap->l_info[DT_FINI] || imap->l_info[DT_FINI_ARRAY]) - && (! (imap->l_flags_1 & DF_1_NODELETE) || ! imap->l_init_called) - /* Skip any half-cooked objects that were never initialized. */ - && imap->l_init_called) - { - /* When debugging print a message first. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) - _dl_debug_printf ("\ncalling fini: %s\n\n", imap->l_name); - - /* Call its termination function. */ - if (imap->l_info[DT_FINI_ARRAY] != NULL) - { - ElfW(Addr) *array = - (ElfW(Addr) *) (imap->l_addr - + imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr); - unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val - / sizeof (ElfW(Addr))); - unsigned int cnt; - - for (cnt = 0; cnt < sz; ++cnt) - ((fini_t) (imap->l_addr + array[cnt])) (); - } - - /* Next try the old-style destructor. */ - if (imap->l_info[DT_FINI] != NULL) - (*(void (*) (void)) DL_DT_FINI_ADDRESS - (imap, (void *) imap->l_addr - + imap->l_info[DT_FINI]->d_un.d_ptr)) (); - } - else if (new_opencount[i] != 0 && imap->l_type == lt_loaded) - { - /* The object is still used. But the object we are unloading - right now is responsible for loading it and therefore we - have the search list of the current object in its scope. - Remove it. */ - struct r_scope_elem **runp = imap->l_scope; - - while (*runp != NULL) - if (*runp == &map->l_searchlist) - { - /* Copy all later elements. */ - while ((runp[0] = runp[1]) != NULL) - ++runp; - break; - } - else - ++runp; - } - - /* Store the new l_opencount value. */ - imap->l_opencount = new_opencount[i]; - /* Just a sanity check. */ - assert (imap->l_type == lt_loaded || imap->l_opencount > 0); - } - - /* Notify the debugger we are about to remove some loaded objects. */ - _r_debug.r_state = RT_DELETE; - _dl_debug_state (); - - /* Check each element of the search list to see if all references to - it are gone. */ - for (i = 0; list[i] != NULL; ++i) - { - struct link_map *imap = list[i]; - if (imap->l_opencount == 0 && imap->l_type == lt_loaded) - { - struct libname_list *lnp; - - /* That was the last reference, and this was a dlopen-loaded - object. We can unmap it. */ - if (__builtin_expect (imap->l_global, 0)) - { - /* This object is in the global scope list. Remove it. */ - unsigned int cnt = _dl_main_searchlist->r_nlist; - - do - --cnt; - while (_dl_main_searchlist->r_list[cnt] != imap); - - /* The object was already correctly registered. */ - while (++cnt < _dl_main_searchlist->r_nlist) - _dl_main_searchlist->r_list[cnt - 1] - = _dl_main_searchlist->r_list[cnt]; - - --_dl_main_searchlist->r_nlist; - } - - /* We can unmap all the maps at once. We determined the - start address and length when we loaded the object and - the `munmap' call does the rest. */ - DL_UNMAP (imap); - - /* Finally, unlink the data structure and free it. */ -#ifdef SHARED - /* We will unlink the first object only if this is a statically - linked program. */ - assert (imap->l_prev != NULL); - imap->l_prev->l_next = imap->l_next; -#else - if (imap->l_prev != NULL) - imap->l_prev->l_next = imap->l_next; - else - _dl_loaded = imap->l_next; -#endif - --_dl_nloaded; - if (imap->l_next) - imap->l_next->l_prev = imap->l_prev; - - if (imap->l_versions != NULL) - free (imap->l_versions); - if (imap->l_origin != NULL && imap->l_origin != (char *) -1) - free ((char *) imap->l_origin); - - /* If the object has relocation dependencies save this - information for latter. */ - if (__builtin_expect (imap->l_reldeps != NULL, 0)) - { - struct reldep_list *newrel; - - newrel = (struct reldep_list *) alloca (sizeof (*reldeps)); - newrel->rellist = imap->l_reldeps; - newrel->nrellist = imap->l_reldepsact; - newrel->next = reldeps; - - reldeps = newrel; - } - - /* This name always is allocated. */ - free (imap->l_name); - /* Remove the list with all the names of the shared object. */ - lnp = imap->l_libname; - do - { - struct libname_list *this = lnp; - lnp = lnp->next; - if (!this->dont_free) - free (this); - } - while (lnp != NULL); - - /* Remove the searchlists. */ - if (imap != map) - free (imap->l_initfini); - - /* Remove the scope array if we allocated it. */ - if (imap->l_scope != imap->l_scope_mem) - free (imap->l_scope); - - if (imap->l_phdr_allocated) - free ((void *) imap->l_phdr); - - if (imap->l_rpath_dirs.dirs != (void *) -1) - free (imap->l_rpath_dirs.dirs); - if (imap->l_runpath_dirs.dirs != (void *) -1) - free (imap->l_runpath_dirs.dirs); - - free (imap); - } - } - - /* Notify the debugger those objects are finalized and gone. */ - _r_debug.r_state = RT_CONSISTENT; - _dl_debug_state (); - - /* Now we can perhaps also remove the modules for which we had - dependencies because of symbol lookup. */ - while (__builtin_expect (reldeps != NULL, 0)) - { - while (reldeps->nrellist-- > 0) - _dl_close (reldeps->rellist[reldeps->nrellist]); - - free (reldeps->rellist); - - reldeps = reldeps->next; - } - - free (list); - - /* Release the lock. */ -#ifdef HAVE_DD_LOCK - __lock_release(_dl_load_lock); -#endif - - -} - - -static void -free_mem (void) -{ - if (__builtin_expect (_dl_global_scope_alloc, 0) != 0 - && _dl_main_searchlist->r_nlist == _dl_initial_searchlist.r_nlist) - { - /* All object dynamically loaded by the program are unloaded. Free - the memory allocated for the global scope variable. */ - struct link_map **old = _dl_main_searchlist->r_list; - - /* Put the old map in. */ - _dl_main_searchlist->r_list = _dl_initial_searchlist.r_list; - /* Signal that the original map is used. */ - _dl_global_scope_alloc = 0; - - /* Now free the old map. */ - free (old); - } -} -text_set_element (__libc_subfreeres, free_mem); diff --git a/newlib/libc/sys/linux/dl/dl-debug.c b/newlib/libc/sys/linux/dl/dl-debug.c deleted file mode 100644 index 5a51b5335..000000000 --- a/newlib/libc/sys/linux/dl/dl-debug.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Communicate dynamic linker state to the debugger at runtime. - Copyright (C) 1996, 1998, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <ldsodefs.h> - -/* This structure communicates dl state to the debugger. The debugger - normally finds it via the DT_DEBUG entry in the dynamic section, but in - a statically-linked program there is no dynamic section for the debugger - to examine and it looks for this particular symbol name. */ -struct r_debug _r_debug; - - -/* Initialize _r_debug if it has not already been done. The argument is - the run-time load address of the dynamic linker, to be put in - _r_debug.r_ldbase. Returns the address of _r_debug. */ - -struct r_debug * -internal_function -_dl_debug_initialize (ElfW(Addr) ldbase) -{ - if (_r_debug.r_brk == 0) - { - /* Tell the debugger where to find the map of loaded objects. */ - _r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */; - _r_debug.r_ldbase = ldbase; - _r_debug.r_map = _dl_loaded; - _r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state; - } - - return &_r_debug; -} - - -/* This function exists solely to have a breakpoint set on it by the - debugger. The debugger is supposed to find this function's address by - examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks - for this particular symbol name in the PT_INTERP file. */ -void -_dl_debug_state (void) -{ -} diff --git a/newlib/libc/sys/linux/dl/dl-deps.c b/newlib/libc/sys/linux/dl/dl-deps.c deleted file mode 100644 index 4596a85d7..000000000 --- a/newlib/libc/sys/linux/dl/dl-deps.c +++ /dev/null @@ -1,561 +0,0 @@ -/* Load the dependencies of a mapped object. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <assert.h> -#include <dlfcn.h> -#include <errno.h> -#include <libintl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/param.h> -#include <ldsodefs.h> - -#include <dl-dst.h> - -/* Whether an shared object references one or more auxiliary objects - is signaled by the AUXTAG entry in l_info. */ -#define AUXTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRATAGIDX (DT_AUXILIARY)) -/* Whether an shared object references one or more auxiliary objects - is signaled by the AUXTAG entry in l_info. */ -#define FILTERTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ - + DT_EXTRATAGIDX (DT_FILTER)) - -/* This is zero at program start to signal that the global scope map is - allocated by rtld. Later it keeps the size of the map. It might be - reset if in _dl_close if the last global object is removed. */ -size_t _dl_global_scope_alloc; - -extern size_t _dl_platformlen; - -/* When loading auxiliary objects we must ignore errors. It's ok if - an object is missing. */ -struct openaux_args - { - /* The arguments to openaux. */ - struct link_map *map; - int trace_mode; - const char *strtab; - const char *name; - - /* The return value of openaux. */ - struct link_map *aux; - }; - -static void -openaux (void *a) -{ - struct openaux_args *args = (struct openaux_args *) a; - - args->aux = _dl_map_object (args->map, args->name, 0, - (args->map->l_type == lt_executable - ? lt_library : args->map->l_type), - args->trace_mode, 0); -} - - - -/* We use a very special kind of list to track the path - through the list of loaded shared objects. We have to - produce a flat list with unique members of all involved objects. -*/ -struct list - { - int done; /* Nonzero if this map was processed. */ - struct link_map *map; /* The data. */ - struct list *next; /* Elements for normal list. */ - }; - - -/* Macro to expand DST. It is an macro since we use `alloca'. */ -#define expand_dst(l, str, fatal) \ - ({ \ - const char *__str = (str); \ - const char *__result = __str; \ - size_t __cnt = DL_DST_COUNT(__str, 0); \ - \ - if (__cnt != 0) \ - { \ - char *__newp; \ - \ - __newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str), \ - __cnt)); \ - \ - __result = DL_DST_SUBSTITUTE (l, __str, __newp, 0); \ - \ - if (*__result == '\0') \ - { \ - /* The replacement for the DST is not known. We can't \ - processed. */ \ - if (fatal) \ - _dl_signal_error (0, __str, NULL, N_("\ -empty dynamics string token substitution")); \ - else \ - { \ - /* This is for DT_AUXILIARY. */ \ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) \ - _dl_debug_printf ("cannot load auxiliary `%s' because of" \ - "empty dynamic string token " \ - "substitution\n", __str); \ - continue; \ - } \ - } \ - } \ - \ - __result; }) - - -void -internal_function -_dl_map_object_deps (struct link_map *map, - struct link_map **preloads, unsigned int npreloads, - int trace_mode) -{ - struct list known[1 + npreloads + 1]; - struct list *runp, *tail; - unsigned int nlist, i; - /* Object name. */ - const char *name; - int errno_saved; - int errno_reason; - const char *errstring; - const char *objname; - - auto inline void preload (struct link_map *map); - - inline void preload (struct link_map *map) - { - known[nlist].done = 0; - known[nlist].map = map; - known[nlist].next = &known[nlist + 1]; - - ++nlist; - /* We use `l_reserved' as a mark bit to detect objects we have - already put in the search list and avoid adding duplicate - elements later in the list. */ - map->l_reserved = 1; - } - - /* No loaded object so far. */ - nlist = 0; - - /* First load MAP itself. */ - preload (map); - - /* Add the preloaded items after MAP but before any of its dependencies. */ - for (i = 0; i < npreloads; ++i) - preload (preloads[i]); - - /* Terminate the lists. */ - known[nlist - 1].next = NULL; - - /* Pointer to last unique object. */ - tail = &known[nlist - 1]; - - /* Process each element of the search list, loading each of its - auxiliary objects and immediate dependencies. Auxiliary objects - will be added in the list before the object itself and - dependencies will be appended to the list as we step through it. - This produces a flat, ordered list that represents a - breadth-first search of the dependency tree. - - The whole process is complicated by the fact that we better - should use alloca for the temporary list elements. But using - alloca means we cannot use recursive function calls. */ - errno_saved = errno; - errno_reason = 0; - errstring = NULL; - errno = 0; - name = NULL; - for (runp = known; runp; ) - { - struct link_map *l = runp->map; - struct link_map **needed = NULL; - unsigned int nneeded = 0; - - /* Unless otherwise stated, this object is handled. */ - runp->done = 1; - - /* Allocate a temporary record to contain the references to the - dependencies of this object. */ - if (l->l_searchlist.r_list == NULL && l->l_initfini == NULL - && l != map && l->l_ldnum > 0) - needed = (struct link_map **) alloca (l->l_ldnum - * sizeof (struct link_map *)); - - if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG]) - { - const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); - struct openaux_args args; - struct list *orig; - const ElfW(Dyn) *d; - - args.strtab = strtab; - args.map = l; - args.trace_mode = trace_mode; - orig = runp; - - for (d = l->l_ld; d->d_tag != DT_NULL; ++d) - if (__builtin_expect (d->d_tag, DT_NEEDED) == DT_NEEDED) - { - /* Map in the needed object. */ - struct link_map *dep; - int err; - - /* Recognize DSTs. */ - name = expand_dst (l, strtab + d->d_un.d_val, 0); - /* Store the tag in the argument structure. */ - args.name = name; - - err = _dl_catch_error (&objname, &errstring, openaux, &args); - if (__builtin_expect (errstring != NULL, 0)) - { - if (err) - errno_reason = err; - else - errno_reason = -1; - goto out; - } - else - dep = args.aux; - - if (! dep->l_reserved) - { - /* Allocate new entry. */ - struct list *newp; - - newp = alloca (sizeof (struct list)); - - /* Append DEP to the list. */ - newp->map = dep; - newp->done = 0; - newp->next = NULL; - tail->next = newp; - tail = newp; - ++nlist; - /* Set the mark bit that says it's already in the list. */ - dep->l_reserved = 1; - } - - /* Remember this dependency. */ - if (needed != NULL) - needed[nneeded++] = dep; - } - else if (d->d_tag == DT_AUXILIARY || d->d_tag == DT_FILTER) - { - struct list *newp; - - /* Recognize DSTs. */ - name = expand_dst (l, strtab + d->d_un.d_val, - d->d_tag == DT_AUXILIARY); - /* Store the tag in the argument structure. */ - args.name = name; - - if (d->d_tag == DT_AUXILIARY) - { - int err; - - /* Say that we are about to load an auxiliary library. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) - _dl_debug_printf ("load auxiliary object=%s" - " requested by file=%s\n", name, - l->l_name[0] - ? l->l_name : _dl_argv[0]); - - /* We must be prepared that the addressed shared - object is not available. */ - err = _dl_catch_error (&objname, &errstring, openaux, - &args); - if (__builtin_expect (errstring != NULL, 0)) - { - /* We are not interested in the error message. */ - assert (errstring != NULL); - if (errstring != _dl_out_of_memory) - free ((char *) errstring); - - /* Simply ignore this error and continue the work. */ - continue; - } - } - else - { - int err; - - /* Say that we are about to load an auxiliary library. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) - _dl_debug_printf ("load filtered object=%s" - " requested by file=%s\n", name, - l->l_name[0] - ? l->l_name : _dl_argv[0]); - - /* For filter objects the dependency must be available. */ - err = _dl_catch_error (&objname, &errstring, openaux, - &args); - if (__builtin_expect (errstring != NULL, 0)) - { - if (err) - errno_reason = err; - else - errno_reason = -1; - goto out; - } - } - - /* The auxiliary object is actually available. - Incorporate the map in all the lists. */ - - /* Allocate new entry. This always has to be done. */ - newp = alloca (sizeof (struct list)); - - /* We want to insert the new map before the current one, - but we have no back links. So we copy the contents of - the current entry over. Note that ORIG and NEWP now - have switched their meanings. */ - memcpy (newp, orig, sizeof (*newp)); - - /* Initialize new entry. */ - orig->done = 0; - orig->map = args.aux; - - /* Remember this dependency. */ - if (needed != NULL) - needed[nneeded++] = args.aux; - - /* We must handle two situations here: the map is new, - so we must add it in all three lists. If the map - is already known, we have two further possibilities: - - if the object is before the current map in the - search list, we do nothing. It is already found - early - - if the object is after the current one, we must - move it just before the current map to make sure - the symbols are found early enough - */ - if (args.aux->l_reserved) - { - /* The object is already somewhere in the list. - Locate it first. */ - struct list *late; - - /* This object is already in the search list we - are building. Don't add a duplicate pointer. - Just added by _dl_map_object. */ - for (late = newp; late->next != NULL; late = late->next) - if (late->next->map == args.aux) - break; - - if (late->next != NULL) - { - /* The object is somewhere behind the current - position in the search path. We have to - move it to this earlier position. */ - orig->next = newp; - - /* Now remove the later entry from the list - and adjust the tail pointer. */ - if (tail == late->next) - tail = late; - late->next = late->next->next; - - /* We must move the object earlier in the chain. */ - if (args.aux->l_prev != NULL) - args.aux->l_prev->l_next = args.aux->l_next; - if (args.aux->l_next != NULL) - args.aux->l_next->l_prev = args.aux->l_prev; - - args.aux->l_prev = newp->map->l_prev; - newp->map->l_prev = args.aux; - if (args.aux->l_prev != NULL) - args.aux->l_prev->l_next = args.aux; - args.aux->l_next = newp->map; - } - else - { - /* The object must be somewhere earlier in the - list. Undo to the current list element what - we did above. */ - memcpy (orig, newp, sizeof (*newp)); - continue; - } - } - else - { - /* This is easy. We just add the symbol right here. */ - orig->next = newp; - ++nlist; - /* Set the mark bit that says it's already in the list. */ - args.aux->l_reserved = 1; - - /* The only problem is that in the double linked - list of all objects we don't have this new - object at the correct place. Correct this here. */ - if (args.aux->l_prev) - args.aux->l_prev->l_next = args.aux->l_next; - if (args.aux->l_next) - args.aux->l_next->l_prev = args.aux->l_prev; - - args.aux->l_prev = newp->map->l_prev; - newp->map->l_prev = args.aux; - if (args.aux->l_prev != NULL) - args.aux->l_prev->l_next = args.aux; - args.aux->l_next = newp->map; - } - - /* Move the tail pointer if necessary. */ - if (orig == tail) - tail = newp; - - /* Move on the insert point. */ - orig = newp; - } - } - - /* Terminate the list of dependencies and store the array address. */ - if (needed != NULL) - { - needed[nneeded++] = NULL; - - l->l_initfini = (struct link_map **) - malloc ((nneeded + 1) * sizeof needed[0]); - if (l->l_initfini == NULL) - _dl_signal_error (ENOMEM, map->l_name, NULL, - N_("cannot allocate dependency list")); - l->l_initfini[0] = l; - memcpy (&l->l_initfini[1], needed, nneeded * sizeof needed[0]); - } - - /* If we have no auxiliary objects just go on to the next map. */ - if (runp->done) - do - runp = runp->next; - while (runp != NULL && runp->done); - } - - out: - if (errno == 0 && errno_saved != 0) - __set_errno (errno_saved); - - if (map->l_initfini != NULL && map->l_type == lt_loaded) - { - /* This object was previously loaded as a dependency and we have - a separate l_initfini list. We don't need it anymore. */ - assert (map->l_searchlist.r_list == NULL); - free (map->l_initfini); - } - - /* Store the search list we built in the object. It will be used for - searches in the scope of this object. */ - map->l_initfini = - (struct link_map **) malloc ((2 * nlist + 1) - * sizeof (struct link_map *)); - if (map->l_initfini == NULL) - _dl_signal_error (ENOMEM, map->l_name, NULL, - N_("cannot allocate symbol search list")); - - - map->l_searchlist.r_list = &map->l_initfini[nlist + 1]; - map->l_searchlist.r_nlist = nlist; - - for (nlist = 0, runp = known; runp; runp = runp->next) - { - if (__builtin_expect (trace_mode, 0) && runp->map->l_faked) - /* This can happen when we trace the loading. */ - --map->l_searchlist.r_nlist; - else - map->l_searchlist.r_list[nlist++] = runp->map; - - /* Now clear all the mark bits we set in the objects on the search list - to avoid duplicates, so the next call starts fresh. */ - runp->map->l_reserved = 0; - } - - /* Maybe we can remove some relocation dependencies now. */ - assert (map->l_searchlist.r_list[0] == map); - for (i = 0; i < map->l_reldepsact; ++i) - { - unsigned int j; - - for (j = 1; j < nlist; ++j) - if (map->l_searchlist.r_list[j] == map->l_reldeps[i]) - { - /* A direct or transitive dependency is also on the list - of relocation dependencies. Remove the latter. */ - --map->l_reldeps[i]->l_opencount; - - for (j = i + 1; j < map->l_reldepsact; ++j) - map->l_reldeps[j - 1] = map->l_reldeps[j]; - - --map->l_reldepsact; - - /* Account for the '++i' performed by the 'for'. */ - --i; - break; - } - } - - /* Now determine the order in which the initialization has to happen. */ - memcpy (map->l_initfini, map->l_searchlist.r_list, - nlist * sizeof (struct link_map *)); - /* We can skip looking for the binary itself which is at the front - of the search list. Look through the list backward so that circular - dependencies are not changing the order. */ - for (i = 1; i < nlist; ++i) - { - struct link_map *l = map->l_searchlist.r_list[i]; - unsigned int j; - unsigned int k; - - /* Find the place in the initfini list where the map is currently - located. */ - for (j = 1; map->l_initfini[j] != l; ++j) - ; - - /* Find all object for which the current one is a dependency and - move the found object (if necessary) in front. */ - for (k = j + 1; k < nlist; ++k) - { - struct link_map **runp; - - runp = map->l_initfini[k]->l_initfini; - if (runp != NULL) - { - while (*runp != NULL) - if (__builtin_expect (*runp++ == l, 0)) - { - struct link_map *here = map->l_initfini[k]; - - /* Move it now. */ - memmove (&map->l_initfini[j] + 1, - &map->l_initfini[j], - (k - j) * sizeof (struct link_map *)); - map->l_initfini[j] = here; - - break; - } - } - } - } - /* Terminate the list of dependencies. */ - map->l_initfini[nlist] = NULL; - - if (errno_reason) - _dl_signal_error (errno_reason == -1 ? 0 : errno_reason, - objname, NULL, errstring); -} diff --git a/newlib/libc/sys/linux/dl/dl-dst.h b/newlib/libc/sys/linux/dl/dl-dst.h deleted file mode 100644 index ccebf9259..000000000 --- a/newlib/libc/sys/linux/dl/dl-dst.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Handling of dynamic sring tokens. - Copyright (C) 1999, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* Determine the number of DST elements in the name. Only if IS_PATH is - nonzero paths are recognized (i.e., multiple, ':' separated filenames). */ -#define DL_DST_COUNT(name, is_path) \ - ({ \ - size_t __cnt = 0; \ - const char *__sf = strchr (name, '$'); \ - \ - if (__builtin_expect (__sf != NULL, 0)) \ - __cnt = _dl_dst_count (__sf, is_path); \ - \ - __cnt; }) - -/* Prototype for used function. */ -extern size_t _dl_dst_count (const char *name, int is_path); - - -/* Guess from the number of DSTs the length of the result string. */ -#define DL_DST_REQUIRED(l, name, len, cnt) 1024 - -/* Perform the DST substitution. */ -#define DL_DST_SUBSTITUTE(l, name, res, is_path) \ - _dl_dst_substitute (l, name, res, is_path) - -/* Prototype for used function. */ -extern char *_dl_dst_substitute (struct link_map *l, const char *name, - char *result, int is_path); diff --git a/newlib/libc/sys/linux/dl/dl-error.c b/newlib/libc/sys/linux/dl/dl-error.c deleted file mode 100644 index 9c0f55f7f..000000000 --- a/newlib/libc/sys/linux/dl/dl-error.c +++ /dev/null @@ -1,189 +0,0 @@ -/* Error handling for runtime dynamic linker. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <libintl.h> -#include <setjmp.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <ldsodefs.h> -#include <sys/libc-tsd.h> - -/* This structure communicates state between _dl_catch_error and - _dl_signal_error. */ -struct catch - { - const char *objname; /* Object/File name. */ - const char *errstring; /* Error detail filled in here. */ - jmp_buf env; /* longjmp here on error. */ - }; - -/* Multiple threads at once can use the `_dl_catch_error' function. The - calls can come from `_dl_map_object_deps', `_dlerror_run', or from - any of the libc functionality which loads dynamic objects (NSS, iconv). - Therefore we have to be prepared to save the state in thread-local - memory. */ - -__libc_tsd_define (static, DL_ERROR) -#define tsd_getspecific() __libc_tsd_get (DL_ERROR) -#define tsd_setspecific(data) __libc_tsd_set (DL_ERROR, (data)) - - -/* This message we return as a last resort. We define the string in a - variable since we have to avoid freeing it and so have to enable - a pointer comparison. See below and in dlfcn/dlerror.c. */ -const char _dl_out_of_memory[] = "out of memory"; - - -/* This points to a function which is called when an continuable error is - received. Unlike the handling of `catch' this function may return. - The arguments will be the `errstring' and `objname'. - - Since this functionality is not used in normal programs (only in ld.so) - we do not care about multi-threaded programs here. We keep this as a - global variable. */ -static receiver_fct receiver; - - -void -internal_function -_dl_signal_error (int errcode, const char *objname, const char *occation, - const char *errstring) -{ - struct catch *lcatch; - - if (! errstring) - errstring = N_("DYNAMIC LINKER BUG!!!"); - - lcatch = tsd_getspecific (); - if (objname == NULL) - objname = ""; - if (lcatch != NULL) - { - /* We are inside _dl_catch_error. Return to it. We have to - duplicate the error string since it might be allocated on the - stack. The object name is always a string constant. */ - size_t len_objname = strlen (objname) + 1; - size_t len_errstring = strlen (errstring) + 1; - - lcatch->errstring = (char *) malloc (len_objname + len_errstring); - if (lcatch->errstring != NULL) - { - char *tmp; - /* Make a copy of the object file name and the error string. */ - tmp = memcpy ((char *) lcatch->errstring, - errstring, len_errstring); - tmp += len_errstring; - lcatch->objname = memcpy (tmp, - objname, len_objname); - } - else - { - /* This is better than nothing. */ - lcatch->objname = ""; - lcatch->errstring = _dl_out_of_memory; - } - longjmp (lcatch->env, errcode ?: -1); - } - else - { - /* Lossage while resolving the program's own symbols is always fatal. */ - char buffer[1024]; - _dl_fatal_printf ("%s: %s: %s%s%s%s%s\n", - _dl_argv[0] ?: "<program name unknown>", - occation ?: N_("error while loading shared libraries"), - objname, *objname ? ": " : "", - errstring, errcode ? ": " : "", - (errcode - ? __strerror_r (errcode, buffer, sizeof buffer) - : "")); - } -} - - -void -internal_function -_dl_signal_cerror (int errcode, const char *objname, const char *occation, - const char *errstring) -{ - if (receiver) - { - /* We are inside _dl_receive_error. Call the user supplied - handler and resume the work. The receiver will still be - installed. */ - (*receiver) (errcode, objname, errstring); - } - else - _dl_signal_error (errcode, objname, occation, errstring); -} - - -int -internal_function -_dl_catch_error (const char **objname, const char **errstring, - void (*operate) (void *), void *args) -{ - int errcode; - struct catch *volatile old; - struct catch c; - /* We need not handle `receiver' since setting a `catch' is handled - before it. */ - - /* Some systems (e.g., SPARC) handle constructors to local variables - inefficient. So we initialize `c' by hand. */ - c.errstring = NULL; - - old = tsd_getspecific (); - errcode = setjmp (c.env); - if (__builtin_expect (errcode, 0) == 0) - { - tsd_setspecific (&c); - (*operate) (args); - tsd_setspecific (old); - *objname = NULL; - *errstring = NULL; - return 0; - } - - /* We get here only if we longjmp'd out of OPERATE. */ - tsd_setspecific (old); - *objname = c.objname; - *errstring = c.errstring; - return errcode == -1 ? 0 : errcode; -} - -void -internal_function -_dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args) -{ - struct catch *old_catch; - receiver_fct old_receiver; - - old_catch = tsd_getspecific (); - old_receiver = receiver; - - /* Set the new values. */ - tsd_setspecific (NULL); - receiver = fct; - - (*operate) (args); - - tsd_setspecific (old_catch); - receiver = old_receiver; -} diff --git a/newlib/libc/sys/linux/dl/dl-fini.c b/newlib/libc/sys/linux/dl/dl-fini.c deleted file mode 100644 index fc4f4b68a..000000000 --- a/newlib/libc/sys/linux/dl/dl-fini.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Call the termination functions of loaded shared objects. - Copyright (C) 1995,96,98,99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <alloca.h> -#include <assert.h> -#include <string.h> -#include <ldsodefs.h> - - -/* Type of the constructor functions. */ -typedef void (*fini_t) (void); - - -void -internal_function -_dl_fini (void) -{ - /* Lots of fun ahead. We have to call the destructors for all still - loaded objects. The problem is that the ELF specification now - demands that dependencies between the modules are taken into account. - I.e., the destructor for a module is called before the ones for any - of its dependencies. - - To make things more complicated, we cannot simply use the reverse - order of the constructors. Since the user might have loaded objects - using `dlopen' there are possibly several other modules with its - dependencies to be taken into account. Therefore we have to start - determining the order of the modules once again from the beginning. */ - unsigned int i; - struct link_map *l; - struct link_map **maps; - - /* XXX Could it be (in static binaries) that there is no object loaded? */ - assert (_dl_nloaded > 0); - - /* Now we can allocate an array to hold all the pointers and copy - the pointers in. */ - maps = (struct link_map **) alloca (_dl_nloaded - * sizeof (struct link_map *)); - for (l = _dl_loaded, i = 0; l != NULL; l = l->l_next) - { - assert (i < _dl_nloaded); - - maps[i++] = l; - - /* Bump l_opencount of all objects so that they are not dlclose()ed - from underneath us. */ - ++l->l_opencount; - } - assert (i == _dl_nloaded); - - /* Now we have to do the sorting. */ - for (l = _dl_loaded->l_next; l != NULL; l = l->l_next) - { - unsigned int j; - unsigned int k; - - /* Find the place in the `maps' array. */ - for (j = 1; maps[j] != l; ++j) - ; - - /* Find all object for which the current one is a dependency and - move the found object (if necessary) in front. */ - for (k = j + 1; k < _dl_nloaded; ++k) - { - struct link_map **runp; - - runp = maps[k]->l_initfini; - if (runp != NULL) - { - while (*runp != NULL) - if (*runp == l) - { - struct link_map *here = maps[k]; - - /* Move it now. */ - memmove (&maps[j] + 1, - &maps[j], - (k - j) * sizeof (struct link_map *)); - maps[j++] = here; - - break; - } - else - ++runp; - } - - if (__builtin_expect (maps[k]->l_reldeps != NULL, 0)) - { - unsigned int m = maps[k]->l_reldepsact; - struct link_map **relmaps = maps[k]->l_reldeps; - - while (m-- > 0) - { - if (relmaps[m] == l) - { - struct link_map *here = maps[k]; - - /* Move it now. */ - memmove (&maps[j] + 1, - &maps[j], - (k - j) * sizeof (struct link_map *)); - maps[j] = here; - - break; - } - - } - } - } - } - - /* `maps' now contains the objects in the right order. Now call the - destructors. We have to process this array from the front. */ - for (i = 0; i < _dl_nloaded; ++i) - { - l = maps[i]; - - if (l->l_init_called) - { - /* Make sure nothing happens if we are called twice. */ - l->l_init_called = 0; - - /* Don't call the destructors for objects we are not supposed to. */ - if (l->l_name[0] == '\0' && l->l_type == lt_executable) - continue; - - /* Is there a destructor function? */ - if (l->l_info[DT_FINI_ARRAY] == NULL && l->l_info[DT_FINI] == NULL) - continue; - - /* When debugging print a message first. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) - _dl_debug_printf ("\ncalling fini: %s\n\n", - l->l_name[0] ? l->l_name : _dl_argv[0]); - - /* First see whether an array is given. */ - if (l->l_info[DT_FINI_ARRAY] != NULL) - { - ElfW(Addr) *array = - (ElfW(Addr) *) (l->l_addr - + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr); - unsigned int sz = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val - / sizeof (ElfW(Addr))); - unsigned int cnt; - - for (cnt = 0; cnt < sz; ++cnt) - ((fini_t) (l->l_addr + array[cnt])) (); - } - - /* Next try the old-style destructor. */ - if (l->l_info[DT_FINI] != NULL) - ((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) (); - } - } -} diff --git a/newlib/libc/sys/linux/dl/dl-init.c b/newlib/libc/sys/linux/dl/dl-init.c deleted file mode 100644 index 5448b03c3..000000000 --- a/newlib/libc/sys/linux/dl/dl-init.c +++ /dev/null @@ -1,149 +0,0 @@ -/* Return the next shared object initializer function not yet run. - Copyright (C) 1995,1996,1998,1999,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <stddef.h> -#include <ldsodefs.h> - - -/* Type of the initializer. */ -typedef void (*init_t) (int, char **, char **); - -/* Flag, nonzero during startup phase. */ -extern int _dl_starting_up; - -/* The object to be initialized first. */ -extern struct link_map *_dl_initfirst; - - -static void -call_init (struct link_map *l, int argc, char **argv, char **env) -{ - if (l->l_init_called) - /* This object is all done. */ - return; - - /* Avoid handling this constructor again in case we have a circular - dependency. */ - l->l_init_called = 1; - - /* Check for object which constructors we do not run here. */ - if (__builtin_expect (l->l_name[0], 'a') == '\0' - && l->l_type == lt_executable) - return; - - /* Are there any constructors? */ - if (l->l_info[DT_INIT] == NULL - && __builtin_expect (l->l_info[DT_INIT_ARRAY] == NULL, 1)) - return; - - /* Print a debug message if wanted. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) - _dl_debug_printf ("\ncalling init: %s\n\n", - l->l_name[0] ? l->l_name : _dl_argv[0]); - - /* Now run the local constructors. There are two forms of them: - - the one named by DT_INIT - - the others in the DT_INIT_ARRAY. - */ - if (l->l_info[DT_INIT] != NULL) - { - init_t init = (init_t) DL_DT_INIT_ADDRESS - (l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr); - - /* Call the function. */ - init (argc, argv, env); - } - - /* Next see whether there is an array with initialization functions. */ - if (l->l_info[DT_INIT_ARRAY] != NULL) - { - unsigned int j; - unsigned int jm; - ElfW(Addr) *addrs; - - jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr)); - - addrs = (ElfW(Addr) *) (l->l_info[DT_INIT_ARRAY]->d_un.d_ptr - + l->l_addr); - for (j = 0; j < jm; ++j) - ((init_t) addrs[j]) (argc, argv, env); - } -} - - -void -internal_function -_dl_init (struct link_map *main_map, int argc, char **argv, char **env) -{ - ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY]; - struct r_debug *r; - unsigned int i; - - if (__builtin_expect (_dl_initfirst != NULL, 0)) - { - call_init (_dl_initfirst, argc, argv, env); - _dl_initfirst = NULL; - } - - /* Don't do anything if there is no preinit array. */ - if (__builtin_expect (preinit_array != NULL, 0) - && (i = preinit_array->d_un.d_val / sizeof (ElfW(Addr))) > 0) - { - ElfW(Addr) *addrs; - unsigned int cnt; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) - _dl_debug_printf ("\ncalling preinit: %s\n\n", - main_map->l_name[0] - ? main_map->l_name : _dl_argv[0]); - - addrs = (ElfW(Addr) *) (main_map->l_info[DT_PREINIT_ARRAY]->d_un.d_ptr - + main_map->l_addr); - for (cnt = 0; cnt < i; ++cnt) - ((init_t) addrs[cnt]) (argc, argv, env); - } - - /* Notify the debugger we have added some objects. We need to call - _dl_debug_initialize in a static program in case dynamic linking has - not been used before. */ - r = _dl_debug_initialize (0); - r->r_state = RT_ADD; - _dl_debug_state (); - - /* Stupid users forced the ELF specification to be changed. It now - says that the dynamic loader is responsible for determining the - order in which the constructors have to run. The constructors - for all dependencies of an object must run before the constructor - for the object itself. Circular dependencies are left unspecified. - - This is highly questionable since it puts the burden on the dynamic - loader which has to find the dependencies at runtime instead of - letting the user do it right. Stupidity rules! */ - - i = main_map->l_searchlist.r_nlist; - while (i-- > 0) - call_init (main_map->l_initfini[i], argc, argv, env); - - /* Notify the debugger all new objects are now ready to go. */ - r->r_state = RT_CONSISTENT; - _dl_debug_state (); - - /* Finished starting up. */ - _dl_starting_up = 0; -} diff --git a/newlib/libc/sys/linux/dl/dl-iteratephdr.c b/newlib/libc/sys/linux/dl/dl-iteratephdr.c deleted file mode 100644 index a39a4934e..000000000 --- a/newlib/libc/sys/linux/dl/dl-iteratephdr.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Get loaded objects program headers. - Copyright (C) 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek <jakub@redhat.com>, 2001. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include <errno.h> -#include <ldsodefs.h> -#include <stddef.h> -#include <bits/libc-lock.h> - -int -__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, - size_t size, void *data), void *data) -{ - struct link_map *l; - struct dl_phdr_info info; - int ret = 0; - - /* Make sure we are alone. */ -#ifdef HAVE_DD_LOCK - __lock_acquire(_dl_load_lock); -#endif - - - for (l = _dl_loaded; l != NULL; l = l->l_next) - { - /* Skip the dynamic linker. */ - if (l->l_phdr == NULL) - continue; - info.dlpi_addr = l->l_addr; - info.dlpi_name = l->l_name; - info.dlpi_phdr = l->l_phdr; - info.dlpi_phnum = l->l_phnum; - ret = callback (&info, sizeof (struct dl_phdr_info), data); - if (ret) - break; - } - - /* Release the lock. */ -#ifdef HAVE_DD_LOCK - __lock_release(_dl_load_lock); -#endif - - - return ret; -} - -#ifdef SHARED -weak_alias (__dl_iterate_phdr, dl_iterate_phdr); -#endif diff --git a/newlib/libc/sys/linux/dl/dl-libc.c b/newlib/libc/sys/linux/dl/dl-libc.c deleted file mode 100644 index c83448df7..000000000 --- a/newlib/libc/sys/linux/dl/dl-libc.c +++ /dev/null @@ -1,156 +0,0 @@ -/* Handle loading and unloading shared objects for internal libc purposes. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <dlfcn.h> -#include <stdlib.h> -#include <ldsodefs.h> - -/* The purpose of this file is to provide wrappers around the dynamic - linker error mechanism (similar to dlopen() et al in libdl) which - are usable from within libc. Generally we want to throw away the - string that dlerror() would return and just pass back a null pointer - for errors. This also lets the rest of libc not know about the error - handling mechanism. - - Much of this code came from gconv_dl.c with slight modifications. */ - -static int -internal_function -dlerror_run (void (*operate) (void *), void *args) -{ - const char *objname; - const char *last_errstring = NULL; - int result; - - (void) _dl_catch_error (&objname, &last_errstring, operate, args); - - result = last_errstring != NULL; - if (result && last_errstring != _dl_out_of_memory) - free ((char *) last_errstring); - - return result; -} - -/* These functions are called by dlerror_run... */ - -struct do_dlopen_args -{ - /* Argument to do_dlopen. */ - const char *name; - - /* Return from do_dlopen. */ - struct link_map *map; -}; - -struct do_dlsym_args -{ - /* Arguments to do_dlsym. */ - struct link_map *map; - const char *name; - - /* Return values of do_dlsym. */ - lookup_t loadbase; - const ElfW(Sym) *ref; -}; - -static void -do_dlopen (void *ptr) -{ - struct do_dlopen_args *args = (struct do_dlopen_args *) ptr; - /* Open and relocate the shared object. */ - args->map = _dl_open (args->name, RTLD_LAZY, NULL); -} - -static void -do_dlsym (void *ptr) -{ - struct do_dlsym_args *args = (struct do_dlsym_args *) ptr; - args->ref = NULL; - args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref, - args->map->l_local_scope, 0, 1); -} - -static void -do_dlclose (void *ptr) -{ - _dl_close ((struct link_map *) ptr); -} - -/* ... and these functions call dlerror_run. */ - -void * -__libc_dlopen (const char *__name) -{ - struct do_dlopen_args args; - args.name = __name; - - return (dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map); -} - -void * -__libc_dlsym (void *__map, const char *__name) -{ - struct do_dlsym_args args; - args.map = __map; - args.name = __name; - - return (dlerror_run (do_dlsym, &args) ? NULL - : (void *) (DL_SYMBOL_ADDRESS (args.loadbase, args.ref))); -} - -int -__libc_dlclose (void *__map) -{ - return dlerror_run (do_dlclose, __map); -} - - -static void -free_mem (void) -{ - struct link_map *l; - struct r_search_path_elem *d; - - /* Remove all search directories. */ - d = _dl_all_dirs; - while (d != _dl_init_all_dirs) - { - struct r_search_path_elem *old = d; - d = d->next; - free (old); - } - - /* Remove all additional names added to the objects. */ - for (l = _dl_loaded; l != NULL; l = l->l_next) - { - struct libname_list *lnp = l->l_libname->next; - - l->l_libname->next = NULL; - - while (lnp != NULL) - { - struct libname_list *old = lnp; - lnp = lnp->next; - if (! old->dont_free) - free (old); - } - } -} -text_set_element (__libc_subfreeres, free_mem); diff --git a/newlib/libc/sys/linux/dl/dl-librecon.h b/newlib/libc/sys/linux/dl/dl-librecon.h deleted file mode 100644 index 3e39a32e6..000000000 --- a/newlib/libc/sys/linux/dl/dl-librecon.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Optional code to distinguish library flavours. - Copyright (C) 1998, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _DL_LIBRECON_H -#define _DL_LIBRECON_H 1 - -#define DISTINGUISH_LIB_VERSIONS \ - do \ - { \ - /* We have to find out whether the binary is linked against \ - libc 5 or glibc. We do this by looking at all the DT_NEEDED \ - entries. If one is libc.so.5 this is a libc 5 linked binary. */ \ - if (_dl_loaded->l_info[DT_NEEDED]) \ - { \ - /* We have dependencies. */ \ - const ElfW(Dyn) *d; \ - const char *strtab; \ - \ - strtab = (const char *) D_PTR (_dl_loaded, l_info[DT_STRTAB]); \ - \ - for (d = _dl_loaded->l_ld; d->d_tag != DT_NULL; ++d) \ - if (d->d_tag == DT_NEEDED \ - && strcmp (strtab + d->d_un.d_val, "libc.so.5") == 0) \ - break; \ - \ - /* We print a `5' or `6' depending on the outcome. */ \ - _dl_printf (d->d_tag != DT_NULL ? "5\n" : "6\n"); \ - } \ - } \ - while (0) - -/* Recognizing extra environment variables. */ -#define EXTRA_LD_ENVVARS \ - case 13: \ - if (memcmp (envline, "ASSUME_KERNEL", 13) == 0) \ - { \ - unsigned long int i, j, osversion = 0; \ - char *p = &envline[14], *q; \ - \ - for (i = 0; i < 3; i++, p = q + 1) \ - { \ - j = __strtoul_internal (p, &q, 0, 0); \ - if (j >= 255 || p == q || (i < 2 && *q && *q != '.')) \ - { \ - osversion = 0; \ - break; \ - } \ - osversion |= j << (16 - 8 * i); \ - if (!*q) \ - break; \ - } \ - if (osversion) \ - _dl_osversion = osversion; \ - break; \ - } \ - \ - case 15: \ - if (memcmp (envline, "LIBRARY_VERSION", 15) == 0) \ - { \ - _dl_correct_cache_id = envline[16] == '5' ? 2 : 3; \ - break; \ - } - -/* Extra unsecure variables. The names are all stuffed in a single - string which means they have to be terminated with a '\0' explicitly. */ -#define EXTRA_UNSECURE_ENVVARS \ - "LD_AOUT_LIBRARY_PATH\0" \ - "LD_AOUT_PRELOAD\0" - -#endif /* dl-librecon.h */ diff --git a/newlib/libc/sys/linux/dl/dl-load.c b/newlib/libc/sys/linux/dl/dl-load.c deleted file mode 100644 index 4e32d604b..000000000 --- a/newlib/libc/sys/linux/dl/dl-load.c +++ /dev/null @@ -1,1830 +0,0 @@ -/* Map in a shared object's segments from the file. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <elf.h> -#include <errno.h> -#include <fcntl.h> -#include <libintl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <ldsodefs.h> -#include <sys/mman.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/types.h> -#include "dynamic-link.h" -#include <abi-tag.h> -#include <dl-osinfo.h> - -#include <dl-dst.h> - -/* On some systems, no flag bits are given to specify file mapping. */ -#ifndef MAP_FILE -# define MAP_FILE 0 -#endif - -/* The right way to map in the shared library files is MAP_COPY, which - makes a virtual copy of the data at the time of the mmap call; this - guarantees the mapped pages will be consistent even if the file is - overwritten. Some losing VM systems like Linux's lack MAP_COPY. All we - get is MAP_PRIVATE, which copies each page when it is modified; this - means if the file is overwritten, we may at some point get some pages - from the new version after starting with pages from the old version. */ -#ifndef MAP_COPY -# define MAP_COPY MAP_PRIVATE -#endif - -/* Some systems link their relocatable objects for another base address - than 0. We want to know the base address for these such that we can - subtract this address from the segment addresses during mapping. - This results in a more efficient address space usage. Defaults to - zero for almost all systems. */ -#ifndef MAP_BASE_ADDR -# define MAP_BASE_ADDR(l) 0 -#endif - - -#include <endian.h> -#if BYTE_ORDER == BIG_ENDIAN -# define byteorder ELFDATA2MSB -#elif BYTE_ORDER == LITTLE_ENDIAN -# define byteorder ELFDATA2LSB -#else -# error "Unknown BYTE_ORDER " BYTE_ORDER -# define byteorder ELFDATANONE -#endif - -#define STRING(x) __STRING (x) - -#ifdef MAP_ANON -/* The fd is not examined when using MAP_ANON. */ -# define ANONFD -1 -#else -int _dl_zerofd = -1; -# define ANONFD _dl_zerofd -#endif - -/* Handle situations where we have a preferred location in memory for - the shared objects. */ -#ifdef ELF_PREFERRED_ADDRESS_DATA -ELF_PREFERRED_ADDRESS_DATA; -#endif -#ifndef ELF_PREFERRED_ADDRESS -# define ELF_PREFERRED_ADDRESS(loader, maplength, mapstartpref) (mapstartpref) -#endif -#ifndef ELF_FIXED_ADDRESS -# define ELF_FIXED_ADDRESS(loader, mapstart) ((void) 0) -#endif - -/* Type for the buffer we put the ELF header and hopefully the program - header. This buffer does not really have to be too large. In most - cases the program header follows the ELF header directly. If this - is not the case all bets are off and we can make the header arbitrarily - large and still won't get it read. This means the only question is - how large are the ELF and program header combined. The ELF header - in 64-bit files is 56 bytes long. Each program header entry is again - 56 bytes long. I.e., even with a file which has 17 program header - entries we only have to read 1kB. And 17 program header entries is - plenty, normal files have < 10. If this heuristic should really fail - for some file the code in `_dl_map_object_from_fd' knows how to - recover. */ -struct filebuf -{ - ssize_t len; - char buf[1024]; -}; - -size_t _dl_pagesize; - -unsigned int _dl_osversion; - -int _dl_clktck; - -extern const char *_dl_platform; -extern size_t _dl_platformlen; - -/* The object to be initialized first. */ -struct link_map *_dl_initfirst; - -/* This is the decomposed LD_LIBRARY_PATH search path. */ -static struct r_search_path_struct env_path_list; - -/* List of the hardware capabilities we might end up using. */ -static const struct r_strlenpair *capstr; -static size_t ncapstr; -static size_t max_capstrlen; - - -/* Get the generated information about the trusted directories. */ -#include "trusted-dirs.h" - -static const char system_dirs[] = SYSTEM_DIRS; -static const size_t system_dirs_len[] = -{ - SYSTEM_DIRS_LEN -}; -#define nsystem_dirs_len \ - (sizeof (system_dirs_len) / sizeof (system_dirs_len[0])) - - -/* Local version of `strdup' function. */ -static inline char * -local_strdup (const char *s) -{ - size_t len = strlen (s) + 1; - void *new = malloc (len); - - if (new == NULL) - return NULL; - - return (char *) memcpy (new, s, len); -} - - -static size_t -is_dst (const char *start, const char *name, const char *str, size_t cmplen, - int is_path, int secure) -{ - size_t len; - - if (strncmp (name, str, cmplen) == 0) - len = cmplen + 1; - else if (strncmp (name, str + 1, cmplen - 2) == 0 - && (name[cmplen - 2] == '\0' || name[cmplen - 2] == '/' - || (is_path && name[cmplen - 2] == ':'))) - len = cmplen - 1; - else - return 0; - - if (__builtin_expect (secure, 0) - && ((name[len - 1] != '\0' && (!is_path || name[len - 1] != ':')) - || (name != start + 1 && (!is_path || name[-2] != ':')))) - return 0; - - return len; -} - - -size_t -_dl_dst_count (const char *name, int is_path) -{ - const char *const start = name; - size_t cnt = 0; - - do - { - size_t len = 1; - - /* $ORIGIN is not expanded for SUID/GUID programs (except if it - is $ORIGIN alone) and it must always appear first in path. - - Note that it is no bug that the string in the second and - fourth `strncmp' call is longer than the sequence which is - actually tested. */ - if ((len = is_dst (start, name + 1, "{ORIGIN}", 8, is_path, - 0)) != 0 - || ((len = is_dst (start, name + 1, "{PLATFORM}", 10, is_path, 0)) - != 0)) - ++cnt; - - name = strchr (name + len, '$'); - } - while (name != NULL); - - return cnt; -} - - -char * -_dl_dst_substitute (struct link_map *l, const char *name, char *result, - int is_path) -{ - const char *const start = name; - char *last_elem, *wp; - - /* Now fill the result path. While copying over the string we keep - track of the start of the last path element. When we come accross - a DST we copy over the value or (if the value is not available) - leave the entire path element out. */ - last_elem = wp = result; - - do - { - if (__builtin_expect (*name == '$', 0)) - { - const char *repl = NULL; - size_t len = 1; - - /* Note that it is no bug that the string in the second and - fourth `strncmp' call is longer than the sequence which - is actually tested. */ - if ((len = is_dst (start, name + 1, "{ORIGIN}", 8, is_path, - 0)) != 0) - repl = l->l_origin; - else if ((len = is_dst (start, name + 1, "{PLATFORM}", 10, is_path, - 0)) != 0) - repl = _dl_platform; - - if (repl != NULL && repl != (const char *) -1) - { - wp = strcpy (wp, repl); - wp += strlen (repl); - name += len; - } - else if (len > 1) - { - /* We cannot use this path element, the value of the - replacement is unknown. */ - wp = last_elem; - name += len; - while (*name != '\0' && (!is_path || *name != ':')) - ++name; - } - else - /* No DST we recognize. */ - *wp++ = *name++; - } - else - { - *wp++ = *name++; - if (is_path && *name == ':') - last_elem = wp; - } - } - while (*name != '\0'); - - *wp = '\0'; - - return result; -} - - -/* Return copy of argument with all recognized dynamic string tokens - ($ORIGIN and $PLATFORM for now) replaced. On some platforms it - might not be possible to determine the path from which the object - belonging to the map is loaded. In this case the path element - containing $ORIGIN is left out. */ -static char * -expand_dynamic_string_token (struct link_map *l, const char *s) -{ - /* We make two runs over the string. First we determine how large the - resulting string is and then we copy it over. Since this is now - frequently executed operation we are looking here not for performance - but rather for code size. */ - size_t cnt; - size_t total; - char *result; - - /* Determine the number of DST elements. */ - cnt = DL_DST_COUNT (s, 1); - - /* If we do not have to replace anything simply copy the string. */ - if (__builtin_expect (cnt, 0) == 0) - return local_strdup (s); - - /* Determine the length of the substituted string. */ - total = DL_DST_REQUIRED (l, s, strlen (s), cnt); - - /* Allocate the necessary memory. */ - result = (char *) malloc (total + 1); - if (result == NULL) - return NULL; - - return DL_DST_SUBSTITUTE (l, s, result, 1); -} - - -/* Add `name' to the list of names for a particular shared object. - `name' is expected to have been allocated with malloc and will - be freed if the shared object already has this name. - Returns false if the object already had this name. */ -static void -internal_function -add_name_to_object (struct link_map *l, const char *name) -{ - struct libname_list *lnp, *lastp; - struct libname_list *newname; - size_t name_len; - - lastp = NULL; - for (lnp = l->l_libname; lnp != NULL; lastp = lnp, lnp = lnp->next) - if (strcmp (name, lnp->name) == 0) - return; - - name_len = strlen (name) + 1; - newname = (struct libname_list *) malloc (sizeof *newname + name_len); - if (newname == NULL) - { - /* No more memory. */ - _dl_signal_error (ENOMEM, name, NULL, N_("cannot allocate name record")); - return; - } - /* The object should have a libname set from _dl_new_object. */ - assert (lastp != NULL); - - newname->name = memcpy (newname + 1, name, name_len); - newname->next = NULL; - newname->dont_free = 0; - lastp->next = newname; -} - -/* All known directories in sorted order. */ -struct r_search_path_elem *_dl_all_dirs; - -/* All directories after startup. */ -struct r_search_path_elem *_dl_init_all_dirs; - -/* Standard search directories. */ -static struct r_search_path_struct rtld_search_dirs; - -static size_t max_dirnamelen; - -static inline struct r_search_path_elem ** -fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep, - int check_trusted, const char *what, const char *where) -{ - char *cp; - size_t nelems = 0; - - printf("In fillin_rpath\n"); - while ((cp = strsep (&rpath, sep)) != NULL) - { - struct r_search_path_elem *dirp; - size_t len = strlen (cp); - - /* `strsep' can pass an empty string. This has to be - interpreted as `use the current directory'. */ - if (len == 0) - { - static const char curwd[] = "./"; - cp = (char *) curwd; - } - - /* Remove trailing slashes (except for "/"). */ - while (len > 1 && cp[len - 1] == '/') - --len; - - /* Now add one if there is none so far. */ - if (len > 0 && cp[len - 1] != '/') - cp[len++] = '/'; - - /* Make sure we don't use untrusted directories if we run SUID. */ - if (__builtin_expect (check_trusted, 0)) - { - const char *trun = system_dirs; - size_t idx; - int unsecure = 1; - - /* All trusted directories must be complete names. */ - if (cp[0] == '/') - { - for (idx = 0; idx < nsystem_dirs_len; ++idx) - { - if (len == system_dirs_len[idx] - && memcmp (trun, cp, len) == 0) - { - /* Found it. */ - unsecure = 0; - break; - } - - trun += system_dirs_len[idx] + 1; - } - } - - if (unsecure) - /* Simply drop this directory. */ - continue; - } - - /* See if this directory is already known. */ - for (dirp = _dl_all_dirs; dirp != NULL; dirp = dirp->next) - if (dirp->dirnamelen == len && memcmp (cp, dirp->dirname, len) == 0) - break; - - if (dirp != NULL) - { - /* It is available, see whether it's on our own list. */ - size_t cnt; - for (cnt = 0; cnt < nelems; ++cnt) - if (result[cnt] == dirp) - break; - - if (cnt == nelems) - result[nelems++] = dirp; - } - else - { - size_t cnt; - enum r_dir_status init_val; - size_t where_len = where ? strlen (where) + 1 : 0; - - /* It's a new directory. Create an entry and add it. */ - dirp = (struct r_search_path_elem *) - malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status) - + where_len + len + 1); - if (dirp == NULL) - _dl_signal_error (ENOMEM, NULL, NULL, - N_("cannot create cache for search path")); - - dirp->dirname = ((char *) dirp + sizeof (*dirp) - + ncapstr * sizeof (enum r_dir_status)); - *((char *) (memcpy ((char *) dirp->dirname, cp, len) + len)) = '\0'; - dirp->dirnamelen = len; - - if (len > max_dirnamelen) - max_dirnamelen = len; - - /* We have to make sure all the relative directories are - never ignored. The current directory might change and - all our saved information would be void. */ - init_val = cp[0] != '/' ? existing : unknown; - for (cnt = 0; cnt < ncapstr; ++cnt) - dirp->status[cnt] = init_val; - - dirp->what = what; - if (__builtin_expect (where != NULL, 1)) - dirp->where = memcpy ((char *) dirp + sizeof (*dirp) + len + 1 - + ncapstr * sizeof (enum r_dir_status), - where, where_len); - else - dirp->where = NULL; - - dirp->next = _dl_all_dirs; - _dl_all_dirs = dirp; - - /* Put it in the result array. */ - result[nelems++] = dirp; - } - } - - /* Terminate the array. */ - result[nelems] = NULL; - - return result; -} - - -static void -internal_function -decompose_rpath (struct r_search_path_struct *sps, - const char *rpath, struct link_map *l, const char *what) -{ - /* Make a copy we can work with. */ - const char *where = l->l_name; - char *copy; - char *cp; - struct r_search_path_elem **result; - size_t nelems; - /* Initialize to please the compiler. */ - const char *errstring = NULL; - - /* First see whether we must forget the RUNPATH and RPATH from this - object. */ - if (__builtin_expect (_dl_inhibit_rpath != NULL, 0)) - { - const char *found = strstr (_dl_inhibit_rpath, where); - if (found != NULL) - { - size_t len = strlen (where); - if ((found == _dl_inhibit_rpath || found[-1] == ':') - && (found[len] == '\0' || found[len] == ':')) - { - /* This object is on the list of objects for which the - RUNPATH and RPATH must not be used. */ - result = (struct r_search_path_elem **) - malloc (sizeof (*result)); - if (result == NULL) - { - signal_error_cache: - errstring = N_("cannot create cache for search path"); - signal_error: - _dl_signal_error (ENOMEM, NULL, NULL, errstring); - } - - result[0] = NULL; - - sps->dirs = result; - sps->malloced = 1; - - return; - } - } - } - - /* Make a writable copy. At the same time expand possible dynamic - string tokens. */ - copy = expand_dynamic_string_token (l, rpath); - if (copy == NULL) - { - errstring = N_("cannot create RUNPATH/RPATH copy"); - goto signal_error; - } - - /* Count the number of necessary elements in the result array. */ - nelems = 0; - for (cp = copy; *cp != '\0'; ++cp) - if (*cp == ':') - ++nelems; - - /* Allocate room for the result. NELEMS + 1 is an upper limit for the - number of necessary entries. */ - result = (struct r_search_path_elem **) malloc ((nelems + 1 + 1) - * sizeof (*result)); - if (result == NULL) - goto signal_error_cache; - - fillin_rpath (copy, result, ":", 0, what, where); - - /* Free the copied RPATH string. `fillin_rpath' make own copies if - necessary. */ - free (copy); - - sps->dirs = result; - /* The caller will change this value if we haven't used a real malloc. */ - sps->malloced = 1; -} - - -void -internal_function -_dl_init_paths (const char *llp) -{ - size_t idx; - const char *strp; - struct r_search_path_elem *pelem, **aelem; - size_t round_size; -#ifdef SHARED - struct link_map *l; -#endif - /* Initialize to please the compiler. */ - const char *errstring = NULL; - - /* Fill in the information about the application's RPATH and the - directories addressed by the LD_LIBRARY_PATH environment variable. */ - - /* Get the capabilities. */ - capstr = _dl_important_hwcaps (_dl_platform, _dl_platformlen, - &ncapstr, &max_capstrlen); - - /* First set up the rest of the default search directory entries. */ - aelem = rtld_search_dirs.dirs = (struct r_search_path_elem **) - malloc ((nsystem_dirs_len + 1) * sizeof (struct r_search_path_elem *)); - if (rtld_search_dirs.dirs == NULL) - { - errstring = N_("cannot create search path array"); - signal_error: - _dl_signal_error (ENOMEM, NULL, NULL, errstring); - } - - round_size = ((2 * sizeof (struct r_search_path_elem) - 1 - + ncapstr * sizeof (enum r_dir_status)) - / sizeof (struct r_search_path_elem)); - - rtld_search_dirs.dirs[0] = (struct r_search_path_elem *) - malloc ((sizeof (system_dirs) / sizeof (system_dirs[0])) - * round_size * sizeof (struct r_search_path_elem)); - if (rtld_search_dirs.dirs[0] == NULL) - { - errstring = N_("cannot create cache for search path"); - goto signal_error; - } - - rtld_search_dirs.malloced = 0; - pelem = _dl_all_dirs = rtld_search_dirs.dirs[0]; - strp = system_dirs; - idx = 0; - - do - { - size_t cnt; - - *aelem++ = pelem; - - pelem->what = "system search path"; - pelem->where = NULL; - - pelem->dirname = strp; - pelem->dirnamelen = system_dirs_len[idx]; - strp += system_dirs_len[idx] + 1; - - /* System paths must be absolute. */ - assert (pelem->dirname[0] == '/'); - for (cnt = 0; cnt < ncapstr; ++cnt) - pelem->status[cnt] = unknown; - - pelem->next = (++idx == nsystem_dirs_len ? NULL : (pelem + round_size)); - - pelem += round_size; - } - while (idx < nsystem_dirs_len); - - max_dirnamelen = SYSTEM_DIRS_MAX_LEN; - *aelem = NULL; - -#ifdef SHARED - /* This points to the map of the main object. */ - l = _dl_loaded; - if (l != NULL) - { - assert (l->l_type != lt_loaded); - - if (l->l_info[DT_RUNPATH]) - { - /* Allocate room for the search path and fill in information - from RUNPATH. */ - decompose_rpath (&l->l_runpath_dirs, - (const void *) (D_PTR (l, l_info[DT_STRTAB]) - + l->l_info[DT_RUNPATH]->d_un.d_val), - l, "RUNPATH"); - - /* The RPATH is ignored. */ - l->l_rpath_dirs.dirs = (void *) -1; - } - else - { - l->l_runpath_dirs.dirs = (void *) -1; - - if (l->l_info[DT_RPATH]) - { - /* Allocate room for the search path and fill in information - from RPATH. */ - decompose_rpath (&l->l_rpath_dirs, - (const void *) (D_PTR (l, l_info[DT_STRTAB]) - + l->l_info[DT_RPATH]->d_un.d_val), - l, "RPATH"); - l->l_rpath_dirs.malloced = 0; - } - else - l->l_rpath_dirs.dirs = (void *) -1; - } - } -#endif /* SHARED */ - - if (llp != NULL && *llp != '\0') - { - size_t nllp; - const char *cp = llp; - const char *old = llp; - size_t len = strlen (old) + 1; - char *new = alloca(len); - char *llp_tmp; - - llp_tmp = memcpy (new, old, len); - - /* Decompose the LD_LIBRARY_PATH contents. First determine how many - elements it has. */ - nllp = 1; - while (*cp) - { - if (*cp == ':' || *cp == ';') - ++nllp; - ++cp; - } - - env_path_list.dirs = (struct r_search_path_elem **) - malloc ((nllp + 1) * sizeof (struct r_search_path_elem *)); - if (env_path_list.dirs == NULL) - { - errstring = N_("cannot create cache for search path"); - goto signal_error; - } - - (void) fillin_rpath (llp_tmp, env_path_list.dirs, ":;", - 0, "LD_LIBRARY_PATH", NULL); - - if (env_path_list.dirs[0] == NULL) - { - free (env_path_list.dirs); - env_path_list.dirs = (void *) -1; - } - - env_path_list.malloced = 0; - } - else - env_path_list.dirs = (void *) -1; - - /* Remember the last search directory added at startup. */ - _dl_init_all_dirs = _dl_all_dirs; -} - - -/* Think twice before changing anything in this function. It is placed - here and prepared using the `alloca' magic to prevent it from being - inlined. The function is only called in case of an error. But then - performance does not count. The function used to be "inlinable" and - the compiled did so all the time. This increased the code size for - absolutely no good reason. */ -static void -__attribute__ ((noreturn)) -lose (int code, int fd, const char *name, char *realname, struct link_map *l, - const char *msg) -{ - /* The use of `alloca' here looks ridiculous but it helps. The goal - is to avoid the function from being inlined. There is no official - way to do this so we use this trick. gcc never inlines functions - which use `alloca'. */ - int *a = (int *) alloca (sizeof (int)); - a[0] = fd; - /* The file might already be closed. */ - if (a[0] != -1) - (void) close (a[0]); - if (l != NULL) - { - /* Remove the stillborn object from the list and free it. */ - assert (l->l_next == NULL); -#ifndef SHARED - if (l->l_prev == NULL) - /* No other module loaded. */ - _dl_loaded = NULL; - else -#endif - l->l_prev->l_next = NULL; - --_dl_nloaded; - free (l); - } - free (realname); - _dl_signal_error (code, name, NULL, msg); -} - - -/* Map in the shared object NAME, actually located in REALNAME, and already - opened on FD. */ - -#ifndef EXTERNAL_MAP_FROM_FD -static -#endif -struct link_map * -_dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, - char *realname, struct link_map *loader, int l_type, - int mode) -{ - struct link_map *l = NULL; - const ElfW(Ehdr) *header; - const ElfW(Phdr) *phdr; - const ElfW(Phdr) *ph; - size_t maplength; - int type; - struct stat64 st; - /* Initialize to keep the compiler happy. */ - const char *errstring = NULL; - int errval = 0; - - /* Get file information. */ - if (__builtin_expect (fstat64 (fd, &st) < 0, 0)) - { - errstring = N_("cannot stat shared object"); - call_lose_errno: - errval = errno; - call_lose: - fprintf (stderr, "%s\n", errstring); - lose (errval, fd, name, realname, l, errstring); - } - - /* Look again to see if the real name matched another already loaded. */ - for (l = _dl_loaded; l; l = l->l_next) - if (l->l_ino == st.st_ino && l->l_dev == st.st_dev) - { - /* The object is already loaded. - Just bump its reference count and return it. */ - close (fd); - - /* If the name is not in the list of names for this object add - it. */ - free (realname); - add_name_to_object (l, name); - - return l; - } - - if (mode & RTLD_NOLOAD) - /* We are not supposed to load the object unless it is already - loaded. So return now. */ - return NULL; - - /* Print debugging message. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) - _dl_debug_printf ("file=%s; generating link map\n", name); - - /* This is the ELF header. We read it in `open_verify'. */ - header = (void *) fbp->buf; - -#ifndef MAP_ANON -# define MAP_ANON 0 - if (_dl_zerofd == -1) - { - _dl_zerofd = _dl_sysdep_open_zero_fill (); - if (_dl_zerofd == -1) - { - close (fd); - _dl_signal_error (errno, NULL, NULL, - N_("cannot open zero fill device")); - } - } -#endif - - /* Enter the new object in the list of loaded objects. */ - l = _dl_new_object (realname, name, l_type, loader); - if (__builtin_expect (! l, 0)) - { - errstring = N_("cannot create shared object descriptor"); - goto call_lose_errno; - } - - /* Extract the remaining details we need from the ELF header - and then read in the program header table. */ - l->l_entry = header->e_entry; - type = header->e_type; - l->l_phnum = header->e_phnum; - - maplength = header->e_phnum * sizeof (ElfW(Phdr)); - if (header->e_phoff + maplength <= fbp->len) - phdr = (void *) (fbp->buf + header->e_phoff); - else - { - phdr = alloca (maplength); - lseek (fd, SEEK_SET, header->e_phoff); - if (__libc_read (fd, (void *) phdr, maplength) != maplength) - { - errstring = N_("cannot read file data"); - goto call_lose_errno; - } - } - - { - /* Scan the program header table, collecting its load commands. */ - struct loadcmd - { - ElfW(Addr) mapstart, mapend, dataend, allocend; - off_t mapoff; - int prot; - } loadcmds[l->l_phnum], *c; - size_t nloadcmds = 0; - - /* The struct is initialized to zero so this is not necessary: - l->l_ld = 0; - l->l_phdr = 0; - l->l_addr = 0; */ - for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph) - switch (ph->p_type) - { - /* These entries tell us where to find things once the file's - segments are mapped in. We record the addresses it says - verbatim, and later correct for the run-time load address. */ - case PT_DYNAMIC: - l->l_ld = (void *) ph->p_vaddr; - l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn)); - break; - - case PT_PHDR: - l->l_phdr = (void *) ph->p_vaddr; - break; - - case PT_LOAD: - /* A load command tells us to map in part of the file. - We record the load commands and process them all later. */ - if ((ph->p_align & (_dl_pagesize - 1)) != 0) - { - errstring = N_("ELF load command alignment not page-aligned"); - goto call_lose; - } - if (((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1)) != 0) - { - errstring - = N_("ELF load command address/offset not properly aligned"); - goto call_lose; - } - - { - struct loadcmd *c = &loadcmds[nloadcmds++]; - c->mapstart = ph->p_vaddr & ~(ph->p_align - 1); - c->mapend = ((ph->p_vaddr + ph->p_filesz + _dl_pagesize - 1) - & ~(_dl_pagesize - 1)); - c->dataend = ph->p_vaddr + ph->p_filesz; - c->allocend = ph->p_vaddr + ph->p_memsz; - c->mapoff = ph->p_offset & ~(ph->p_align - 1); - - /* Optimize a common case. */ -#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7 - c->prot = (PF_TO_PROT - >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf; -#else - c->prot = 0; - if (ph->p_flags & PF_R) - c->prot |= PROT_READ; - if (ph->p_flags & PF_W) - c->prot |= PROT_WRITE; - if (ph->p_flags & PF_X) - c->prot |= PROT_EXEC; -#endif - } - break; - } - - /* Now process the load commands and map segments into memory. */ - c = loadcmds; - - /* Length of the sections to be loaded. */ - maplength = loadcmds[nloadcmds - 1].allocend - c->mapstart; - - if (__builtin_expect (type, ET_DYN) == ET_DYN) - { - /* This is a position-independent shared object. We can let the - kernel map it anywhere it likes, but we must have space for all - the segments in their specified positions relative to the first. - So we map the first segment without MAP_FIXED, but with its - extent increased to cover all the segments. Then we remove - access from excess portion, and there is known sufficient space - there to remap from the later segments. - - As a refinement, sometimes we have an address that we would - prefer to map such objects at; but this is only a preference, - the OS can do whatever it likes. */ - ElfW(Addr) mappref; - mappref = (ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart) - - MAP_BASE_ADDR (l)); - - /* Remember which part of the address space this object uses. */ - l->l_map_start = (ElfW(Addr)) mmap ((void *) mappref, maplength, - c->prot, MAP_COPY | MAP_FILE, - fd, c->mapoff); - if ((void *) l->l_map_start == MAP_FAILED) - { - map_error: - errstring = N_("failed to map segment from shared object"); - goto call_lose_errno; - } - - l->l_map_end = l->l_map_start + maplength; - l->l_addr = l->l_map_start - c->mapstart; - - /* Change protection on the excess portion to disallow all access; - the portions we do not remap later will be inaccessible as if - unallocated. Then jump into the normal segment-mapping loop to - handle the portion of the segment past the end of the file - mapping. */ - mprotect ((caddr_t) (l->l_addr + c->mapend), - loadcmds[nloadcmds - 1].allocend - c->mapend, - PROT_NONE); - - goto postmap; - } - else - { - /* This object is loaded at a fixed address. This must never - happen for objects loaded with dlopen(). */ - if (__builtin_expect (mode & __RTLD_DLOPEN, 0)) - { - errstring = N_("cannot dynamically load executable"); - goto call_lose; - } - - /* Notify ELF_PREFERRED_ADDRESS that we have to load this one - fixed. */ - ELF_FIXED_ADDRESS (loader, c->mapstart); - } - - /* Remember which part of the address space this object uses. */ - l->l_map_start = c->mapstart + l->l_addr; - l->l_map_end = l->l_map_start + maplength; - - while (c < &loadcmds[nloadcmds]) - { - if (c->mapend > c->mapstart - /* Map the segment contents from the file. */ - && (mmap ((void *) (l->l_addr + c->mapstart), - c->mapend - c->mapstart, c->prot, - MAP_FIXED | MAP_COPY | MAP_FILE, fd, c->mapoff) - == MAP_FAILED)) - goto map_error; - - postmap: - if (l->l_phdr == 0 - && c->mapoff <= header->e_phoff - && (c->mapend - c->mapstart + c->mapoff - >= header->e_phoff + header->e_phnum * sizeof (ElfW(Phdr)))) - /* Found the program header in this segment. */ - l->l_phdr = (void *) (c->mapstart + header->e_phoff - c->mapoff); - - if (c->allocend > c->dataend) - { - /* Extra zero pages should appear at the end of this segment, - after the data mapped from the file. */ - ElfW(Addr) zero, zeroend, zeropage; - - zero = l->l_addr + c->dataend; - zeroend = l->l_addr + c->allocend; - zeropage = (zero + _dl_pagesize - 1) & ~(_dl_pagesize - 1); - - if (zeroend < zeropage) - /* All the extra data is in the last page of the segment. - We can just zero it. */ - zeropage = zeroend; - - if (zeropage > zero) - { - /* Zero the final part of the last page of the segment. */ - if ((c->prot & PROT_WRITE) == 0) - { - /* Dag nab it. */ - if (mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), - _dl_pagesize, c->prot|PROT_WRITE) < 0) - { - errstring = N_("cannot change memory protections"); - goto call_lose_errno; - } - } - memset ((void *) zero, '\0', zeropage - zero); - if ((c->prot & PROT_WRITE) == 0) - mprotect ((caddr_t) (zero & ~(_dl_pagesize - 1)), - _dl_pagesize, c->prot); - } - - if (zeroend > zeropage) - { - /* Map the remaining zero pages in from the zero fill FD. */ - caddr_t mapat; - mapat = mmap ((caddr_t) zeropage, zeroend - zeropage, - c->prot, MAP_ANON|MAP_PRIVATE|MAP_FIXED, - ANONFD, 0); - if (mapat == MAP_FAILED) - { - errstring = N_("cannot map zero-fill pages"); - goto call_lose_errno; - } - } - } - - ++c; - } - - if (l->l_phdr == NULL) - { - /* The program header is not contained in any of the segments. - We have to allocate memory ourself and copy it over from - out temporary place. */ - ElfW(Phdr) *newp = (ElfW(Phdr) *) malloc (header->e_phnum - * sizeof (ElfW(Phdr))); - if (newp == NULL) - { - errstring = N_("cannot allocate memory for program header"); - goto call_lose_errno; - } - - l->l_phdr = memcpy (newp, phdr, - (header->e_phnum * sizeof (ElfW(Phdr)))); - l->l_phdr_allocated = 1; - } - else - /* Adjust the PT_PHDR value by the runtime load address. */ - l->l_phdr = (ElfW(Addr)) l->l_phdr + l->l_addr; - } - - /* We are done mapping in the file. We no longer need the descriptor. */ - close (fd); - /* Signal that we closed the file. */ - fd = -1; - - if (l->l_type == lt_library && type == ET_EXEC) - l->l_type = lt_executable; - - if (l->l_ld == 0) - { - if (type == ET_DYN) - { - errstring = N_("object file has no dynamic section"); - goto call_lose; - } - } - else - l->l_ld = (ElfW(Addr)) l->l_ld + l->l_addr; - - l->l_entry += l->l_addr; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) - _dl_debug_printf (" dynamic: 0x%0*lx base: 0x%0*lx size: 0x%0*Zx\n" - " entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u\n\n", - (int) sizeof (void *) * 2, (unsigned long int) l->l_ld, - (int) sizeof (void *) * 2, (unsigned long int) l->l_addr, - (int) sizeof (void *) * 2, maplength, - (int) sizeof (void *) * 2, (unsigned long int) l->l_entry, - (int) sizeof (void *) * 2, (unsigned long int) l->l_phdr, - (int) sizeof (void *) * 2, l->l_phnum); - - elf_get_dynamic_info (l); - - /* Make sure we are dlopen()ing an object which has the DF_1_NOOPEN - flag set. */ - if (__builtin_expect (l->l_flags_1 & DF_1_NOOPEN, 0) - && (mode & __RTLD_DLOPEN)) - { - /* We are not supposed to load this object. Free all resources. */ - munmap ((void *) l->l_map_start, l->l_map_end - l->l_map_start); - - if (!l->l_libname->dont_free) - free (l->l_libname); - - if (l->l_phdr_allocated) - free ((void *) l->l_phdr); - - errstring = N_("shared object cannot be dlopen()ed"); - goto call_lose; - } - - if (l->l_info[DT_HASH]) - _dl_setup_hash (l); - - /* If this object has DT_SYMBOLIC set modify now its scope. We don't - have to do this for the main map. */ - if (__builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0) - && &l->l_searchlist != l->l_scope[0]) - { - /* Create an appropriate searchlist. It contains only this map. - - XXX This is the definition of DT_SYMBOLIC in SysVr4. The old - GNU ld.so implementation had a different interpretation which - is more reasonable. We are prepared to add this possibility - back as part of a GNU extension of the ELF format. */ - l->l_symbolic_searchlist.r_list = - (struct link_map **) malloc (sizeof (struct link_map *)); - - if (l->l_symbolic_searchlist.r_list == NULL) - { - errstring = N_("cannot create searchlist"); - goto call_lose_errno; - } - - l->l_symbolic_searchlist.r_list[0] = l; - l->l_symbolic_searchlist.r_nlist = 1; - - /* Now move the existing entries one back. */ - memmove (&l->l_scope[1], &l->l_scope[0], - (l->l_scope_max - 1) * sizeof (l->l_scope[0])); - - /* Now add the new entry. */ - l->l_scope[0] = &l->l_symbolic_searchlist; - } - - /* Remember whether this object must be initialized first. */ - if (l->l_flags_1 & DF_1_INITFIRST) - _dl_initfirst = l; - - /* Finally the file information. */ - l->l_dev = st.st_dev; - l->l_ino = st.st_ino; - - return l; -} - -/* Print search path. */ -static void -print_search_path (struct r_search_path_elem **list, - const char *what, const char *name) -{ - char buf[max_dirnamelen + max_capstrlen]; - int first = 1; - - _dl_debug_printf (" search path="); - - while (*list != NULL && (*list)->what == what) /* Yes, ==. */ - { - char *endp = memcpy (buf, (*list)->dirname, (*list)->dirnamelen); - size_t cnt; - endp += (*list)->dirnamelen; - - - for (cnt = 0; cnt < ncapstr; ++cnt) - if ((*list)->status[cnt] != nonexisting) - { - char *cp = memcpy (endp, capstr[cnt].str, capstr[cnt].len); - cp += capstr[cnt].len; - - if (cp == buf || (cp == buf + 1 && buf[0] == '/')) - cp[0] = '\0'; - else - cp[-1] = '\0'; - - _dl_debug_printf_c (first ? "%s" : ":%s", buf); - first = 0; - } - - ++list; - } - - if (name != NULL) - _dl_debug_printf_c ("\t\t(%s from file %s)\n", what, - name[0] ? name : _dl_argv[0]); - else - _dl_debug_printf_c ("\t\t(%s)\n", what); -} - -/* Open a file and verify it is an ELF file for this architecture. We - ignore only ELF files for other architectures. Non-ELF files and - ELF files with different header information cause fatal errors since - this could mean there is something wrong in the installation and the - user might want to know about this. */ -static int -open_verify (const char *name, struct filebuf *fbp) -{ - /* This is the expected ELF header. */ -#define ELF32_CLASS ELFCLASS32 -#define ELF64_CLASS ELFCLASS64 -#ifndef VALID_ELF_HEADER -# define VALID_ELF_HEADER(hdr,exp,size) (memcmp (hdr, exp, size) == 0) -# define VALID_ELF_OSABI(osabi) (osabi == ELFOSABI_SYSV) -# define VALID_ELF_ABIVERSION(ver) (ver == 0) -#endif - static const unsigned char expected[EI_PAD] = - { - [EI_MAG0] = ELFMAG0, - [EI_MAG1] = ELFMAG1, - [EI_MAG2] = ELFMAG2, - [EI_MAG3] = ELFMAG3, - [EI_CLASS] = ELFW(CLASS), - [EI_DATA] = byteorder, - [EI_VERSION] = EV_CURRENT, - [EI_OSABI] = ELFOSABI_SYSV, - [EI_ABIVERSION] = 0 - }; - static const struct - { - ElfW(Word) vendorlen; - ElfW(Word) datalen; - ElfW(Word) type; - char vendor[4]; - } expected_note = { 4, 16, 1, "GNU" }; - int fd; - /* Initialize it to make the compiler happy. */ - const char *errstring = NULL; - int errval = 0; - - /* Open the file. We always open files read-only. */ - fd = open (name, O_RDONLY); - if (fd != -1) - { - ElfW(Ehdr) *ehdr; - ElfW(Phdr) *phdr, *ph; - ElfW(Word) *abi_note, abi_note_buf[8]; - unsigned int osversion; - size_t maplength; - - /* We successfully openened the file. Now verify it is a file - we can use. */ - __set_errno (0); - fbp->len = __libc_read (fd, fbp->buf, sizeof (fbp->buf)); - - /* This is where the ELF header is loaded. */ - assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr))); - ehdr = (ElfW(Ehdr) *) fbp->buf; - - /* Now run the tests. */ - if (__builtin_expect (fbp->len < (ssize_t) sizeof (ElfW(Ehdr)), 0)) - { - errval = errno; - errstring = (errval == 0 - ? N_("file too short") : N_("cannot read file data")); - call_lose: - lose (errval, fd, name, NULL, NULL, errstring); - } - - /* See whether the ELF header is what we expect. */ - if (__builtin_expect (! VALID_ELF_HEADER (ehdr->e_ident, expected, - EI_PAD), 0)) - { - /* Something is wrong. */ - if (*(Elf32_Word *) &ehdr->e_ident != -#if BYTE_ORDER == LITTLE_ENDIAN - ((ELFMAG0 << (EI_MAG0 * 8)) | - (ELFMAG1 << (EI_MAG1 * 8)) | - (ELFMAG2 << (EI_MAG2 * 8)) | - (ELFMAG3 << (EI_MAG3 * 8))) -#else - ((ELFMAG0 << (EI_MAG3 * 8)) | - (ELFMAG1 << (EI_MAG2 * 8)) | - (ELFMAG2 << (EI_MAG1 * 8)) | - (ELFMAG3 << (EI_MAG0 * 8))) -#endif - ) - errstring = N_("invalid ELF header"); - else if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS)) - /* This is not a fatal error. On architectures where - 32-bit and 64-bit binaries can be run this might - happen. */ - goto close_and_out; - else if (ehdr->e_ident[EI_DATA] != byteorder) - { - if (BYTE_ORDER == BIG_ENDIAN) - errstring = N_("ELF file data encoding not big-endian"); - else - errstring = N_("ELF file data encoding not little-endian"); - } - else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) - errstring - = N_("ELF file version ident does not match current one"); - /* XXX We should be able so set system specific versions which are - allowed here. */ - else if (!VALID_ELF_OSABI (ehdr->e_ident[EI_OSABI])) - errstring = N_("ELF file OS ABI invalid"); - else if (!VALID_ELF_ABIVERSION (ehdr->e_ident[EI_ABIVERSION])) - errstring = N_("ELF file ABI version invalid"); - else - /* Otherwise we don't know what went wrong. */ - errstring = N_("internal error"); - - goto call_lose; - } - - if (__builtin_expect (ehdr->e_version, EV_CURRENT) != EV_CURRENT) - { - errstring = N_("ELF file version does not match current one"); - goto call_lose; - } - if (! __builtin_expect (elf_machine_matches_host (ehdr), 1)) - goto close_and_out; - else if (__builtin_expect (ehdr->e_phentsize, sizeof (ElfW(Phdr))) - != sizeof (ElfW(Phdr))) - { - errstring = N_("ELF file's phentsize not the expected size"); - goto call_lose; - } - else if (__builtin_expect (ehdr->e_type, ET_DYN) != ET_DYN - && __builtin_expect (ehdr->e_type, ET_EXEC) != ET_EXEC) - { - errstring = N_("only ET_DYN and ET_EXEC can be loaded"); - goto call_lose; - } - - maplength = ehdr->e_phnum * sizeof (ElfW(Phdr)); - if (ehdr->e_phoff + maplength <= fbp->len) - phdr = (void *) (fbp->buf + ehdr->e_phoff); - else - { - phdr = alloca (maplength); - lseek (fd, SEEK_SET, ehdr->e_phoff); - if (__libc_read (fd, (void *) phdr, maplength) != maplength) - { - read_error: - errval = errno; - errstring = N_("cannot read file data"); - goto call_lose; - } - } - - /* Check .note.ABI-tag if present. */ - for (ph = phdr; ph < &phdr[ehdr->e_phnum]; ++ph) - if (ph->p_type == PT_NOTE && ph->p_filesz == 32 && ph->p_align >= 4) - { - if (ph->p_offset + 32 <= fbp->len) - abi_note = (void *) (fbp->buf + ph->p_offset); - else - { - lseek (fd, SEEK_SET, ph->p_offset); - if (__libc_read (fd, (void *) abi_note_buf, 32) != 32) - goto read_error; - - abi_note = abi_note_buf; - } - - if (memcmp (abi_note, &expected_note, sizeof (expected_note))) - continue; - - osversion = (abi_note[5] & 0xff) * 65536 - + (abi_note[6] & 0xff) * 256 - + (abi_note[7] & 0xff); - if (abi_note[4] != __ABI_TAG_OS - || (_dl_osversion && _dl_osversion < osversion)) - { - close_and_out: - close (fd); - __set_errno (ENOENT); - fd = -1; - } - - break; - } - } - - return fd; -} - -/* Try to open NAME in one of the directories in *DIRSP. - Return the fd, or -1. If successful, fill in *REALNAME - with the malloc'd full directory name. If it turns out - that none of the directories in *DIRSP exists, *DIRSP is - replaced with (void *) -1, and the old value is free()d - if MAY_FREE_DIRS is true. */ - -static int -open_path (const char *name, size_t namelen, int preloaded, - struct r_search_path_struct *sps, char **realname, - struct filebuf *fbp) -{ - struct r_search_path_elem **dirs = sps->dirs; - char *buf; - int fd = -1; - const char *current_what = NULL; - int any = 0; - - buf = alloca (max_dirnamelen + max_capstrlen + namelen); - do - { - struct r_search_path_elem *this_dir = *dirs; - size_t buflen = 0; - size_t cnt; - char *edp; - int here_any = 0; - int err; - - /* If we are debugging the search for libraries print the path - now if it hasn't happened now. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0) - && current_what != this_dir->what) - { - current_what = this_dir->what; - print_search_path (dirs, current_what, this_dir->where); - } - - edp = (char *) (memcpy (buf, this_dir->dirname, this_dir->dirnamelen) + this_dir->dirnamelen); - for (cnt = 0; fd == -1 && cnt < ncapstr; ++cnt) - { - char *tmp; - /* Skip this directory if we know it does not exist. */ - if (this_dir->status[cnt] == nonexisting) - continue; - - tmp = memcpy (edp, capstr[cnt].str, capstr[cnt].len); - tmp += capstr[cnt].len; - - tmp = memcpy (tmp, name, namelen); - tmp += namelen; - buflen = ((char *) (tmp - buf)); - - /* Print name we try if this is wanted. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) - _dl_debug_printf (" trying file=%s\n", buf); - - fd = open_verify (buf, fbp); - if (this_dir->status[cnt] == unknown) - { - if (fd != -1) - this_dir->status[cnt] = existing; - else - { - /* We failed to open machine dependent library. Let's - test whether there is any directory at all. */ - struct stat64 st; - - buf[buflen - namelen - 1] = '\0'; - - if (stat64 (buf, &st) != 0 - || ! S_ISDIR (st.st_mode)) - /* The directory does not exist or it is no directory. */ - this_dir->status[cnt] = nonexisting; - else - this_dir->status[cnt] = existing; - } - } - - /* Remember whether we found any existing directory. */ - here_any |= this_dir->status[cnt] == existing; - - if (fd != -1 && __builtin_expect (preloaded, 0) - && 0) - { - /* This is an extra security effort to make sure nobody can - preload broken shared objects which are in the trusted - directories and so exploit the bugs. */ - struct stat64 st; - - if (fstat64 (fd, &st) != 0 - || (st.st_mode & S_ISUID) == 0) - { - /* The shared object cannot be tested for being SUID - or this bit is not set. In this case we must not - use this object. */ - close (fd); - fd = -1; - /* We simply ignore the file, signal this by setting - the error value which would have been set by `open'. */ - errno = ENOENT; - } - } - } - - if (fd != -1) - { - *realname = (char *) malloc (buflen); - if (*realname != NULL) - { - memcpy (*realname, buf, buflen); - return fd; - } - else - { - /* No memory for the name, we certainly won't be able - to load and link it. */ - close (fd); - return -1; - } - } - if (here_any && (err = errno) != ENOENT && err != EACCES) - /* The file exists and is readable, but something went wrong. */ - return -1; - - /* Remember whether we found anything. */ - any |= here_any; - } - while (*++dirs != NULL); - - /* Remove the whole path if none of the directories exists. */ - if (__builtin_expect (! any, 0)) - { - /* Paths which were allocated using the minimal malloc() in ld.so - must not be freed using the general free() in libc. */ - if (sps->malloced) - free (sps->dirs); - sps->dirs = (void *) -1; - } - - return -1; -} - -/* Map in the shared object file NAME. */ - -struct link_map * -internal_function -_dl_map_object (struct link_map *loader, const char *name, int preloaded, - int type, int trace_mode, int mode) -{ - int fd; - char *realname; - char *name_copy; - struct link_map *l; - struct filebuf fb; - - /* Look for this name among those already loaded. */ - for (l = _dl_loaded; l; l = l->l_next) - { - /* If the requested name matches the soname of a loaded object, - use that object. Elide this check for names that have not - yet been opened. */ - if (__builtin_expect (l->l_faked, 0) != 0) - continue; - if (!_dl_name_match_p (name, l)) - { - const char *soname; - - if (__builtin_expect (l->l_soname_added, 1) - || l->l_info[DT_SONAME] == NULL) - continue; - - soname = ((const char *) D_PTR (l, l_info[DT_STRTAB]) - + l->l_info[DT_SONAME]->d_un.d_val); - if (strcmp (name, soname) != 0) - continue; - - /* We have a match on a new name -- cache it. */ - add_name_to_object (l, soname); - l->l_soname_added = 1; - } - - /* We have a match. */ - return l; - } - - /* Display information if we are debugging. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0) && loader != NULL) - _dl_debug_printf ("\nfile=%s; needed by %s\n", name, - loader->l_name[0] ? loader->l_name : _dl_argv[0]); - - if (strchr (name, '/') == NULL) - { - /* Search for NAME in several places. */ - - size_t namelen = strlen (name) + 1; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) - _dl_debug_printf ("find library=%s; searching\n", name); - - fd = -1; - - /* When the object has the RUNPATH information we don't use any - RPATHs. */ - if (loader == NULL || loader->l_info[DT_RUNPATH] == NULL) - { - /* First try the DT_RPATH of the dependent object that caused NAME - to be loaded. Then that object's dependent, and on up. */ - for (l = loader; fd == -1 && l; l = l->l_loader) - { - if (l->l_rpath_dirs.dirs == NULL) - { - if (l->l_info[DT_RPATH] == NULL) - { - /* There is no path. */ - l->l_rpath_dirs.dirs = (void *) -1; - continue; - } - else - { - /* Make sure the cache information is available. */ - size_t ptrval = (D_PTR (l, l_info[DT_STRTAB]) - + l->l_info[DT_RPATH]->d_un.d_val); - decompose_rpath (&l->l_rpath_dirs, - (const char *) ptrval, l, "RPATH"); - } - } - - if (l->l_rpath_dirs.dirs != (void *) -1) - fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, - &realname, &fb); - } - - /* If dynamically linked, try the DT_RPATH of the executable - itself. */ - l = _dl_loaded; - if (fd == -1 && l && l->l_type != lt_loaded && l != loader - && l->l_rpath_dirs.dirs != (void *) -1) - fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, - &realname, &fb); - } - - /* Try the LD_LIBRARY_PATH environment variable. */ - if (fd == -1 && env_path_list.dirs != (void *) -1) - fd = open_path (name, namelen, preloaded, &env_path_list, - &realname, &fb); - - /* Look at the RUNPATH information for this binary. - - Note that this is no real loop. 'while' is used only to enable - us to use 'break' instead of a 'goto' to jump to the end. The - loop is always left after the first round. */ - while (fd == -1 && loader != NULL - && loader->l_runpath_dirs.dirs != (void *) -1) - { - if (loader->l_runpath_dirs.dirs == NULL) - { - if (loader->l_info[DT_RUNPATH] == NULL) - { - /* No RUNPATH. */ - loader->l_runpath_dirs.dirs = (void *) -1; - break; - } - else - { - /* Make sure the cache information is available. */ - size_t ptrval = (D_PTR (loader, l_info[DT_STRTAB]) - + loader->l_info[DT_RUNPATH]->d_un.d_val); - decompose_rpath (&loader->l_runpath_dirs, - (const char *) ptrval, loader, "RUNPATH"); - } - } - - if (loader->l_runpath_dirs.dirs != (void *) -1) - fd = open_path (name, namelen, preloaded, - &loader->l_runpath_dirs, &realname, &fb); - break; - } - - if (fd == -1 - && (__builtin_expect (! preloaded, 1) || ! 0)) - { - /* Check the list of libraries in the file /etc/ld.so.cache, - for compatibility with Linux's ldconfig program. */ - const char *cached = _dl_load_cache_lookup (name); - - if (cached != NULL) - { -#ifdef SHARED - l = loader ?: _dl_loaded; -#else - l = loader; -#endif - - /* If the loader has the DF_1_NODEFLIB flag set we must not - use a cache entry from any of these directories. */ - if ( -#ifndef SHARED - /* 'l' is always != NULL for dynamically linked objects. */ - l != NULL && -#endif - __builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0)) - { - const char *dirp = system_dirs; - unsigned int cnt = 0; - - do - { - if (memcmp (cached, dirp, system_dirs_len[cnt]) == 0) - { - /* The prefix matches. Don't use the entry. */ - cached = NULL; - break; - } - - dirp += system_dirs_len[cnt] + 1; - ++cnt; - } - while (cnt < nsystem_dirs_len); - } - - if (cached != NULL) - { - fd = open_verify (cached, &fb); - if (__builtin_expect (fd != -1, 1)) - { - realname = local_strdup (cached); - if (realname == NULL) - { - close (fd); - fd = -1; - } - } - } - } - } - - /* Finally, try the default path. */ - if (fd == -1 - && ((l = loader ?: _dl_loaded) - /* 'l' is always != NULL for dynamically linked objects. */ -#ifdef SHARED - , -#else - == NULL || -#endif - __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)) - && rtld_search_dirs.dirs != (void *) -1) - fd = open_path (name, namelen, preloaded, &rtld_search_dirs, - &realname, &fb); - - /* Add another newline when we a tracing the library loading. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) - _dl_debug_printf ("\n"); - } - else - { - /* The path may contain dynamic string tokens. */ - realname = (loader - ? expand_dynamic_string_token (loader, name) - : local_strdup (name)); - if (realname == NULL) - fd = -1; - else - { - fd = open_verify (realname, &fb); - if (__builtin_expect (fd, 0) == -1) - free (realname); - } - } - - if (__builtin_expect (fd, 0) == -1) - { - if (trace_mode) - { - /* We haven't found an appropriate library. But since we - are only interested in the list of libraries this isn't - so severe. Fake an entry with all the information we - have. */ - static const Elf_Symndx dummy_bucket = STN_UNDEF; - - /* Enter the new object in the list of loaded objects. */ - if ((name_copy = local_strdup (name)) == NULL - || (l = _dl_new_object (name_copy, name, type, loader)) == NULL) - _dl_signal_error (ENOMEM, name, NULL, - N_("cannot create shared object descriptor")); - /* Signal that this is a faked entry. */ - l->l_faked = 1; - /* Since the descriptor is initialized with zero we do not - have do this here. - l->l_reserved = 0; */ - l->l_buckets = &dummy_bucket; - l->l_nbuckets = 1; - l->l_relocated = 1; - - return l; - } - else - _dl_signal_error (errno, name, NULL, - N_("cannot open shared object file")); - } - - return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode); -} diff --git a/newlib/libc/sys/linux/dl/dl-local.h b/newlib/libc/sys/linux/dl/dl-local.h deleted file mode 100644 index 3629ab94c..000000000 --- a/newlib/libc/sys/linux/dl/dl-local.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _LOCAL_H -#include <dlfcn.h> - -#define internal_function - -/* Internally used flag. */ -#define __RTLD_DLOPEN 0x80000000 -#define __RTLD_SPROF 0x40000000 - -/* Now define the internal interfaces. */ -extern void *__dlvsym (void *__handle, __const char *__name, - __const char *__version); - -extern void *__libc_dlopen (__const char *__name); -extern void *__libc_dlsym (void *__map, __const char *__name); -extern int __libc_dlclose (void *__map); - -/* Locate shared object containing the given address. */ -extern int _dl_addr (const void *address, Dl_info *info) - internal_function; - -/* Open the shared object NAME, relocate it, and run its initializer if it - hasn't already been run. MODE is as for `dlopen' (see <dlfcn.h>). If - the object is already opened, returns its existing map. */ -extern void *_dl_open (const char *name, int mode, const void *caller) - internal_function; - -/* Close an object previously opened by _dl_open. */ -extern void _dl_close (void *map) - internal_function; - -/* Look up NAME in shared object HANDLE (which may be RTLD_DEFAULT or - RTLD_NEXT). WHO is the calling function, for RTLD_NEXT. Returns - the symbol value, which may be NULL. */ -extern void *_dl_sym (void *handle, const char *name, void *who) - internal_function; - -/* Look up version VERSION of symbol NAME in shared object HANDLE - (which may be RTLD_DEFAULT or RTLD_NEXT). WHO is the calling - function, for RTLD_NEXT. Returns the symbol value, which may be - NULL. */ -extern void *_dl_vsym (void *handle, const char *name, const char *version, - void *who) - internal_function; - -/* Call OPERATE, catching errors from `dl_signal_error'. If there is no - error, *ERRSTRING is set to null. If there is an error, *ERRSTRING is - set to a string constructed from the strings passed to _dl_signal_error, - and the error code passed is the return value and *OBJNAME is set to - the object name which experienced the problems. ERRSTRING if nonzero - points to a malloc'ed string which the caller has to free after use. - ARGS is passed as argument to OPERATE. */ -extern int _dl_catch_error (const char **objname, const char **errstring, - void (*operate) (void *), - void *args) - internal_function; - -/* Helper function for <dlfcn.h> functions. Runs the OPERATE function via - _dl_catch_error. Returns zero for success, nonzero for failure; and - arranges for `dlerror' to return the error details. - ARGS is passed as argument to OPERATE. */ -extern int _dlerror_run (void (*operate) (void *), void *args) - internal_function; - -#endif diff --git a/newlib/libc/sys/linux/dl/dl-lookup.c b/newlib/libc/sys/linux/dl/dl-lookup.c deleted file mode 100644 index 9fc296cf1..000000000 --- a/newlib/libc/sys/linux/dl/dl-lookup.c +++ /dev/null @@ -1,654 +0,0 @@ -/* Look up a symbol in the loaded objects. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <alloca.h> -#include <libintl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <ldsodefs.h> -#include "dl-hash.h" -#include <machine/dl-machine.h> -#include <bits/libc-lock.h> - -#include <assert.h> - -#define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) - -/* We need this string more than once. */ -static const char undefined_msg[] = "undefined symbol: "; - - -struct sym_val - { - const ElfW(Sym) *s; - struct link_map *m; - }; - - -#define make_string(string, rest...) \ - ({ \ - const char *all[] = { string, ## rest }; \ - size_t len, cnt; \ - char *result, *cp; \ - \ - len = 1; \ - for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \ - len += strlen (all[cnt]); \ - \ - cp = result = alloca (len); \ - for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \ - { \ - cp = strcpy (cp, all[cnt]); \ - cp += strlen(all[cnt]); \ - } \ - \ - result; \ - }) - -/* Statistics function. */ -unsigned long int _dl_num_relocations; - - -/* We have two different situations when looking up a simple: with or - without versioning. gcc is not able to optimize a single function - definition serving for both purposes so we define two functions. */ -#define VERSIONED 0 -#include "do-lookup.h" - -#define VERSIONED 1 -#include "do-lookup.h" - - -/* Add extra dependency on MAP to UNDEF_MAP. */ -static int -internal_function -add_dependency (struct link_map *undef_map, struct link_map *map) -{ - struct link_map **list; - struct link_map *runp; - unsigned int act; - unsigned int i; - int result = 0; - - /* Avoid self-references. */ - if (undef_map == map) - return 0; - - /* Make sure nobody can unload the object while we are at it. */ -#ifdef HAVE_DD_LOCK - __lock_acquire(_dl_load_lock); -#endif - - - /* Determine whether UNDEF_MAP already has a reference to MAP. First - look in the normal dependencies. */ - if (undef_map->l_searchlist.r_list != NULL) - { - list = undef_map->l_initfini; - - for (i = 0; list[i] != NULL; ++i) - if (list[i] == map) - goto out; - } - - /* No normal dependency. See whether we already had to add it - to the special list of dynamic dependencies. */ - list = undef_map->l_reldeps; - act = undef_map->l_reldepsact; - - for (i = 0; i < act; ++i) - if (list[i] == map) - goto out; - - /* The object is not yet in the dependency list. Before we add - it make sure just one more time the object we are about to - reference is still available. There is a brief period in - which the object could have been removed since we found the - definition. */ - runp = _dl_loaded; - while (runp != NULL && runp != map) - runp = runp->l_next; - - if (runp != NULL) - { - /* The object is still available. Add the reference now. */ - if (__builtin_expect (act >= undef_map->l_reldepsmax, 0)) - { - /* Allocate more memory for the dependency list. Since this - can never happen during the startup phase we can use - `realloc'. */ - void *newp; - - undef_map->l_reldepsmax += 5; - newp = realloc (undef_map->l_reldeps, - undef_map->l_reldepsmax - * sizeof (struct link_map *)); - - if (__builtin_expect (newp != NULL, 1)) - undef_map->l_reldeps = (struct link_map **) newp; - else - /* Correct the addition. */ - undef_map->l_reldepsmax -= 5; - } - - /* If we didn't manage to allocate memory for the list this is - no fatal mistake. We simply increment the use counter of the - referenced object and don't record the dependencies. This - means this increment can never be reverted and the object - will never be unloaded. This is semantically the correct - behaviour. */ - if (__builtin_expect (act < undef_map->l_reldepsmax, 1)) - undef_map->l_reldeps[undef_map->l_reldepsact++] = map; - - if (map->l_searchlist.r_list != NULL) - /* And increment the counter in the referenced object. */ - ++map->l_opencount; - else - /* We have to bump the counts for all dependencies since so far - this object was only a normal or transitive dependency. - Now it might be closed with _dl_close() directly. */ - for (list = map->l_initfini; *list != NULL; ++list) - ++(*list)->l_opencount; - - /* Display information if we are debugging. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) - _dl_debug_printf ("\ -\nfile=%s; needed by %s (relocation dependency)\n\n", - map->l_name[0] ? map->l_name : _dl_argv[0], - undef_map->l_name[0] - ? undef_map->l_name : _dl_argv[0]); - } - else - /* Whoa, that was bad luck. We have to search again. */ - result = -1; - - out: - /* Release the lock. */ -#ifdef HAVE_DD_LOCK - __lock_release(_dl_load_lock); -#endif - - - return result; -} - -static int -internal_function -_dl_do_lookup (const char *undef_name, unsigned long int hash, - const ElfW(Sym) *ref, struct sym_val *result, - struct r_scope_elem *scope, size_t i, - struct link_map *skip, int type_class); -static int -internal_function -_dl_do_lookup_versioned (const char *undef_name, unsigned long int hash, - const ElfW(Sym) *ref, struct sym_val *result, - struct r_scope_elem *scope, size_t i, - const struct r_found_version *const version, - struct link_map *skip, int type_class); - - -/* Search loaded objects' symbol tables for a definition of the symbol - UNDEF_NAME. */ - -lookup_t -internal_function -_dl_lookup_symbol (const char *undef_name, struct link_map *undef_map, - const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[], - int type_class, int explicit) -{ - unsigned long int hash = _dl_elf_hash (undef_name); - struct sym_val current_value = { NULL, NULL }; - struct r_scope_elem **scope; - int protected; - - ++_dl_num_relocations; - - /* Search the relevant loaded objects for a definition. */ - for (scope = symbol_scope; *scope; ++scope) - if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, NULL, - type_class)) - { - /* We have to check whether this would bind UNDEF_MAP to an object - in the global scope which was dynamically loaded. In this case - we have to prevent the latter from being unloaded unless the - UNDEF_MAP object is also unloaded. */ - if (__builtin_expect (current_value.m->l_type == lt_loaded, 0) - /* Don't do this for explicit lookups as opposed to implicit - runtime lookups. */ - && ! explicit - /* Add UNDEF_MAP to the dependencies. */ - && add_dependency (undef_map, current_value.m) < 0) - /* Something went wrong. Perhaps the object we tried to reference - was just removed. Try finding another definition. */ - return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope, - type_class, 0); - - break; - } - - if (__builtin_expect (current_value.s == NULL, 0)) - { - const char *reference_name = undef_map ? undef_map->l_name : NULL; - - if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) - /* We could find no value for a strong reference. */ - /* XXX We cannot translate the messages. */ - _dl_signal_cerror (0, (reference_name && reference_name[0] - ? reference_name - : (_dl_argv[0] ?: "<main program>")), - N_("relocation error"), - make_string (undefined_msg, undef_name)); - *ref = NULL; - return 0; - } - - protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) - { - const char *reference_name = undef_map ? undef_map->l_name : NULL; - - _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n", - (reference_name && reference_name[0] - ? reference_name : (_dl_argv[0] ?: "<main program>")), - current_value.m->l_name[0] - ? current_value.m->l_name : _dl_argv[0], - protected ? "protected" : "normal", undef_name); - } - - if (__builtin_expect (protected == 0, 1)) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - else - { - /* It is very tricky. We need to figure out what value to - return for the protected symbol */ - struct sym_val protected_value = { NULL, NULL }; - - for (scope = symbol_scope; *scope; ++scope) - if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, - 0, NULL, ELF_RTYPE_CLASS_PLT)) - break; - - if (protected_value.s == NULL || protected_value.m == undef_map) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - - return LOOKUP_VALUE (undef_map); - } -} - - -/* This function is nearly the same as `_dl_lookup_symbol' but it - skips in the first list all objects until SKIP_MAP is found. I.e., - it only considers objects which were loaded after the described - object. If there are more search lists the object described by - SKIP_MAP is only skipped. */ -lookup_t -internal_function -_dl_lookup_symbol_skip (const char *undef_name, - struct link_map *undef_map, const ElfW(Sym) **ref, - struct r_scope_elem *symbol_scope[], - struct link_map *skip_map) -{ - const char *reference_name = undef_map ? undef_map->l_name : NULL; - const unsigned long int hash = _dl_elf_hash (undef_name); - struct sym_val current_value = { NULL, NULL }; - struct r_scope_elem **scope; - size_t i; - int protected; - - ++_dl_num_relocations; - - /* Search the relevant loaded objects for a definition. */ - scope = symbol_scope; - for (i = 0; (*scope)->r_list[i] != skip_map; ++i) - assert (i < (*scope)->r_nlist); - - if (! _dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, i, - skip_map, 0)) - while (*++scope) - if (_dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, - skip_map, 0)) - break; - - if (__builtin_expect (current_value.s == NULL, 0)) - { - *ref = NULL; - return 0; - } - - protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) - _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n", - (reference_name && reference_name[0] - ? reference_name : (_dl_argv[0] ?: "<main program>")), - current_value.m->l_name[0] - ? current_value.m->l_name : _dl_argv[0], - protected ? "protected" : "normal", undef_name); - - if (__builtin_expect (protected == 0, 1)) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - else - { - /* It is very tricky. We need to figure out what value to - return for the protected symbol. */ - struct sym_val protected_value = { NULL, NULL }; - - if (i >= (*scope)->r_nlist - || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, - i, skip_map, ELF_RTYPE_CLASS_PLT)) - while (*++scope) - if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, - 0, skip_map, ELF_RTYPE_CLASS_PLT)) - break; - - if (protected_value.s == NULL || protected_value.m == undef_map) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - - return LOOKUP_VALUE (undef_map); - } -} - - -/* This function works like _dl_lookup_symbol but it takes an - additional arguement with the version number of the requested - symbol. - - XXX We'll see whether we need this separate function. */ -lookup_t -internal_function -_dl_lookup_versioned_symbol (const char *undef_name, - struct link_map *undef_map, const ElfW(Sym) **ref, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - int type_class, int explicit) -{ - unsigned long int hash = _dl_elf_hash (undef_name); - struct sym_val current_value = { NULL, NULL }; - struct r_scope_elem **scope; - int protected; - - ++_dl_num_relocations; - - /* Search the relevant loaded objects for a definition. */ - for (scope = symbol_scope; *scope; ++scope) - { - int res = do_lookup_versioned (undef_name, hash, *ref, ¤t_value, - *scope, 0, version, NULL, type_class); - if (res > 0) - { - /* We have to check whether this would bind UNDEF_MAP to an object - in the global scope which was dynamically loaded. In this case - we have to prevent the latter from being unloaded unless the - UNDEF_MAP object is also unloaded. */ - if (__builtin_expect (current_value.m->l_type == lt_loaded, 0) - /* Don't do this for explicit lookups as opposed to implicit - runtime lookups. */ - && ! explicit - /* Add UNDEF_MAP to the dependencies. */ - && add_dependency (undef_map, current_value.m) < 0) - /* Something went wrong. Perhaps the object we tried to reference - was just removed. Try finding another definition. */ - return _dl_lookup_versioned_symbol (undef_name, undef_map, ref, - symbol_scope, version, - type_class, 0); - - break; - } - - if (__builtin_expect (res, 0) < 0) - { - /* Oh, oh. The file named in the relocation entry does not - contain the needed symbol. */ - const char *reference_name = undef_map ? undef_map->l_name : NULL; - - /* XXX We cannot translate the message. */ - _dl_signal_cerror (0, (reference_name && reference_name[0] - ? reference_name - : (_dl_argv[0] ?: "<main program>")), - N_("relocation error"), - make_string ("symbol ", undef_name, ", version ", - version->name, - " not defined in file ", - version->filename, - " with link time reference", - res == -2 - ? " (no version symbols)" : "")); - *ref = NULL; - return 0; - } - } - - if (__builtin_expect (current_value.s == NULL, 0)) - { - if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) - { - /* We could find no value for a strong reference. */ - const char *reference_name = undef_map ? undef_map->l_name : NULL; - - /* XXX We cannot translate the message. */ - _dl_signal_cerror (0, (reference_name && reference_name[0] - ? reference_name - : (_dl_argv[0] ?: "<main program>")), NULL, - make_string (undefined_msg, undef_name, - ", version ", - version->name ?: NULL)); - } - *ref = NULL; - return 0; - } - - protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) - { - const char *reference_name = undef_map ? undef_map->l_name : NULL; - - _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n", - (reference_name && reference_name[0] - ? reference_name : (_dl_argv[0] ?: "<main program>")), - current_value.m->l_name[0] - ? current_value.m->l_name : _dl_argv[0], - protected ? "protected" : "normal", - undef_name, version->name); - } - - if (__builtin_expect (protected == 0, 1)) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - else - { - /* It is very tricky. We need to figure out what value to - return for the protected symbol */ - struct sym_val protected_value = { NULL, NULL }; - - for (scope = symbol_scope; *scope; ++scope) - if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value, - *scope, 0, version, NULL, - ELF_RTYPE_CLASS_PLT)) - break; - - if (protected_value.s == NULL || protected_value.m == undef_map) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - - return LOOKUP_VALUE (undef_map); - } -} - - -/* Similar to _dl_lookup_symbol_skip but takes an additional argument - with the version we are looking for. */ -lookup_t -internal_function -_dl_lookup_versioned_symbol_skip (const char *undef_name, - struct link_map *undef_map, - const ElfW(Sym) **ref, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - struct link_map *skip_map) -{ - const char *reference_name = undef_map ? undef_map->l_name : NULL; - const unsigned long int hash = _dl_elf_hash (undef_name); - struct sym_val current_value = { NULL, NULL }; - struct r_scope_elem **scope; - size_t i; - int protected; - - ++_dl_num_relocations; - - /* Search the relevant loaded objects for a definition. */ - scope = symbol_scope; - for (i = 0; (*scope)->r_list[i] != skip_map; ++i) - assert (i < (*scope)->r_nlist); - - if (! _dl_do_lookup_versioned (undef_name, hash, *ref, ¤t_value, - *scope, i, version, skip_map, 0)) - while (*++scope) - if (_dl_do_lookup_versioned (undef_name, hash, *ref, ¤t_value, - *scope, 0, version, skip_map, 0)) - break; - - if (__builtin_expect (current_value.s == NULL, 0)) - { - if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) - { - /* We could find no value for a strong reference. */ - const size_t len = strlen (undef_name); - char buf[sizeof undefined_msg + len]; - char *tmp; - tmp = memcpy (buf, undefined_msg, sizeof undefined_msg - 1); - tmp += (sizeof undefined_msg - 1); - - memcpy (tmp, undef_name, len + 1); - - /* XXX We cannot translate the messages. */ - _dl_signal_cerror (0, (reference_name && reference_name[0] - ? reference_name - : (_dl_argv[0] ?: "<main program>")), - NULL, buf); - } - *ref = NULL; - return 0; - } - - protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) - _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n", - (reference_name && reference_name[0] - ? reference_name : (_dl_argv[0] ?: "<main program>")), - current_value.m->l_name[0] - ? current_value.m->l_name : _dl_argv[0], - protected ? "protected" : "normal", - undef_name, version->name); - - if (__builtin_expect (protected == 0, 1)) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - else - { - /* It is very tricky. We need to figure out what value to - return for the protected symbol */ - struct sym_val protected_value = { NULL, NULL }; - - if (i >= (*scope)->r_nlist - || !_dl_do_lookup_versioned (undef_name, hash, *ref, - &protected_value, *scope, i, version, - skip_map, ELF_RTYPE_CLASS_PLT)) - while (*++scope) - if (_dl_do_lookup_versioned (undef_name, hash, *ref, - &protected_value, *scope, 0, version, - skip_map, ELF_RTYPE_CLASS_PLT)) - break; - - if (protected_value.s == NULL || protected_value.m == undef_map) - { - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); - } - - return LOOKUP_VALUE (undef_map); - } -} - - -/* Cache the location of MAP's hash table. */ - -void -internal_function -_dl_setup_hash (struct link_map *map) -{ - Elf_Symndx *hash; - Elf_Symndx nchain; - - if (!map->l_info[DT_HASH]) - return; - hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr); - - map->l_nbuckets = *hash++; - nchain = *hash++; - map->l_buckets = hash; - hash += map->l_nbuckets; - map->l_chain = hash; -} - -/* These are here so that we only inline do_lookup{,_versioned} in the common - case, not everywhere. */ -static int -internal_function -_dl_do_lookup (const char *undef_name, unsigned long int hash, - const ElfW(Sym) *ref, struct sym_val *result, - struct r_scope_elem *scope, size_t i, - struct link_map *skip, int type_class) -{ - return do_lookup (undef_name, hash, ref, result, scope, i, skip, - type_class); -} - -static int -internal_function -_dl_do_lookup_versioned (const char *undef_name, unsigned long int hash, - const ElfW(Sym) *ref, struct sym_val *result, - struct r_scope_elem *scope, size_t i, - const struct r_found_version *const version, - struct link_map *skip, int type_class) -{ - return do_lookup_versioned (undef_name, hash, ref, result, scope, i, - version, skip, type_class); -} diff --git a/newlib/libc/sys/linux/dl/dl-lookupcfg.h b/newlib/libc/sys/linux/dl/dl-lookupcfg.h deleted file mode 100644 index 810e8c7c6..000000000 --- a/newlib/libc/sys/linux/dl/dl-lookupcfg.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Configuration of lookup functions. - Copyright (C) 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* Some platforms need more information from the symbol lookup function - than just the address. But this is not generally the case. */ -#undef DL_LOOKUP_RETURNS_MAP diff --git a/newlib/libc/sys/linux/dl/dl-minimal.c b/newlib/libc/sys/linux/dl/dl-minimal.c deleted file mode 100644 index 807bfad63..000000000 --- a/newlib/libc/sys/linux/dl/dl-minimal.c +++ /dev/null @@ -1,250 +0,0 @@ -/* Minimal replacements for basic facilities used in the dynamic linker. - Copyright (C) 1995,96,97,98,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <errno.h> -#include <limits.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <ldsodefs.h> -#include <machine/weakalias.h> - -#include <assert.h> - -/* Minimal `malloc' allocator for use while loading shared libraries. - No block is ever freed. */ - -static void *alloc_ptr, *alloc_end, *alloc_last_block; - -/* Declarations of global functions. */ -extern void weak_function free (void *ptr); -extern void * weak_function realloc (void *ptr, size_t n); -extern unsigned long int weak_function __strtoul_internal -(const char *nptr, char **endptr, int base, int group); -extern unsigned long int weak_function strtoul (const char *nptr, - char **endptr, int base); - - -void * weak_function -malloc (size_t n) -{ -#ifdef MAP_ANON -#define _dl_zerofd (-1) -#else - extern int _dl_zerofd; - - if (_dl_zerofd == -1) - _dl_zerofd = _dl_sysdep_open_zero_fill (); -#define MAP_ANON 0 -#endif - - if (alloc_end == 0) - { - /* Consume any unused space in the last page of our data segment. */ - extern int _end; - alloc_ptr = &_end; - alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + _dl_pagesize - 1) - & ~(_dl_pagesize - 1)); - } - - /* Make sure the allocation pointer is ideally aligned. */ - alloc_ptr = (void *) 0 + (((alloc_ptr - (void *) 0) + sizeof (double) - 1) - & ~(sizeof (double) - 1)); - - if (alloc_ptr + n >= alloc_end) - { - /* Insufficient space left; allocate another page. */ - caddr_t page; - size_t nup = (n + _dl_pagesize - 1) & ~(_dl_pagesize - 1); - page = __mmap (0, nup, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); - assert (page != MAP_FAILED); - if (page != alloc_end) - alloc_ptr = page; - alloc_end = page + nup; - } - - alloc_last_block = (void *) alloc_ptr; - alloc_ptr += n; - return alloc_last_block; -} - -/* We use this function occasionally since the real implementation may - be optimized when it can assume the memory it returns already is - set to NUL. */ -void * weak_function -calloc (size_t nmemb, size_t size) -{ - size_t total = nmemb * size; - void *result = malloc (total); - return memset (result, '\0', total); -} - -/* This will rarely be called. */ -void weak_function -free (void *ptr) -{ - /* We can free only the last block allocated. */ - if (ptr == alloc_last_block) - alloc_ptr = alloc_last_block; -} - -/* This is only called with the most recent block returned by malloc. */ -void * weak_function -realloc (void *ptr, size_t n) -{ - void *new; - if (ptr == NULL) - return malloc (n); - assert (ptr == alloc_last_block); - alloc_ptr = alloc_last_block; - new = malloc (n); - assert (new == ptr); - return new; -} - - -/* Define our own version of the internal function used by strerror. We - only provide the messages for some common errors. This avoids pulling - in the whole error list. */ - -char * weak_function -__strerror_r (int errnum, char *buf, size_t buflen) -{ - char *msg; - - switch (errnum) - { - case ENOMEM: - msg = (char *) "Cannot allocate memory"; - break; - case EINVAL: - msg = (char *) "Invalid argument"; - break; - case ENOENT: - msg = (char *) "No such file or directory"; - break; - case EPERM: - msg = (char *) "Operation not permitted"; - break; - case EIO: - msg = (char *) "Input/output error"; - break; - case EACCES: - msg = (char *) "Permission denied"; - break; - default: - /* No need to check buffer size, all calls in the dynamic linker - provide enough space. */ - msg = (char *) "Error"; - break; - } - - return msg; -} - -#ifndef NDEBUG - -/* Define (weakly) our own assert failure function which doesn't use stdio. - If we are linked into the user program (-ldl), the normal __assert_fail - defn can override this one. */ - -void weak_function -__assert_fail (const char *assertion, - const char *file, unsigned int line, const char *function) -{ - _dl_fatal_printf ("\ -Inconsistency detected by ld.so: %s: %u: %s%sAssertion `%s' failed!\n", - file, line, function ?: "", function ? ": " : "", - assertion); - -} - -void weak_function -__assert_perror_fail (int errnum, - const char *file, unsigned int line, - const char *function) -{ - char errbuf[64]; - _dl_fatal_printf ("\ -Inconsistency detected by ld.so: %s: %u: %s%sUnexpected error: %s\n", - file, line, function ?: "", function ? ": " : "", - __strerror_r (errnum, errbuf, sizeof (errbuf))); -} - -#endif - -unsigned long int weak_function -__strtoul_internal (const char *nptr, char **endptr, int base, int group) -{ - unsigned long int result = 0; - long int sign = 1; - - while (*nptr == ' ' || *nptr == '\t') - ++nptr; - - if (*nptr == '-') - { - sign = -1; - ++nptr; - } - else if (*nptr == '+') - ++nptr; - - if (*nptr < '0' || *nptr > '9') - { - if (endptr != NULL) - *endptr = (char *) nptr; - return 0UL; - } - - assert (base == 0); - base = 10; - if (*nptr == '0') - { - if (nptr[1] == 'x' || nptr[1] == 'X') - { - base = 16; - nptr += 2; - } - else - base = 8; - } - - while (*nptr >= '0' && *nptr <= '9') - { - unsigned long int digval = *nptr - '0'; - if (result > LONG_MAX / 10 - || (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10)) - { - errno = ERANGE; - if (endptr != NULL) - *endptr = (char *) nptr; - return ULONG_MAX; - } - result *= base; - result += digval; - ++nptr; - } - - if (endptr != NULL) - *endptr = (char *) nptr; - return result * sign; -} diff --git a/newlib/libc/sys/linux/dl/dl-misc.c b/newlib/libc/sys/linux/dl/dl-misc.c deleted file mode 100644 index 1a4c297d5..000000000 --- a/newlib/libc/sys/linux/dl/dl-misc.c +++ /dev/null @@ -1,277 +0,0 @@ -/* Miscellaneous support functions for dynamic linker - Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <assert.h> -#include <fcntl.h> -#include <ldsodefs.h> -#include <limits.h> -#include <link.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/mman.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/uio.h> - -#ifndef MAP_ANON -/* This is the only dl-sysdep.c function that is actually needed at run-time - by _dl_map_object. */ - -int -_dl_sysdep_open_zero_fill (void) -{ - return __open ("/dev/zero", O_RDONLY); -} -#endif - -/* Read the whole contents of FILE into new mmap'd space with given - protections. *SIZEP gets the size of the file. On error MAP_FAILED - is returned. */ - -void * -internal_function -_dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) -{ - void *result = MAP_FAILED; - struct stat64 st; - int fd = __open (file, O_RDONLY); - if (fd >= 0) - { - if (fstat64 (fd, &st) >= 0) - { - *sizep = st.st_size; - - /* No need to map the file if it is empty. */ - if (*sizep != 0) - /* Map a copy of the file contents. */ - result = mmap (NULL, *sizep, prot, -#ifdef MAP_COPY - MAP_COPY -#else - MAP_PRIVATE -#endif -#ifdef MAP_FILE - | MAP_FILE -#endif - , fd, 0); - } - close (fd); - } - return result; -} - - -/* Descriptor to write debug messages to. */ -int _dl_debug_fd = 2; - - -/* Bare-bone printf implementation. This function only knows about - the formats and flags needed and can handle only up to 64 stripes in - the output. */ -static void -_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg) -{ - const int niovmax = 64; - struct iovec iov[niovmax]; - int niov = 0; - pid_t pid = 0; - char pidbuf[7]; - - while (*fmt != '\0') - { - const char *startp = fmt; - - if (tag_p > 0) - { - /* Generate the tag line once. It consists of the PID and a - colon followed by a tab. */ - if (pid == 0) - { - char *p = "0"; - pid = __getpid (); - assert (pid >= 0 && pid < 100000); - while (p > pidbuf) - *--p = '0'; - pidbuf[5] = ':'; - pidbuf[6] = '\t'; - } - - /* Append to the output. */ - assert (niov < niovmax); - iov[niov].iov_len = 7; - iov[niov++].iov_base = pidbuf; - - /* No more tags until we see the next newline. */ - tag_p = -1; - } - - /* Skip everything except % and \n (if tags are needed). */ - while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n')) - ++fmt; - - /* Append constant string. */ - assert (niov < niovmax); - if ((iov[niov].iov_len = fmt - startp) != 0) - iov[niov++].iov_base = (char *) startp; - - if (*fmt == '%') - { - /* It is a format specifier. */ - char fill = ' '; - int width = -1; -#if LONG_MAX != INT_MAX - int long_mod = 0; -#endif - - /* Recognize zero-digit fill flag. */ - if (*++fmt == '0') - { - fill = '0'; - ++fmt; - } - - /* See whether with comes from a parameter. Note that no other - way to specify the width is implemented. */ - if (*fmt == '*') - { - width = va_arg (arg, int); - ++fmt; - } - - /* Recognize the l modifier. It is only important on some - platforms where long and int have a different size. We - can use the same code for size_t. */ - if (*fmt == 'l' || *fmt == 'Z') - { -#if LONG_MAX != INT_MAX - long_mod = 1; -#endif - ++fmt; - } - - switch (*fmt) - { - /* Integer formatting. */ - case 'u': - case 'x': - { - /* We have to make a difference if long and int have a - different size. */ -#if LONG_MAX != INT_MAX - unsigned long int num = (long_mod - ? va_arg (arg, unsigned long int) - : va_arg (arg, unsigned int)); -#else - unsigned long int num = va_arg (arg, unsigned int); -#endif - /* We use alloca() to allocate the buffer with the most - pessimistic guess for the size. Using alloca() allows - having more than one integer formatting in a call. */ - char *buf = (char *) alloca (3 * sizeof (unsigned long int)); - char *endp = &buf[3 * sizeof (unsigned long int)]; - char *cp = "0"; - - /* Pad to the width the user specified. */ - if (width != -1) - while (endp - cp < width) - *--cp = fill; - - iov[niov].iov_base = cp; - iov[niov].iov_len = endp - cp; - ++niov; - } - break; - - case 's': - /* Get the string argument. */ - iov[niov].iov_base = va_arg (arg, char *); - iov[niov].iov_len = strlen (iov[niov].iov_base); - ++niov; - break; - - case '%': - iov[niov].iov_base = (void *) fmt; - iov[niov].iov_len = 1; - ++niov; - break; - - default: - assert (! "invalid format specifier"); - } - ++fmt; - } - else if (*fmt == '\n') - { - /* See whether we have to print a single newline character. */ - if (fmt == startp) - { - iov[niov].iov_base = (char *) startp; - iov[niov++].iov_len = 1; - } - else - /* No, just add it to the rest of the string. */ - ++iov[niov - 1].iov_len; - - /* Next line, print a tag again. */ - tag_p = 1; - ++fmt; - } - } - - /* Finally write the result. */ - writev (fd, iov, niov); -} - - -/* Write to debug file. */ -void -_dl_debug_printf (const char *fmt, ...) -{ - va_list arg; - - va_start (arg, fmt); - _dl_debug_vdprintf (_dl_debug_fd, 1, fmt, arg); - va_end (arg); -} - - -/* Write to debug file but don't start with a tag. */ -void -_dl_debug_printf_c (const char *fmt, ...) -{ - va_list arg; - - va_start (arg, fmt); - _dl_debug_vdprintf (_dl_debug_fd, -1, fmt, arg); - va_end (arg); -} - - -/* Write the given file descriptor. */ -void -_dl_dprintf (int fd, const char *fmt, ...) -{ - va_list arg; - - va_start (arg, fmt); - _dl_debug_vdprintf (fd, 0, fmt, arg); - va_end (arg); -} diff --git a/newlib/libc/sys/linux/dl/dl-object.c b/newlib/libc/sys/linux/dl/dl-object.c deleted file mode 100644 index 1e2049e25..000000000 --- a/newlib/libc/sys/linux/dl/dl-object.c +++ /dev/null @@ -1,163 +0,0 @@ -/* Storage management for the chain of loaded shared objects. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <ldsodefs.h> - -#include <assert.h> - - -/* Allocate a `struct link_map' for a new object being loaded, - and enter it into the _dl_loaded list. */ - -struct link_map * -internal_function -_dl_new_object (char *realname, const char *libname, int type, - struct link_map *loader) -{ - struct link_map *l; - int idx; - size_t libname_len = strlen (libname) + 1; - struct link_map *new; - struct libname_list *newname; - - new = (struct link_map *) calloc (sizeof (*new) + sizeof (*newname) - + libname_len, 1); - if (new == NULL) - return NULL; - - new->l_libname = newname = (struct libname_list *) (new + 1); - newname->name = (char *) memcpy (newname + 1, libname, libname_len); - /* newname->next = NULL; We use calloc therefore not necessary. */ - newname->dont_free = 1; - - new->l_name = realname; - new->l_type = type; - new->l_loader = loader; - /* new->l_global = 0; We use calloc therefore not necessary. */ - - /* Use the 'l_scope_mem' array by default for the the 'l_scope' - information. If we need more entries we will allocate a large - array dynamically. */ - new->l_scope = new->l_scope_mem; - new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]); - - /* Counter for the scopes we have to handle. */ - idx = 0; - - if (_dl_loaded != NULL) - { - l = _dl_loaded; - while (l->l_next != NULL) - l = l->l_next; - new->l_prev = l; - /* new->l_next = NULL; Would be necessary but we use calloc. */ - l->l_next = new; - - /* Add the global scope. */ - new->l_scope[idx++] = &_dl_loaded->l_searchlist; - } - else - _dl_loaded = new; - ++_dl_nloaded; - - /* If we have no loader the new object acts as it. */ - if (loader == NULL) - loader = new; - else - /* Determine the local scope. */ - while (loader->l_loader != NULL) - loader = loader->l_loader; - - /* Insert the scope if it isn't the global scope we already added. */ - if (idx == 0 || &loader->l_searchlist != new->l_scope[0]) - new->l_scope[idx] = &loader->l_searchlist; - - new->l_local_scope[0] = &new->l_searchlist; - - /* Don't try to find the origin for the main map which has the name "". */ - if (realname[0] != '\0') - { - size_t realname_len = strlen (realname) + 1; - char *origin; - char *cp; - - if (realname[0] == '/') - { - /* It is an absolute path. Use it. But we have to make a - copy since we strip out the trailing slash. */ - cp = origin = (char *) malloc (realname_len); - if (origin == NULL) - { - origin = (char *) -1; - goto out; - } - } - else - { - size_t len = realname_len; - char *result = NULL; - - /* Get the current directory name. */ - origin = NULL; - do - { - len += 128; - origin = (char *) realloc (origin, len); - } - while (origin != NULL - && (result = getcwd (origin, len - realname_len)) == NULL - && errno == ERANGE); - - if (result == NULL) - { - /* We were not able to determine the current directory. - Note that free(origin) is OK if origin == NULL. */ - free (origin); - origin = (char *) -1; - goto out; - } - - /* Find the end of the path and see whether we have to add - a slash. */ - cp = memchr (origin, '\0', strlen(origin)); - if (cp[-1] != '/') - *cp++ = '/'; - } - - /* Add the real file name. */ - memcpy (cp, realname, realname_len); - - /* Now remove the filename and the slash. Leave the slash if it - the name is something like "/foo". */ - cp = strrchr (origin, '/'); - if (cp == origin) - origin[1] = '\0'; - else - *cp = '\0'; - - out: - new->l_origin = origin; - } - - return new; -} diff --git a/newlib/libc/sys/linux/dl/dl-open.c b/newlib/libc/sys/linux/dl/dl-open.c deleted file mode 100644 index 4e068d435..000000000 --- a/newlib/libc/sys/linux/dl/dl-open.c +++ /dev/null @@ -1,487 +0,0 @@ -/* Load a shared object at runtime, relocate it, and run its initializer. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <assert.h> -#include <dlfcn.h> -#include <errno.h> -#include <libintl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/mman.h> /* Check whether MAP_COPY is defined. */ -#include <sys/param.h> -#include <ldsodefs.h> -#include <bp-sym.h> - -#include <dl-dst.h> -#include <machine/weakalias.h> - - -extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, - void (*dl_main) (const ElfW(Phdr) *phdr, - ElfW(Word) phnum, - ElfW(Addr) *user_entry)) - weak_function; - -/* This function is used to unload the cache file if necessary. */ -extern void _dl_unload_cache (void); - -int __libc_argc = 0; -char **__libc_argv = NULL; - -extern char **environ; - -extern int _dl_lazy; /* Do we do lazy relocations? */ - -/* Undefine the following for debugging. */ -/* #define SCOPE_DEBUG 1 */ -#ifdef SCOPE_DEBUG -static void show_scope (struct link_map *new); -#endif - -extern size_t _dl_platformlen; - -/* We must be carefull not to leave us in an inconsistent state. Thus we - catch any error and re-raise it after cleaning up. */ - -struct dl_open_args -{ - const char *file; - int mode; - const void *caller; - struct link_map *map; -}; - - -static int -add_to_global (struct link_map *new) -{ - struct link_map **new_global; - unsigned int to_add = 0; - unsigned int cnt; - - /* Count the objects we have to put in the global scope. */ - for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) - if (new->l_searchlist.r_list[cnt]->l_global == 0) - ++to_add; - - /* The symbols of the new objects and its dependencies are to be - introduced into the global scope that will be used to resolve - references from other dynamically-loaded objects. - - The global scope is the searchlist in the main link map. We - extend this list if necessary. There is one problem though: - since this structure was allocated very early (before the libc - is loaded) the memory it uses is allocated by the malloc()-stub - in the ld.so. When we come here these functions are not used - anymore. Instead the malloc() implementation of the libc is - used. But this means the block from the main map cannot be used - in an realloc() call. Therefore we allocate a completely new - array the first time we have to add something to the locale scope. */ - - if (_dl_global_scope_alloc == 0) - { - /* This is the first dynamic object given global scope. */ - _dl_global_scope_alloc = _dl_main_searchlist->r_nlist + to_add + 8; - new_global = (struct link_map **) - malloc (_dl_global_scope_alloc * sizeof (struct link_map *)); - if (new_global == NULL) - { - _dl_global_scope_alloc = 0; - nomem: - _dl_signal_error (ENOMEM, new->l_libname->name, NULL, - N_("cannot extend global scope")); - return 1; - } - - /* Copy over the old entries. */ - memcpy (new_global, _dl_main_searchlist->r_list, - (_dl_main_searchlist->r_nlist * sizeof (struct link_map *))); - - _dl_main_searchlist->r_list = new_global; - } - else if (_dl_main_searchlist->r_nlist + to_add > _dl_global_scope_alloc) - { - /* We have to extend the existing array of link maps in the - main map. */ - new_global = (struct link_map **) - realloc (_dl_main_searchlist->r_list, - ((_dl_global_scope_alloc + to_add + 8) - * sizeof (struct link_map *))); - if (new_global == NULL) - goto nomem; - - _dl_global_scope_alloc += to_add + 8; - _dl_main_searchlist->r_list = new_global; - } - - /* Now add the new entries. */ - for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) - { - struct link_map *map = new->l_searchlist.r_list[cnt]; - - if (map->l_global == 0) - { - map->l_global = 1; - _dl_main_searchlist->r_list[_dl_main_searchlist->r_nlist] = map; - ++_dl_main_searchlist->r_nlist; - } - } - - return 0; -} - - -static void -dl_open_worker (void *a) -{ - struct dl_open_args *args = a; - const char *file = args->file; - int mode = args->mode; - struct link_map *new, *l; - const char *dst; - int lazy; - unsigned int i; - - /* Maybe we have to expand a DST. */ - dst = strchr (file, '$'); - if (dst != NULL) - { - const void *caller = args->caller; - size_t len = strlen (file); - size_t required; - struct link_map *call_map; - char *new_file; - - /* We have to find out from which object the caller is calling. */ - call_map = NULL; - for (l = _dl_loaded; l; l = l->l_next) - if (caller >= (const void *) l->l_map_start - && caller < (const void *) l->l_map_end) - { - /* There must be exactly one DSO for the range of the virtual - memory. Otherwise something is really broken. */ - call_map = l; - break; - } - - if (call_map == NULL) - /* In this case we assume this is the main application. */ - call_map = _dl_loaded; - - /* Determine how much space we need. We have to allocate the - memory locally. */ - required = DL_DST_REQUIRED (call_map, file, len, _dl_dst_count (dst, 0)); - - /* Get space for the new file name. */ - new_file = (char *) alloca (required + 1); - - /* Generate the new file name. */ - DL_DST_SUBSTITUTE (call_map, file, new_file, 0); - - /* If the substitution failed don't try to load. */ - if (*new_file == '\0') - _dl_signal_error (0, "dlopen", NULL, - N_("empty dynamic string token substitution")); - - /* Now we have a new file name. */ - file = new_file; - } - - /* Load the named object. */ - args->map = new = _dl_map_object (NULL, file, 0, lt_loaded, 0, - mode); - - /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is - set and the object is not already loaded. */ - if (new == NULL) - { - assert (mode & RTLD_NOLOAD); - return; - } - - /* It was already open. */ - if (new->l_searchlist.r_list != NULL) - { - /* Let the user know about the opencount. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) - _dl_debug_printf ("opening file=%s; opencount == %u\n\n", - new->l_name, new->l_opencount); - - /* If the user requested the object to be in the global namespace - but it is not so far, add it now. */ - if ((mode & RTLD_GLOBAL) && new->l_global == 0) - (void) add_to_global (new); - - /* Increment just the reference counter of the object. */ - ++new->l_opencount; - - return; - } - - /* Load that object's dependencies. */ - _dl_map_object_deps (new, NULL, 0, 0); - - /* So far, so good. Now check the versions. */ - for (i = 0; i < new->l_searchlist.r_nlist; ++i) - if (new->l_searchlist.r_list[i]->l_versions == NULL) - (void) _dl_check_map_versions (new->l_searchlist.r_list[i], 0, 0); - -#ifdef SCOPE_DEBUG - show_scope (new); -#endif - - /* Only do lazy relocation if `LD_BIND_NOW' is not set. */ - lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && _dl_lazy; - - /* Relocate the objects loaded. We do this in reverse order so that copy - relocs of earlier objects overwrite the data written by later objects. */ - - l = new; - while (l->l_next) - l = l->l_next; - while (1) - { - if (! l->l_relocated) - { -#if 0 -#ifdef SHARED - if (_dl_profile != NULL) - { - /* If this here is the shared object which we want to profile - make sure the profile is started. We can find out whether - this is necessary or not by observing the `_dl_profile_map' - variable. If was NULL but is not NULL afterwars we must - start the profiling. */ - struct link_map *old_profile_map = _dl_profile_map; - - _dl_relocate_object (l, l->l_scope, 1, 1); - - if (old_profile_map == NULL && _dl_profile_map != NULL) - /* We must prepare the profiling. */ - _dl_start_profile (_dl_profile_map, _dl_profile_output); - } - else -#endif -#endif - _dl_relocate_object (l, l->l_scope, lazy, 0); - } - - if (l == new) - break; - l = l->l_prev; - } - - /* Increment the open count for all dependencies. If the file is - not loaded as a dependency here add the search list of the newly - loaded object to the scope. */ - for (i = 0; i < new->l_searchlist.r_nlist; ++i) - if (++new->l_searchlist.r_list[i]->l_opencount > 1 - && new->l_searchlist.r_list[i]->l_type == lt_loaded) - { - struct link_map *imap = new->l_searchlist.r_list[i]; - struct r_scope_elem **runp = imap->l_scope; - size_t cnt = 0; - - while (*runp != NULL) - { - /* This can happen if imap was just loaded, but during - relocation had l_opencount bumped because of relocation - dependency. Avoid duplicates in l_scope. */ - if (__builtin_expect (*runp == &new->l_searchlist, 0)) - break; - - ++cnt; - ++runp; - } - - if (*runp != NULL) - /* Avoid duplicates. */ - continue; - - if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0)) - { - /* The 'r_scope' array is too small. Allocate a new one - dynamically. */ - struct r_scope_elem **newp; - size_t new_size = imap->l_scope_max * 2; - - if (imap->l_scope == imap->l_scope_mem) - { - newp = (struct r_scope_elem **) - malloc (new_size * sizeof (struct r_scope_elem *)); - if (newp == NULL) - _dl_signal_error (ENOMEM, "dlopen", NULL, - N_("cannot create scope list")); - imap->l_scope = memcpy (newp, imap->l_scope, - cnt * sizeof (imap->l_scope[0])); - } - else - { - newp = (struct r_scope_elem **) - realloc (imap->l_scope, - new_size * sizeof (struct r_scope_elem *)); - if (newp == NULL) - _dl_signal_error (ENOMEM, "dlopen", NULL, - N_("cannot create scope list")); - imap->l_scope = newp; - } - - imap->l_scope_max = new_size; - } - - imap->l_scope[cnt++] = &new->l_searchlist; - imap->l_scope[cnt] = NULL; - } - - /* Run the initializer functions of new objects. */ - _dl_init (new, __libc_argc, __libc_argv, environ); - - /* Now we can make the new map available in the global scope. */ - if (mode & RTLD_GLOBAL) - /* Move the object in the global namespace. */ - if (add_to_global (new) != 0) - /* It failed. */ - return; - - /* Mark the object as not deletable if the RTLD_NODELETE flags was - passed. */ - if (__builtin_expect (mode & RTLD_NODELETE, 0)) - new->l_flags_1 |= DF_1_NODELETE; - - /* Let the user know about the opencount. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) - _dl_debug_printf ("opening file=%s; opencount == %u\n\n", - new->l_name, new->l_opencount); -} - - -void * -internal_function -_dl_open (const char *file, int mode, const void *caller) -{ - struct dl_open_args args; - const char *objname; - const char *errstring; - int errcode; - - if ((mode & RTLD_BINDING_MASK) == 0) - /* One of the flags must be set. */ - _dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()")); - - /* Make sure we are alone. */ -#ifdef HAVE_DD_LOCK - __lock_acquire_recursive(_dl_load_lock); -#endif - - args.file = file; - args.mode = mode; - args.caller = caller; - args.map = NULL; - errcode = _dl_catch_error (&objname, &errstring, dl_open_worker, &args); - -#ifndef MAP_COPY - /* We must munmap() the cache file. */ - _dl_unload_cache (); -#endif - - /* Release the lock. */ -#ifdef HAVE_DD_LOCK - __lock_release_recursive(_dl_load_lock); -#endif - - - if (errstring) - { - /* Some error occurred during loading. */ - char *local_errstring; - size_t len_errstring; - - /* Remove the object from memory. It may be in an inconsistent - state if relocation failed, for example. */ - if (args.map) - { - unsigned int i; - - /* Increment open counters for all objects since this has - not happened yet. */ - for (i = 0; i < args.map->l_searchlist.r_nlist; ++i) - ++args.map->l_searchlist.r_list[i]->l_opencount; - - _dl_close (args.map); - } - - /* Make a local copy of the error string so that we can release the - memory allocated for it. */ - len_errstring = strlen (errstring) + 1; - if (objname == errstring + len_errstring) - { - size_t total_len = len_errstring + strlen (objname) + 1; - local_errstring = alloca (total_len); - memcpy (local_errstring, errstring, total_len); - objname = local_errstring + len_errstring; - } - else - { - local_errstring = alloca (len_errstring); - memcpy (local_errstring, errstring, len_errstring); - } - - if (errstring != _dl_out_of_memory) - free ((char *) errstring); - - /* Reraise the error. */ - _dl_signal_error (errcode, objname, NULL, local_errstring); - } - -#ifndef SHARED - DL_STATIC_INIT (args.map); -#endif - - return args.map; -} - - -#ifdef SCOPE_DEBUG -#include <unistd.h> - -static void -show_scope (struct link_map *new) -{ - int scope_cnt; - - for (scope_cnt = 0; new->l_scope[scope_cnt] != NULL; ++scope_cnt) - { - char numbuf[2]; - unsigned int cnt; - - numbuf[0] = '0' + scope_cnt; - numbuf[1] = '\0'; - _dl_printf ("scope %s:", numbuf); - - for (cnt = 0; cnt < new->l_scope[scope_cnt]->r_nlist; ++cnt) - if (*new->l_scope[scope_cnt]->r_list[cnt]->l_name) - _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name); - else - _dl_printf (" <main>"); - - _dl_printf ("\n"); - } -} -#endif diff --git a/newlib/libc/sys/linux/dl/dl-osinfo.h b/newlib/libc/sys/linux/dl/dl-osinfo.h deleted file mode 100644 index 4976b3126..000000000 --- a/newlib/libc/sys/linux/dl/dl-osinfo.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Operating system specific code for generic dynamic loader functions. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <string.h> -#include <sys/sysctl.h> -#include <sys/utsname.h> -#include "kernel-features.h" - -#ifndef MIN -# define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#ifdef SHARED -/* This is the function used in the dynamic linker to print the fatal error - message. */ -static inline void -__attribute__ ((__noreturn__)) -dl_fatal (const char *str) -{ - _dl_dprintf (2, str); - _exit (1); -} -#endif - - -#define DL_SYSDEP_OSCHECK(FATAL) \ - do { \ - /* Test whether the kernel is new enough. This test is only \ - performed if the library is not compiled to run on all \ - kernels. */ \ - if (__LINUX_KERNEL_VERSION > 0) \ - { \ - char bufmem[64]; \ - char *buf = bufmem; \ - unsigned int version; \ - int parts; \ - char *cp; \ - struct utsname uts; \ - \ - /* Try the uname syscall */ \ - if (__uname (&uts)) \ - { \ - /* This was not successful. Now try reading the /proc \ - filesystem. */ \ - ssize_t reslen; \ - int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY); \ - if (fd == -1 \ - || (reslen = __read (fd, bufmem, sizeof (bufmem))) <= 0) \ - /* This also didn't work. We give up since we cannot \ - make sure the library can actually work. */ \ - FATAL ("FATAL: cannot determine library version\n"); \ - __close (fd); \ - buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0'; \ - } \ - else \ - buf = uts.release; \ - \ - /* Now convert it into a number. The string consists of at most \ - three parts. */ \ - version = 0; \ - parts = 0; \ - cp = buf; \ - while ((*cp >= '0') && (*cp <= '9')) \ - { \ - unsigned int here = *cp++ - '0'; \ - \ - while ((*cp >= '0') && (*cp <= '9')) \ - { \ - here *= 10; \ - here += *cp++ - '0'; \ - } \ - \ - ++parts; \ - version <<= 8; \ - version |= here; \ - \ - if (*cp++ != '.') \ - /* Another part following? */ \ - break; \ - } \ - \ - if (parts < 3) \ - version <<= 8 * (3 - parts); \ - \ - /* Now we can test with the required version. */ \ - if (version < __LINUX_KERNEL_VERSION) \ - /* Not sufficent. */ \ - FATAL ("FATAL: kernel too old\n"); \ - \ - _dl_osversion = version; \ - } \ - } while (0) diff --git a/newlib/libc/sys/linux/dl/dl-profile.c b/newlib/libc/sys/linux/dl/dl-profile.c deleted file mode 100644 index 52c533f5f..000000000 --- a/newlib/libc/sys/linux/dl/dl-profile.c +++ /dev/null @@ -1,539 +0,0 @@ -/* Profiling of shared libraries. - Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. - Based on the BSD mcount implementation. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <ldsodefs.h> -#include <sys/gmon.h> -#include <sys/gmon_out.h> -#include <sys/mman.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <atomicity.h> -#include <config.h> - -/* The LD_PROFILE feature has to be implemented different to the - normal profiling using the gmon/ functions. The problem is that an - arbitrary amount of processes simulataneously can be run using - profiling and all write the results in the same file. To provide - this mechanism one could implement a complicated mechanism to merge - the content of two profiling runs or one could extend the file - format to allow more than one data set. For the second solution we - would have the problem that the file can grow in size beyond any - limit and both solutions have the problem that the concurrency of - writing the results is a big problem. - - Another much simpler method is to use mmap to map the same file in - all using programs and modify the data in the mmap'ed area and so - also automatically on the disk. Using the MAP_SHARED option of - mmap(2) this can be done without big problems in more than one - file. - - This approach is very different from the normal profiling. We have - to use the profiling data in exactly the way they are expected to - be written to disk. But the normal format used by gprof is not usable - to do this. It is optimized for size. It writes the tags as single - bytes but this means that the following 32/64 bit values are - unaligned. - - Therefore we use a new format. This will look like this - - 0 1 2 3 <- byte is 32 bit word - 0000 g m o n - 0004 *version* <- GMON_SHOBJ_VERSION - 0008 00 00 00 00 - 000c 00 00 00 00 - 0010 00 00 00 00 - - 0014 *tag* <- GMON_TAG_TIME_HIST - 0018 ?? ?? ?? ?? - ?? ?? ?? ?? <- 32/64 bit LowPC - 0018+A ?? ?? ?? ?? - ?? ?? ?? ?? <- 32/64 bit HighPC - 0018+2*A *histsize* - 001c+2*A *profrate* - 0020+2*A s e c o - 0024+2*A n d s \0 - 0028+2*A \0 \0 \0 \0 - 002c+2*A \0 \0 \0 - 002f+2*A s - - 0030+2*A ?? ?? ?? ?? <- Count data - ... ... - 0030+2*A+K ?? ?? ?? ?? - - 0030+2*A+K *tag* <- GMON_TAG_CG_ARC - 0034+2*A+K *lastused* - 0038+2*A+K ?? ?? ?? ?? - ?? ?? ?? ?? <- FromPC#1 - 0038+3*A+K ?? ?? ?? ?? - ?? ?? ?? ?? <- ToPC#1 - 0038+4*A+K ?? ?? ?? ?? <- Count#1 - ... ... ... - 0038+(2*(CN-1)+2)*A+(CN-1)*4+K ?? ?? ?? ?? - ?? ?? ?? ?? <- FromPC#CGN - 0038+(2*(CN-1)+3)*A+(CN-1)*4+K ?? ?? ?? ?? - ?? ?? ?? ?? <- ToPC#CGN - 0038+(2*CN+2)*A+(CN-1)*4+K ?? ?? ?? ?? <- Count#CGN - - We put (for now?) no basic block information in the file since this would - introduce rase conditions among all the processes who want to write them. - - `K' is the number of count entries which is computed as - - textsize / HISTFRACTION - - `CG' in the above table is the number of call graph arcs. Normally, - the table is sparse and the profiling code writes out only the those - entries which are really used in the program run. But since we must - not extend this table (the profiling file) we'll keep them all here. - So CN can be executed in advance as - - MINARCS <= textsize*(ARCDENSITY/100) <= MAXARCS - - Now the remaining question is: how to build the data structures we can - work with from this data. We need the from set and must associate the - froms with all the associated tos. We will do this by constructing this - data structures at the program start. To do this we'll simply visit all - entries in the call graph table and add it to the appropriate list. */ - -extern int __profile_frequency (void); - -/* We define a special type to address the elements of the arc table. - This is basically the `gmon_cg_arc_record' format but it includes - the room for the tag and it uses real types. */ -struct here_cg_arc_record - { - uintptr_t from_pc; - uintptr_t self_pc; - uint32_t count; - } __attribute__ ((packed)); - -static struct here_cg_arc_record *data; - -/* Nonzero if profiling is under way. */ -static int running; - -/* This is the number of entry which have been incorporated in the toset. */ -static uint32_t narcs; -/* This is a pointer to the object representing the number of entries - currently in the mmaped file. At no point of time this has to be the - same as NARCS. If it is equal all entries from the file are in our - lists. */ -static volatile uint32_t *narcsp; - -static volatile uint16_t *kcount; -static size_t kcountsize; - -struct here_fromstruct - { - struct here_cg_arc_record volatile *here; - uint16_t link; - }; - -static volatile uint16_t *tos; - -static struct here_fromstruct *froms; -static uint32_t fromlimit; -static volatile uint32_t fromidx; - -static uintptr_t lowpc; -static size_t textsize; -static unsigned int hashfraction; -static unsigned int log_hashfraction; - - - -/* Set up profiling data to profile object desribed by MAP. The output - file is found (or created) in OUTPUT_DIR. */ -void -internal_function -_dl_start_profile (struct link_map *map, const char *output_dir) -{ - char *filename; - int fd; - struct stat64 st; - const ElfW(Phdr) *ph; - ElfW(Addr) mapstart = ~((ElfW(Addr)) 0); - ElfW(Addr) mapend = 0; - struct gmon_hdr gmon_hdr; - struct gmon_hist_hdr hist_hdr; - char *hist, *cp, *tmp; - size_t idx; - size_t tossize; - size_t fromssize; - uintptr_t highpc; - struct gmon_hdr *addr = NULL; - off_t expected_size; - /* See profil(2) where this is described. */ - int s_scale; -#define SCALE_1_TO_1 0x10000L - - /* Compute the size of the sections which contain program code. */ - for (ph = map->l_phdr; ph < &map->l_phdr[map->l_phnum]; ++ph) - if (ph->p_type == PT_LOAD && (ph->p_flags & PF_X)) - { - ElfW(Addr) start = (ph->p_vaddr & ~(_dl_pagesize - 1)); - ElfW(Addr) end = ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1) - & ~(_dl_pagesize - 1)); - - if (start < mapstart) - mapstart = start; - if (end > mapend) - mapend = end; - } - - /* Now we can compute the size of the profiling data. This is done - with the same formulars as in `monstartup' (see gmon.c). */ - running = 0; - lowpc = ROUNDDOWN (mapstart + map->l_addr, - HISTFRACTION * sizeof (HISTCOUNTER)); - highpc = ROUNDUP (mapend + map->l_addr, - HISTFRACTION * sizeof (HISTCOUNTER)); - textsize = highpc - lowpc; - kcountsize = textsize / HISTFRACTION; - hashfraction = HASHFRACTION; - if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) - /* If HASHFRACTION is a power of two, mcount can use shifting - instead of integer division. Precompute shift amount. */ - log_hashfraction = ffs (hashfraction * sizeof (*froms)) - 1; - else - log_hashfraction = -1; - tossize = textsize / HASHFRACTION; - fromlimit = textsize * ARCDENSITY / 100; - if (fromlimit < MINARCS) - fromlimit = MINARCS; - if (fromlimit > MAXARCS) - fromlimit = MAXARCS; - fromssize = fromlimit * sizeof (struct here_fromstruct); - - expected_size = (sizeof (struct gmon_hdr) - + 4 + sizeof (struct gmon_hist_hdr) + kcountsize - + 4 + 4 + fromssize * sizeof (struct here_cg_arc_record)); - - /* Create the gmon_hdr we expect or write. */ - memset (&gmon_hdr, '\0', sizeof (struct gmon_hdr)); - memcpy (&gmon_hdr.cookie[0], GMON_MAGIC, sizeof (gmon_hdr.cookie)); - *(int32_t *) gmon_hdr.version = GMON_SHOBJ_VERSION; - - /* Create the hist_hdr we expect or write. */ - *(char **) hist_hdr.low_pc = (char *) mapstart; - *(char **) hist_hdr.high_pc = (char *) mapend; - *(int32_t *) hist_hdr.hist_size = kcountsize / sizeof (HISTCOUNTER); - *(int32_t *) hist_hdr.prof_rate = __profile_frequency (); - strncpy (hist_hdr.dimen, "seconds", sizeof (hist_hdr.dimen)); - hist_hdr.dimen_abbrev = 's'; - - /* First determine the output name. We write in the directory - OUTPUT_DIR and the name is composed from the shared objects - soname (or the file name) and the ending ".profile". */ - filename = (char *) alloca (strlen (output_dir) + 1 + strlen (_dl_profile) - + sizeof ".profile"); - cp = strcpy (filename, output_dir); - cp += strlen (output_dir); - *cp++ = '/'; - tmp = strcpy (cp, _dl_profile); - tmp += strlen (_dl_profile); - strcpy (tmp, ".profile"); - -#ifdef O_NOFOLLOW -# define EXTRA_FLAGS | O_NOFOLLOW -#else -# define EXTRA_FLAGS -#endif - fd = __open (filename, O_RDWR | O_CREAT EXTRA_FLAGS); - if (fd == -1) - { - /* We cannot write the profiling data so don't do anything. */ - char buf[400]; - _dl_error_printf ("%s: cannot open file: %s\n", filename, - __strerror_r (errno, buf, sizeof buf)); - return; - } - - if (fstat64 (fd, &st) < 0 || !S_ISREG (st.st_mode)) - { - /* Not stat'able or not a regular file => don't use it. */ - char buf[400]; - int errnum = errno; - __close (fd); - _dl_error_printf ("%s: cannot stat file: %s\n", filename, - __strerror_r (errnum, buf, sizeof buf)); - return; - } - - /* Test the size. If it does not match what we expect from the size - values in the map MAP we don't use it and warn the user. */ - if (st.st_size == 0) - { - /* We have to create the file. */ - char buf[_dl_pagesize]; - - memset (buf, '\0', _dl_pagesize); - - if (__lseek (fd, expected_size & ~(_dl_pagesize - 1), SEEK_SET) == -1) - { - char buf[400]; - int errnum; - cannot_create: - errnum = errno; - __close (fd); - _dl_error_printf ("%s: cannot create file: %s\n", filename, - __strerror_r (errnum, buf, sizeof buf)); - return; - } - - if (TEMP_FAILURE_RETRY (__libc_write (fd, buf, (expected_size - & (_dl_pagesize - 1)))) - < 0) - goto cannot_create; - } - else if (st.st_size != expected_size) - { - __close (fd); - wrong_format: - - if (addr != NULL) - __munmap ((void *) addr, expected_size); - - _dl_error_printf ("%s: file is no correct profile data file for `%s'\n", - filename, _dl_profile); - return; - } - - addr = (struct gmon_hdr *) __mmap (NULL, expected_size, PROT_READ|PROT_WRITE, - MAP_SHARED|MAP_FILE, fd, 0); - if (addr == (struct gmon_hdr *) MAP_FAILED) - { - char buf[400]; - int errnum = errno; - __close (fd); - _dl_error_printf ("%s: cannot map file: %s\n", filename, - __strerror_r (errnum, buf, sizeof buf)); - return; - } - - /* We don't need the file desriptor anymore. */ - __close (fd); - - /* Pointer to data after the header. */ - hist = (char *) (addr + 1); - kcount = (uint16_t *) ((char *) hist + sizeof (uint32_t) - + sizeof (struct gmon_hist_hdr)); - - /* Compute pointer to array of the arc information. */ - narcsp = (uint32_t *) ((char *) kcount + kcountsize + sizeof (uint32_t)); - data = (struct here_cg_arc_record *) ((char *) narcsp + sizeof (uint32_t)); - - if (st.st_size == 0) - { - /* Create the signature. */ - memcpy (addr, &gmon_hdr, sizeof (struct gmon_hdr)); - - *(uint32_t *) hist = GMON_TAG_TIME_HIST; - memcpy (hist + sizeof (uint32_t), &hist_hdr, - sizeof (struct gmon_hist_hdr)); - - narcsp[-1] = GMON_TAG_CG_ARC; - } - else - { - /* Test the signature in the file. */ - if (memcmp (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0 - || *(uint32_t *) hist != GMON_TAG_TIME_HIST - || memcmp (hist + sizeof (uint32_t), &hist_hdr, - sizeof (struct gmon_hist_hdr)) != 0 - || narcsp[-1] != GMON_TAG_CG_ARC) - goto wrong_format; - } - - /* Allocate memory for the froms data and the pointer to the tos records. */ - tos = (uint16_t *) calloc (tossize + fromssize, 1); - if (tos == NULL) - { - __munmap ((void *) addr, expected_size); - _dl_fatal_printf ("Out of memory while initializing profiler\n"); - /* NOTREACHED */ - } - - froms = (struct here_fromstruct *) ((char *) tos + tossize); - fromidx = 0; - - /* Now we have to process all the arc count entries. BTW: it is - not critical whether the *NARCSP value changes meanwhile. Before - we enter a new entry in to toset we will check that everything is - available in TOS. This happens in _dl_mcount. - - Loading the entries in reverse order should help to get the most - frequently used entries at the front of the list. */ - for (idx = narcs = MIN (*narcsp, fromlimit); idx > 0; ) - { - size_t to_index; - size_t newfromidx; - --idx; - to_index = (data[idx].self_pc / (hashfraction * sizeof (*tos))); - newfromidx = fromidx++; - froms[newfromidx].here = &data[idx]; - froms[newfromidx].link = tos[to_index]; - tos[to_index] = newfromidx; - } - - /* Setup counting data. */ - if (kcountsize < highpc - lowpc) - { -#if 0 - s_scale = ((double) kcountsize / (highpc - lowpc)) * SCALE_1_TO_1; -#else - size_t range = highpc - lowpc; - size_t quot = range / kcountsize; - - if (quot >= SCALE_1_TO_1) - s_scale = 1; - else if (quot >= SCALE_1_TO_1 / 256) - s_scale = SCALE_1_TO_1 / quot; - else if (range > ULONG_MAX / 256) - s_scale = (SCALE_1_TO_1 * 256) / (range / (kcountsize / 256)); - else - s_scale = (SCALE_1_TO_1 * 256) / ((range * 256) / kcountsize); -#endif - } - else - s_scale = SCALE_1_TO_1; - - /* Start the profiler. */ - profil ((void *) kcount, kcountsize, lowpc, s_scale); - - /* Turn on profiling. */ - running = 1; -} - - -void -_dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc) -{ - volatile uint16_t *topcindex; - size_t i, fromindex; - struct here_fromstruct *fromp; - - if (! running) - return; - - /* Compute relative addresses. The shared object can be loaded at - any address. The value of frompc could be anything. We cannot - restrict it in any way, just set to a fixed value (0) in case it - is outside the allowed range. These calls show up as calls from - <external> in the gprof output. */ - frompc -= lowpc; - if (frompc >= textsize) - frompc = 0; - selfpc -= lowpc; - if (selfpc >= textsize) - goto done; - - /* Getting here we now have to find out whether the location was - already used. If yes we are lucky and only have to increment a - counter (this also has to be atomic). If the entry is new things - are getting complicated... */ - - /* Avoid integer divide if possible. */ - if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) - i = selfpc >> log_hashfraction; - else - i = selfpc / (hashfraction * sizeof (*tos)); - - topcindex = &tos[i]; - fromindex = *topcindex; - - if (fromindex == 0) - goto check_new_or_add; - - fromp = &froms[fromindex]; - - /* We have to look through the chain of arcs whether there is already - an entry for our arc. */ - while (fromp->here->from_pc != frompc) - { - if (fromp->link != 0) - do - fromp = &froms[fromp->link]; - while (fromp->link != 0 && fromp->here->from_pc != frompc); - - if (fromp->here->from_pc != frompc) - { - topcindex = &fromp->link; - - check_new_or_add: - /* Our entry is not among the entries we read so far from the - data file. Now see whether we have to update the list. */ - while (narcs != *narcsp && narcs < fromlimit) - { - size_t to_index; - size_t newfromidx; - to_index = (data[narcs].self_pc - / (hashfraction * sizeof (*tos))); - newfromidx = exchange_and_add (&fromidx, 1) + 1; - froms[newfromidx].here = &data[narcs]; - froms[newfromidx].link = tos[to_index]; - tos[to_index] = newfromidx; - atomic_add (&narcs, 1); - } - - /* If we still have no entry stop searching and insert. */ - if (*topcindex == 0) - { - uint32_t newarc = exchange_and_add (narcsp, 1); - - /* In rare cases it could happen that all entries in FROMS are - occupied. So we cannot count this anymore. */ - if (newarc >= fromlimit) - goto done; - - *topcindex = exchange_and_add (&fromidx, 1) + 1; - fromp = &froms[*topcindex]; - - fromp->here = &data[newarc]; - data[newarc].from_pc = frompc; - data[newarc].self_pc = selfpc; - data[newarc].count = 0; - fromp->link = 0; - atomic_add (&narcs, 1); - - break; - } - - fromp = &froms[*topcindex]; - } - else - /* Found in. */ - break; - } - - /* Increment the counter. */ - atomic_add (&fromp->here->count, 1); - - done: - ; -} diff --git a/newlib/libc/sys/linux/dl/dl-profstub.c b/newlib/libc/sys/linux/dl/dl-profstub.c deleted file mode 100644 index 41758864b..000000000 --- a/newlib/libc/sys/linux/dl/dl-profstub.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Helper definitions for profiling of shared libraries. - Copyright (C) 1998, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <dlfcn.h> -#include <elf.h> -#include <ldsodefs.h> -#include <libc-symbols.h> - -/* This is the map for the shared object we profile. It is defined here - only because we test for this value being NULL or not. */ -extern struct link_map *_dl_profile_map; - - -void -_dl_mcount_wrapper (void *selfpc) -{ - _dl_mcount ((ElfW(Addr)) RETURN_ADDRESS (0), (ElfW(Addr)) selfpc); -} - - -void -_dl_mcount_wrapper_check (void *selfpc) -{ - if (_dl_profile_map != NULL) - _dl_mcount ((ElfW(Addr)) RETURN_ADDRESS (0), (ElfW(Addr)) selfpc); -} diff --git a/newlib/libc/sys/linux/dl/dl-reloc.c b/newlib/libc/sys/linux/dl/dl-reloc.c deleted file mode 100644 index 0bffa4e76..000000000 --- a/newlib/libc/sys/linux/dl/dl-reloc.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Relocate a shared object and resolve its references to other loaded objects. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <errno.h> -#include <libintl.h> -#include <stdlib.h> -#include <unistd.h> -#include <ldsodefs.h> -#include <sys/mman.h> -#include <sys/param.h> -#include <sys/types.h> -#include "dynamic-link.h" - -/* Statistics function. */ -unsigned long int _dl_num_cache_relocations; - - -void -_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], - int lazy, int consider_profiling) -{ - struct textrels - { - caddr_t start; - size_t len; - int prot; - struct textrels *next; - } *textrels = NULL; - /* Initialize it to make the compiler happy. */ - const char *errstring = NULL; - - if (l->l_relocated) - return; - - /* If DT_BIND_NOW is set relocate all references in this object. We - do not do this if we are profiling, of course. */ - if (!consider_profiling - && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0)) - lazy = 0; - - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_RELOC, 0)) - _dl_printf ("\nrelocation processing: %s%s\n", - l->l_name[0] ? l->l_name : _dl_argv[0], lazy ? " (lazy)" : ""); - - /* DT_TEXTREL is now in level 2 and might phase out at some time. - But we rewrite the DT_FLAGS entry to a DT_TEXTREL entry to make - testing easier and therefore it will be available at all time. */ - if (__builtin_expect (l->l_info[DT_TEXTREL] != NULL, 0)) - { - /* Bletch. We must make read-only segments writable - long enough to relocate them. */ - const ElfW(Phdr) *ph; - for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph) - if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0) - { - struct textrels *newp; - - newp = (struct textrels *) alloca (sizeof (*newp)); - newp->len = (((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1) - & ~(_dl_pagesize - 1)) - - (ph->p_vaddr & ~(_dl_pagesize - 1))); - newp->start = ((ph->p_vaddr & ~(_dl_pagesize - 1)) - + (caddr_t) l->l_addr); - - if (mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0) - { - errstring = N_("cannot make segment writable for relocation"); - call_error: - _dl_signal_error (errno, l->l_name, NULL, errstring); - } - -#if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7 - newp->prot = (PF_TO_PROT - >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf; -#else - newp->prot = 0; - if (ph->p_flags & PF_R) - newp->prot |= PROT_READ; - if (ph->p_flags & PF_W) - newp->prot |= PROT_WRITE; - if (ph->p_flags & PF_X) - newp->prot |= PROT_EXEC; -#endif - newp->next = textrels; - textrels = newp; - } - } - - { - /* Do the actual relocation of the object's GOT and other data. */ - - /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ -#define RESOLVE_MAP(ref, version, r_type, scope) \ - (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ - ? ((__builtin_expect ((*ref) == map->l_lookup_cache.sym, 0) \ - && elf_machine_type_class (r_type) == map->l_lookup_cache.type_class)\ - ? (++_dl_num_cache_relocations, \ - (*ref) = map->l_lookup_cache.ret, \ - map->l_lookup_cache.value) \ - : ({ lookup_t _lr; \ - int _tc = elf_machine_type_class (r_type); \ - map->l_lookup_cache.type_class = _tc; \ - map->l_lookup_cache.sym = (*ref); \ - _lr = ((version) != NULL && (version)->hash != 0 \ - ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, \ - map, (ref), scope, \ - (version), _tc, 0) \ - : _dl_lookup_symbol (strtab + (*ref)->st_name, map, (ref),\ - scope, _tc, 0)); \ - map->l_lookup_cache.ret = (*ref); \ - map->l_lookup_cache.value = _lr; })) \ - : map) -#define RESOLVE(ref, version, r_type, scope) \ - (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ - ? ((__builtin_expect ((*ref) == map->l_lookup_cache.sym, 0) \ - && elf_machine_type_class (r_type) == map->l_lookup_cache.type_class)\ - ? (++_dl_num_cache_relocations, \ - (*ref) = map->l_lookup_cache.ret, \ - map->l_lookup_cache.value) \ - : ({ lookup_t _lr; \ - int _tc = elf_machine_type_class (r_type); \ - map->l_lookup_cache.type_class = _tc; \ - map->l_lookup_cache.sym = (*ref); \ - _lr = ((version) != NULL && (version)->hash != 0 \ - ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, \ - map, (ref), scope, \ - (version), _tc, 0) \ - : _dl_lookup_symbol (strtab + (*ref)->st_name, map, (ref),\ - scope, _tc, 0)); \ - map->l_lookup_cache.ret = (*ref); \ - map->l_lookup_cache.value = _lr; })) \ - : map->l_addr) - -#include "dynamic-link.h" - - ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling); - - if (__builtin_expect (consider_profiling, 0)) - { - /* Allocate the array which will contain the already found - relocations. If the shared object lacks a PLT (for example - if it only contains lead function) the l_info[DT_PLTRELSZ] - will be NULL. */ - if (l->l_info[DT_PLTRELSZ] == NULL) - { - errstring = N_("%s: profiler found no PLTREL in object %s\n"); - fatal: - _dl_fatal_printf (errstring, - _dl_argv[0] ?: "<program name unknown>", - l->l_name); - } - - l->l_reloc_result = - (ElfW(Addr) *) calloc (sizeof (ElfW(Addr)), - l->l_info[DT_PLTRELSZ]->d_un.d_val); - if (l->l_reloc_result == NULL) - { - errstring = N_("\ -%s: profiler out of memory shadowing PLTREL of %s\n"); - goto fatal; - } - } - } - - /* Mark the object so we know this work has been done. */ - l->l_relocated = 1; - - /* Undo the segment protection changes. */ - while (__builtin_expect (textrels != NULL, 0)) - { - if (mprotect (textrels->start, textrels->len, textrels->prot) < 0) - { - errstring = N_("cannot restore segment prot after reloc"); - goto call_error; - } - - textrels = textrels->next; - } -} - -#include <machine/dl-machine.h> - -void -internal_function -_dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt) -{ - /* XXX We cannot translate these messages. */ - static const char msg[2][32] = { "unexpected reloc type", - "unexpected PLT reloc type" }; - char msgbuf[sizeof (msg[0])]; - - strcpy (msgbuf, msg[plt]); - - _dl_signal_error (0, map->l_name, NULL, msgbuf); -} diff --git a/newlib/libc/sys/linux/dl/dl-runtime.c b/newlib/libc/sys/linux/dl/dl-runtime.c deleted file mode 100644 index 4fb81cfaf..000000000 --- a/newlib/libc/sys/linux/dl/dl-runtime.c +++ /dev/null @@ -1,233 +0,0 @@ -/* On-demand PLT fixup for shared objects. - Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <alloca.h> -#include <stdlib.h> -#include <unistd.h> -#include <ldsodefs.h> -#include "dynamic-link.h" - -#ifndef __attribute_used__ -#define __attribute_used__ -#endif - -#if !defined ELF_MACHINE_NO_RELA || ELF_MACHINE_NO_REL -# define PLTREL ElfW(Rela) -#else -# define PLTREL ElfW(Rel) -#endif - -#ifndef VERSYMIDX -# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) -#endif - - -/* This function is called through a special trampoline from the PLT the - first time each PLT entry is called. We must perform the relocation - specified in the PLT of the given shared object, and return the resolved - function address to the trampoline, which will restart the original call - to that address. Future calls will bounce directly from the PLT to the - function. */ - -#ifndef ELF_MACHINE_NO_PLT -static ElfW(Addr) __attribute__ ((regparm (2), used)) -fixup ( -# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS - ELF_MACHINE_RUNTIME_FIXUP_ARGS, -# endif - /* GKM FIXME: Fix trampoline to pass bounds so we can do - without the `__unbounded' qualifier. */ - struct link_map *__unbounded l, ElfW(Word) reloc_offset) -{ - const ElfW(Sym) *const symtab - = (const void *) D_PTR (l, l_info[DT_SYMTAB]); - const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); - - const PLTREL *const reloc - = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset); - const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; - void *const rel_addr = (void *)(l->l_addr + reloc->r_offset); - lookup_t result; - ElfW(Addr) value; - - /* The use of `alloca' here looks ridiculous but it helps. The goal is - to prevent the function from being inlined and thus optimized out. - There is no official way to do this so we use this trick. gcc never - inlines functions which use `alloca'. */ - alloca (sizeof (int)); - - /* Sanity check that we're really looking at a PLT relocation. */ - assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - - /* Look up the target symbol. If the normal lookup rules are not - used don't look in the global scope. */ - if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) - { - switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) - { - default: - { - const ElfW(Half) *vernum = - (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); - ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; - const struct r_found_version *version = &l->l_versions[ndx]; - - if (version->hash != 0) - { - result = _dl_lookup_versioned_symbol (strtab + sym->st_name, - l, &sym, l->l_scope, - version, - ELF_RTYPE_CLASS_PLT, 0); - break; - } - } - case 0: - result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, - l->l_scope, ELF_RTYPE_CLASS_PLT, 0); - } - - /* Currently result contains the base load address (or link map) - of the object that defines sym. Now add in the symbol - offset. */ - value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0); - } - else - { - /* We already found the symbol. The module (and therefore its load - address) is also known. */ - value = l->l_addr + sym->st_value; -#ifdef DL_LOOKUP_RETURNS_MAP - result = l; -#endif - } - - /* And now perhaps the relocation addend. */ - value = elf_machine_plt_value (l, reloc, value); - - /* Finally, fix up the plt itself. */ - if (__builtin_expect (_dl_bind_not, 0)) - return value; - - return elf_machine_fixup_plt (l, result, reloc, rel_addr, value); -} -#endif - -#if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__ - -static ElfW(Addr) __attribute__ ((regparm (3), used)) -profile_fixup ( -#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS - ELF_MACHINE_RUNTIME_FIXUP_ARGS, -#endif - struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr) -{ - void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount; - ElfW(Addr) *resultp; - lookup_t result; - ElfW(Addr) value; - - /* The use of `alloca' here looks ridiculous but it helps. The goal is - to prevent the function from being inlined, and thus optimized out. - There is no official way to do this so we use this trick. gcc never - inlines functions which use `alloca'. */ - alloca (sizeof (int)); - - /* This is the address in the array where we store the result of previous - relocations. */ - resultp = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)]; - - value = *resultp; - if (value == 0) - { - /* This is the first time we have to relocate this object. */ - const ElfW(Sym) *const symtab - = (const void *) D_PTR (l, l_info[DT_SYMTAB]); - const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); - - const PLTREL *const reloc - = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset); - const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; - - /* Sanity check that we're really looking at a PLT relocation. */ - assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - - /* Look up the target symbol. If the symbol is marked STV_PROTECTED - don't look in the global scope. */ - if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) - { - switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) - { - default: - { - const ElfW(Half) *vernum = - (const void *) D_PTR (l,l_info[VERSYMIDX (DT_VERSYM)]); - ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; - const struct r_found_version *version = &l->l_versions[ndx]; - - if (version->hash != 0) - { - result = _dl_lookup_versioned_symbol(strtab + sym->st_name, - l, &sym, l->l_scope, - version, - ELF_RTYPE_CLASS_PLT, - 0); - break; - } - } - case 0: - result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, - l->l_scope, ELF_RTYPE_CLASS_PLT, 0); - } - - /* Currently result contains the base load address (or link map) - of the object that defines sym. Now add in the symbol - offset. */ - value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0); - } - else - { - /* We already found the symbol. The module (and therefore its load - address) is also known. */ - value = l->l_addr + sym->st_value; -#ifdef DL_LOOKUP_RETURNS_MAP - result = l; -#endif - } - /* And now perhaps the relocation addend. */ - value = elf_machine_plt_value (l, reloc, value); - - /* Store the result for later runs. */ - if (__builtin_expect (! _dl_bind_not, 1)) - *resultp = value; - } - - (*mcount_fct) (retaddr, value); - - return value; -} - -#endif /* PROF && ELF_MACHINE_NO_PLT */ - - -/* This macro is defined in dl-machine.h to define the entry point called - by the PLT. The `fixup' function above does the real work, but a little - more twiddling is needed to get the stack right and jump to the address - finally resolved. */ - -ELF_MACHINE_RUNTIME_TRAMPOLINE diff --git a/newlib/libc/sys/linux/dl/dl-support.c b/newlib/libc/sys/linux/dl/dl-support.c deleted file mode 100644 index ce5349153..000000000 --- a/newlib/libc/sys/linux/dl/dl-support.c +++ /dev/null @@ -1,184 +0,0 @@ -/* Support for dynamic linking code in static libc. - Copyright (C) 1996, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* This file defines some things that for the dynamic linker are defined in - rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */ - -#include <errno.h> -#include <libintl.h> -#include <stdlib.h> -#include <unistd.h> -#include <dirent.h> -#include <pthread.h> -#include <ldsodefs.h> -#include <machine/dl-machine.h> -#include <dl-librecon.h> -#include <unsecvars.h> -#include <machine/hp-timing.h> - -char *__progname = "newlib"; -char **_dl_argv = &__progname; /* This is checked for some error messages. */ - -/* Name of the architecture. */ -const char *_dl_platform; -size_t _dl_platformlen; - -int _dl_debug_mask; -int _dl_lazy; -/* XXX I know about at least one case where we depend on the old weak - behavior (it has to do with librt). Until we get DSO groups implemented - we have to make this the default. Bummer. --drepper */ -#if 0 -int _dl_dynamic_weak; -#else -int _dl_dynamic_weak = 1; -#endif - -/* If nonzero print warnings about problematic situations. */ -int _dl_verbose; - -/* Structure to store information about search paths. */ -struct r_search_path *_dl_search_paths; - -/* We never do profiling. */ -const char *_dl_profile; - -/* Names of shared object for which the RUNPATHs and RPATHs should be - ignored. */ -const char *_dl_inhibit_rpath; - -/* The map for the object we will profile. */ -struct link_map *_dl_profile_map; - -/* This is the address of the last stack address ever used. */ -void *__libc_stack_end; - -/* Path where the binary is found. */ -const char *_dl_origin_path; - -/* Nonzero if runtime lookup should not update the .got/.plt. */ -int _dl_bind_not; - -/* Initially empty list of loaded objects. */ -struct link_map *_dl_loaded; -/* Number of object in the _dl_loaded list. */ -unsigned int _dl_nloaded; - -/* Fake scope. In dynamically linked binaries this is the scope of the - main application but here we don't have something like this. So - create a fake scope containing nothing. */ -struct r_scope_elem _dl_initial_searchlist; -/* Variable which can be used in lookup to process the global scope. */ -struct r_scope_elem *_dl_global_scope[2] = { &_dl_initial_searchlist, NULL }; -/* This is a global pointer to this structure which is public. It is - used by dlopen/dlclose to add and remove objects from what is regarded - to be the global scope. */ -struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist; - -/* Nonzero during startup. */ -int _dl_starting_up = 1; - -/* We expect less than a second for relocation. */ -#ifdef HP_SMALL_TIMING_AVAIL -# undef HP_TIMING_AVAIL -# define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL -#endif - -/* Initial value of the CPU clock. */ -#ifndef HP_TIMING_NONAVAIL -hp_timing_t _dl_cpuclock_offset; -#endif - -/* During the program run we must not modify the global data of - loaded shared object simultanously in two threads. Therefore we - protect `_dl_open' and `_dl_close' in dl-close.c. - - This must be a recursive lock since the initializer function of - the loaded object might as well require a call to this function. - At this time it is not anymore a problem to modify the tables. */ -__LOCK_INIT_RECURSIVE(, _dl_load_lock) - - -#ifdef HAVE_AUX_VECTOR -extern int _dl_clktck; - -void -internal_function -_dl_aux_init (ElfW(auxv_t) *av) -{ - for (; av->a_type != AT_NULL; ++av) - switch (av->a_type) - { - case AT_PAGESZ: - _dl_pagesize = av->a_un.a_val; - break; - case AT_CLKTCK: - _dl_clktck = av->a_un.a_val; - break; - } -} -#endif - -void non_dynamic_init (void) __attribute__ ((unused)); - -void -non_dynamic_init (void) -{ - if (HP_TIMING_AVAIL) - HP_TIMING_NOW (_dl_cpuclock_offset); - - if (!_dl_pagesize) - _dl_pagesize = __getpagesize (); - - _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; - - /* Initialize the data structures for the search paths for shared - objects. */ - _dl_init_paths (getenv ("LD_LIBRARY_PATH")); - - _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; - - _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0'; - - _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; - -#ifdef DL_PLATFORM_INIT - DL_PLATFORM_INIT; -#endif - - /* Now determine the length of the platform string. */ - if (_dl_platform != NULL) - _dl_platformlen = strlen (_dl_platform); -} -text_set_element (__libc_subinit, non_dynamic_init); - -const struct r_strlenpair * -internal_function -_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, - size_t *max_capstrlen) -{ - static struct r_strlenpair result; - static char buf[1]; - - result.str = buf; /* Does not really matter. */ - result.len = 0; - - *sz = 1; - return &result; -} diff --git a/newlib/libc/sys/linux/dl/dl-sym.c b/newlib/libc/sys/linux/dl/dl-sym.c deleted file mode 100644 index 85d084f7f..000000000 --- a/newlib/libc/sys/linux/dl/dl-sym.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Look up a symbol in a shared object loaded by `dlopen'. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <stddef.h> -#include <setjmp.h> -#include <libintl.h> - -#include <dlfcn.h> -#include <ldsodefs.h> -#include <dl-hash.h> - -void * -internal_function -_dl_sym (void *handle, const char *name, void *who) -{ - const ElfW(Sym) *ref = NULL; - lookup_t result; - ElfW(Addr) caller = (ElfW(Addr)) who; - struct link_map *match; - struct link_map *l; - - /* If the address is not recognized the call comes from the main - program (we hope). */ - match = _dl_loaded; - - /* Find the highest-addressed object that CALLER is not below. */ - for (l = _dl_loaded; l != NULL; l = l->l_next) - if (caller >= l->l_map_start && caller < l->l_map_end) - { - /* There must be exactly one DSO for the range of the virtual - memory. Otherwise something is really broken. */ - match = l; - break; - } - - if (handle == RTLD_DEFAULT) - /* Search the global scope as seen in the caller object. */ - result = _dl_lookup_symbol (name, match, &ref, match->l_scope, 0, 0); - else - { - if (handle != RTLD_NEXT) - { - /* Search the scope of the given object. */ - struct link_map *map = handle; - - result = _dl_lookup_symbol (name, match, &ref, map->l_local_scope, - 0, 1); - } - else - { - if (__builtin_expect (match == _dl_loaded, 0)) - { - if (! _dl_loaded - || caller < _dl_loaded->l_map_start - || caller >= _dl_loaded->l_map_end) - _dl_signal_error (0, NULL, NULL, N_("\ -RTLD_NEXT used in code not dynamically loaded")); - } - - l = match; - while (l->l_loader != NULL) - l = l->l_loader; - - result = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope, - match); - } - } - - if (ref != NULL) - return DL_SYMBOL_ADDRESS (result, ref); - - return NULL; -} - -void * -internal_function -_dl_vsym (void *handle, const char *name, const char *version, void *who) -{ - const ElfW(Sym) *ref = NULL; - struct r_found_version vers; - lookup_t result; - ElfW(Addr) caller = (ElfW(Addr)) who; - struct link_map *match; - struct link_map *l; - - /* Compute hash value to the version string. */ - vers.name = version; - vers.hidden = 1; - vers.hash = _dl_elf_hash (version); - /* We don't have a specific file where the symbol can be found. */ - vers.filename = NULL; - - /* If the address is not recognized the call comes from the main - program (we hope). */ - match = _dl_loaded; - - /* Find the highest-addressed object that CALLER is not below. */ - for (l = _dl_loaded; l != NULL; l = l->l_next) - if (caller >= l->l_map_start && caller < l->l_map_end) - { - /* There must be exactly one DSO for the range of the virtual - memory. Otherwise something is really broken. */ - match = l; - break; - } - - if (handle == RTLD_DEFAULT) - /* Search the global scope. */ - result = _dl_lookup_versioned_symbol (name, match, &ref, match->l_scope, - &vers, 0, 0); - else if (handle == RTLD_NEXT) - { - if (__builtin_expect (match == _dl_loaded, 0)) - { - if (! _dl_loaded - || caller < _dl_loaded->l_map_start - || caller >= _dl_loaded->l_map_end) - _dl_signal_error (0, NULL, NULL, N_("\ -RTLD_NEXT used in code not dynamically loaded")); - } - - l = match; - while (l->l_loader != NULL) - l = l->l_loader; - - result = _dl_lookup_versioned_symbol_skip (name, l, &ref, - l->l_local_scope, - &vers, match); - } - else - { - /* Search the scope of the given object. */ - struct link_map *map = handle; - result = _dl_lookup_versioned_symbol (name, map, &ref, - map->l_local_scope, &vers, 0, 1); - } - - if (ref != NULL) - return DL_SYMBOL_ADDRESS (result, ref); - - return NULL; -} diff --git a/newlib/libc/sys/linux/dl/dl-version.c b/newlib/libc/sys/linux/dl/dl-version.c deleted file mode 100644 index eefbea7ec..000000000 --- a/newlib/libc/sys/linux/dl/dl-version.c +++ /dev/null @@ -1,385 +0,0 @@ -/* Handle symbol and library versioning. - Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <elf.h> -#include <errno.h> -#include <libintl.h> -#include <stdlib.h> -#include <string.h> -#include <ldsodefs.h> - -#include <assert.h> - - -#ifndef VERSYMIDX -# define VERSYMIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) -#endif - - -#define make_string(string, rest...) \ - ({ \ - const char *all[] = { string, ## rest }; \ - size_t len, cnt; \ - char *result, *cp; \ - \ - len = 1; \ - for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \ - len += strlen (all[cnt]); \ - \ - cp = result = alloca (len); \ - for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \ - { \ - cp = strcpy (cp, all[cnt]); \ - cp += strlen (all[cnt]); \ - } \ - \ - result; \ - }) - - -static inline struct link_map * -find_needed (const char *name, struct link_map *map) -{ - struct link_map *tmap; - unsigned int n; - - for (tmap = _dl_loaded; tmap != NULL; tmap = tmap->l_next) - if (_dl_name_match_p (name, tmap)) - return tmap; - - /* The required object is not in the global scope, look to see if it is - a dependency of the current object. */ - for (n = 0; n < map->l_searchlist.r_nlist; n++) - if (_dl_name_match_p (name, map->l_searchlist.r_list[n])) - return map->l_searchlist.r_list[n]; - - /* Should never happen. */ - return NULL; -} - - -static int -internal_function -match_symbol (const char *name, ElfW(Word) hash, const char *string, - struct link_map *map, int verbose, int weak) -{ - const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - ElfW(Addr) def_offset; - ElfW(Verdef) *def; - /* Initialize to make the compiler happy. */ - const char *errstring = NULL; - int result = 0; - - /* Display information about what we are doing while debugging. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_VERSIONS, 0)) - _dl_debug_printf ("\ -checking for version `%s' in file %s required by file %s\n", - string, map->l_name[0] ? map->l_name : _dl_argv[0], - name); - - if (__builtin_expect (map->l_info[VERSYMIDX (DT_VERDEF)] == NULL, 0)) - { - /* The file has no symbol versioning. I.e., the dependent - object was linked against another version of this file. We - only print a message if verbose output is requested. */ - if (verbose) - { - /* XXX We cannot translate the messages. */ - errstring = make_string ("\ -no version information available (required by ", name, ")"); - goto call_cerror; - } - return 0; - } - - def_offset = map->l_info[VERSYMIDX (DT_VERDEF)]->d_un.d_ptr; - assert (def_offset != 0); - - def = (ElfW(Verdef) *) ((char *) map->l_addr + def_offset); - while (1) - { - /* Currently the version number of the definition entry is 1. - Make sure all we see is this version. */ - if (__builtin_expect (def->vd_version, 1) != 1) - { - char buf[20]; - buf[sizeof (buf) - 1] = '\0'; - /* XXX We cannot translate the message. */ - errstring = make_string ("unsupported version of Verdef record"); - result = 1; - goto call_cerror; - } - - /* Compare the hash values. */ - if (hash == def->vd_hash) - { - ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux); - - /* To be safe, compare the string as well. */ - if (__builtin_expect (strcmp (string, strtab + aux->vda_name), 0) - == 0) - /* Bingo! */ - return 0; - } - - /* If no more definitions we failed to find what we want. */ - if (def->vd_next == 0) - break; - - /* Next definition. */ - def = (ElfW(Verdef) *) ((char *) def + def->vd_next); - } - - /* Symbol not found. If it was a weak reference it is not fatal. */ - if (__builtin_expect (weak, 1)) - { - if (verbose) - { - /* XXX We cannot translate the message. */ - errstring = make_string ("weak version `", string, - "' not found (required by ", name, ")"); - goto call_cerror; - } - return 0; - } - - /* XXX We cannot translate the message. */ - errstring = make_string ("version `", string, "' not found (required by ", - name, ")"); - result = 1; - call_cerror: - _dl_signal_cerror (0, map->l_name[0] ? map->l_name : _dl_argv[0], NULL, - errstring); - return result; -} - - -int -internal_function -_dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) -{ - int result = 0; - const char *strtab; - /* Pointer to section with needed versions. */ - ElfW(Dyn) *dyn; - /* Pointer to dynamic section with definitions. */ - ElfW(Dyn) *def; - /* We need to find out which is the highest version index used - in a dependecy. */ - unsigned int ndx_high = 0; - /* Initialize to make the compiler happy. */ - const char *errstring = NULL; - int errval = 0; - - /* If we don't have a string table, we must be ok. */ - if (map->l_info[DT_STRTAB] == NULL) - return 0; - strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - - dyn = map->l_info[VERSYMIDX (DT_VERNEED)]; - def = map->l_info[VERSYMIDX (DT_VERDEF)]; - - if (dyn != NULL) - { - /* This file requires special versions from its dependencies. */ - ElfW(Verneed) *ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr); - - /* Currently the version number of the needed entry is 1. - Make sure all we see is this version. */ - if (__builtin_expect (ent->vn_version, 1) != 1) - { - char buf[20]; - buf[sizeof (buf) - 1] = '\0'; - /* XXX We cannot translate the message. */ - errstring = make_string ("unsupported version of Verneed record\n"); - call_error: - _dl_signal_error (errval, (*map->l_name ? map->l_name : _dl_argv[0]), - NULL, errstring); - } - - while (1) - { - ElfW(Vernaux) *aux; - struct link_map *needed = find_needed (strtab + ent->vn_file, map); - - /* If NEEDED is NULL this means a dependency was not found - and no stub entry was created. This should never happen. */ - assert (needed != NULL); - - /* Make sure this is no stub we created because of a missing - dependency. */ - if (__builtin_expect (! trace_mode, 1) - || ! __builtin_expect (needed->l_faked, 0)) - { - /* NEEDED is the map for the file we need. Now look for the - dependency symbols. */ - aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux); - while (1) - { - /* Match the symbol. */ - result |= match_symbol ((*map->l_name - ? map->l_name : _dl_argv[0]), - aux->vna_hash, - strtab + aux->vna_name, - needed, verbose, - aux->vna_flags & VER_FLG_WEAK); - - /* Compare the version index. */ - if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high) - ndx_high = aux->vna_other & 0x7fff; - - if (aux->vna_next == 0) - /* No more symbols. */ - break; - - /* Next symbol. */ - aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next); - } - } - - if (ent->vn_next == 0) - /* No more dependencies. */ - break; - - /* Next dependency. */ - ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next); - } - } - - /* We also must store the names of the defined versions. Determine - the maximum index here as well. - - XXX We could avoid the loop by just taking the number of definitions - as an upper bound of new indeces. */ - if (def != NULL) - { - ElfW(Verdef) *ent; - ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr); - while (1) - { - if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high) - ndx_high = ent->vd_ndx & 0x7fff; - - if (ent->vd_next == 0) - /* No more definitions. */ - break; - - ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next); - } - } - - if (ndx_high > 0) - { - /* Now we are ready to build the array with the version names - which can be indexed by the version index in the VERSYM - section. */ - map->l_versions = (struct r_found_version *) - calloc (ndx_high + 1, sizeof (*map->l_versions)); - if (__builtin_expect (map->l_versions == NULL, 0)) - { - errstring = N_("cannot allocate version reference table"); - errval = ENOMEM; - goto call_error; - } - - /* Store the number of available symbols. */ - map->l_nversions = ndx_high + 1; - - /* Compute the pointer to the version symbols. */ - map->l_versyms = (void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); - - if (dyn != NULL) - { - ElfW(Verneed) *ent; - ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr); - while (1) - { - ElfW(Vernaux) *aux; - aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux); - while (1) - { - ElfW(Half) ndx = aux->vna_other & 0x7fff; - map->l_versions[ndx].hash = aux->vna_hash; - map->l_versions[ndx].hidden = aux->vna_other & 0x8000; - map->l_versions[ndx].name = &strtab[aux->vna_name]; - map->l_versions[ndx].filename = &strtab[ent->vn_file]; - - if (aux->vna_next == 0) - /* No more symbols. */ - break; - - /* Advance to next symbol. */ - aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next); - } - - if (ent->vn_next == 0) - /* No more dependencies. */ - break; - - /* Advance to next dependency. */ - ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next); - } - } - - /* And insert the defined versions. */ - if (def != NULL) - { - ElfW(Verdef) *ent; - ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr); - while (1) - { - ElfW(Verdaux) *aux; - aux = (ElfW(Verdaux) *) ((char *) ent + ent->vd_aux); - - if ((ent->vd_flags & VER_FLG_BASE) == 0) - { - /* The name of the base version should not be - available for matching a versioned symbol. */ - ElfW(Half) ndx = ent->vd_ndx & 0x7fff; - map->l_versions[ndx].hash = ent->vd_hash; - map->l_versions[ndx].name = &strtab[aux->vda_name]; - map->l_versions[ndx].filename = NULL; - } - - if (ent->vd_next == 0) - /* No more definitions. */ - break; - - ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next); - } - } - } - - return result; -} - - -int -internal_function -_dl_check_all_versions (struct link_map *map, int verbose, int trace_mode) -{ - struct link_map *l; - int result = 0; - - for (l = map; l != NULL; l = l->l_next) - result |= ! l->l_faked && _dl_check_map_versions (l, verbose, trace_mode); - - return result; -} diff --git a/newlib/libc/sys/linux/dl/do-lookup.h b/newlib/libc/sys/linux/dl/do-lookup.h deleted file mode 100644 index 37718ce6c..000000000 --- a/newlib/libc/sys/linux/dl/do-lookup.h +++ /dev/null @@ -1,201 +0,0 @@ -/* Look up a symbol in the loaded objects. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#if VERSIONED -# define FCT do_lookup_versioned -# define ARG const struct r_found_version *const version, -#else -# define FCT do_lookup -# define ARG -#endif - -/* Inner part of the lookup functions. We return a value > 0 if we - found the symbol, the value 0 if nothing is found and < 0 if - something bad happened. */ -static inline int -FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref, - struct sym_val *result, struct r_scope_elem *scope, size_t i, ARG - struct link_map *skip, int type_class) -{ - struct link_map **list = scope->r_list; - size_t n = scope->r_nlist; - struct link_map *map; - - do - { - const ElfW(Sym) *symtab; - const char *strtab; - const ElfW(Half) *verstab; - Elf_Symndx symidx; - const ElfW(Sym) *sym; -#if ! VERSIONED - int num_versions = 0; - const ElfW(Sym) *versioned_sym = NULL; -#endif - - map = list[i]; - - /* Here come the extra test needed for `_dl_lookup_symbol_skip'. */ - if (skip != NULL && map == skip) - continue; - - /* Don't search the executable when resolving a copy reloc. */ - if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable) - continue; - - /* Print some debugging info if wanted. */ - if (__builtin_expect (_dl_debug_mask & DL_DEBUG_SYMBOLS, 0)) - _dl_debug_printf ("symbol=%s; lookup in file=%s\n", undef_name, - map->l_name[0] ? map->l_name : _dl_argv[0]); - - symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]); - strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - verstab = map->l_versyms; - - /* Search the appropriate hash bucket in this object's symbol table - for a definition for the same symbol name. */ - for (symidx = map->l_buckets[hash % map->l_nbuckets]; - symidx != STN_UNDEF; - symidx = map->l_chain[symidx]) - { - sym = &symtab[symidx]; - - assert (ELF_RTYPE_CLASS_PLT == 1); - if (sym->st_value == 0 || /* No value. */ - /* ((type_class & ELF_RTYPE_CLASS_PLT) - && (sym->st_shndx == SHN_UNDEF)) */ - (type_class & (sym->st_shndx == SHN_UNDEF))) - continue; - - if (ELFW(ST_TYPE) (sym->st_info) > STT_FUNC - && ELFW(ST_TYPE) (sym->st_info) != STT_COMMON) - /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_COMMON and - STT_FUNC entries since these are no code/data definitions. */ - continue; - - if (sym != ref && strcmp (strtab + sym->st_name, undef_name)) - /* Not the symbol we are looking for. */ - continue; - -#if VERSIONED - if (__builtin_expect (verstab == NULL, 0)) - { - /* We need a versioned symbol but haven't found any. If - this is the object which is referenced in the verneed - entry it is a bug in the library since a symbol must - not simply disappear. - - It would also be a bug in the object since it means that - the list of required versions is incomplete and so the - tests in dl-version.c haven't found a problem.*/ - assert (version->filename == NULL - || ! _dl_name_match_p (version->filename, map)); - - /* Otherwise we accept the symbol. */ - } - else - { - /* We can match the version information or use the - default one if it is not hidden. */ - ElfW(Half) ndx = verstab[symidx] & 0x7fff; - if ((map->l_versions[ndx].hash != version->hash - || strcmp (map->l_versions[ndx].name, version->name)) - && (version->hidden || map->l_versions[ndx].hash - || (verstab[symidx] & 0x8000))) - /* It's not the version we want. */ - continue; - } -#else - /* No specific version is selected. When the object file - also does not define a version we have a match. - Otherwise we accept the default version, or in case there - is only one version defined, this one version. */ - if (verstab != NULL) - { - ElfW(Half) ndx = verstab[symidx] & 0x7fff; - if (ndx > 2) /* map->l_versions[ndx].hash != 0) */ - { - /* Don't accept hidden symbols. */ - if ((verstab[symidx] & 0x8000) == 0 && num_versions++ == 0) - /* No version so far. */ - versioned_sym = sym; - continue; - } - } -#endif - - /* There cannot be another entry for this symbol so stop here. */ - goto found_it; - } - - /* If we have seen exactly one versioned symbol while we are - looking for an unversioned symbol and the version is not the - default version we still accept this symbol since there are - no possible ambiguities. */ -#if VERSIONED - sym = NULL; -#else - sym = num_versions == 1 ? versioned_sym : NULL; -#endif - - if (sym != NULL) - { - found_it: - switch (ELFW(ST_BIND) (sym->st_info)) - { - case STB_WEAK: - /* Weak definition. Use this value if we don't find another. */ - if (__builtin_expect (_dl_dynamic_weak, 0)) - { - if (! result->s) - { - result->s = sym; - result->m = map; - } - break; - } - /* FALLTHROUGH */ - case STB_GLOBAL: - /* Global definition. Just what we need. */ - result->s = sym; - result->m = map; - return 1; - default: - /* Local symbols are ignored. */ - break; - } - } - -#if VERSIONED - /* If this current map is the one mentioned in the verneed entry - and we have not found a weak entry, it is a bug. */ - if (symidx == STN_UNDEF && version->filename != NULL - && __builtin_expect (_dl_name_match_p (version->filename, map), 0)) - return -1; -#endif - } - while (++i < n); - - /* We have not found anything until now. */ - return 0; -} - -#undef FCT -#undef ARG -#undef VERSIONED diff --git a/newlib/libc/sys/linux/dl/do-rel.h b/newlib/libc/sys/linux/dl/do-rel.h deleted file mode 100644 index 03b9e807b..000000000 --- a/newlib/libc/sys/linux/dl/do-rel.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Do relocations for ELF dynamic linking. - Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* This file may be included twice, to define both - `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. */ - -#include <machine/weakalias.h> - -#ifdef DO_RELA -# define elf_dynamic_do_rel elf_dynamic_do_rela -# define RELCOUNT_IDX VERSYMIDX (DT_RELACOUNT) -# define Rel Rela -# define elf_machine_rel elf_machine_rela -# define elf_machine_rel_relative elf_machine_rela_relative -#else -# define RELCOUNT_IDX VERSYMIDX (DT_RELCOUNT) -#endif - -#ifndef VERSYMIDX -# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) -#endif - -/* Perform the relocations in MAP on the running program image as specified - by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT - relocations; they should be set up to call _dl_runtime_resolve, rather - than fully resolved now. */ - -static inline void -elf_dynamic_do_rel (struct link_map *map, - ElfW(Addr) reladdr, ElfW(Addr) relsize, - int lazy, - struct r_scope_elem *scope[]) -{ - const ElfW(Rel) *r = (const void *) reladdr; - const ElfW(Rel) *end = (const void *) (reladdr + relsize); - ElfW(Addr) l_addr = map->l_addr; - -#ifndef RTLD_BOOTSTRAP - /* We never bind lazily during ld.so bootstrap. Unfortunately gcc is - not clever enough to see through all the function calls to realize - that. */ - if (lazy) - { - /* Doing lazy PLT relocations; they need very little info. */ - for (; r < end; ++r) - elf_machine_lazy_rel (map, l_addr, r); - } - else -#endif - { - const ElfW(Sym) *const symtab = - (const void *) D_PTR (map, l_info[DT_SYMTAB]); - ElfW(Word) nrelative = (map->l_info[RELCOUNT_IDX] == NULL - ? 0 : map->l_info[RELCOUNT_IDX]->d_un.d_val); - const ElfW(Rel) *relative = r; - r = MIN (r + nrelative, end); - -#ifndef RTLD_BOOTSTRAP - /* This is defined in rtld.c, but nowhere in the static libc.a; make - the reference weak so static programs can still link. This - declaration cannot be done when compiling rtld.c (i.e. #ifdef - RTLD_BOOTSTRAP) because rtld.c contains the common defn for - _dl_rtld_map, which is incompatible with a weak decl in the same - file. */ - #pragma weak _dl_rtld_map - if (map != &_dl_rtld_map) /* Already done in rtld itself. */ -# ifndef DO_RELA - /* Rela platforms get the offset from r_addend and this must - be copied in the relocation address. Therefore we can skip - the relative relocations only if this is for rel - relocations. */ - if (l_addr != 0) -# endif -#endif - for (; relative < r; ++relative) - elf_machine_rel_relative (l_addr, relative, - (void *) (l_addr + relative->r_offset)); - - if (map->l_info[VERSYMIDX (DT_VERSYM)]) - { - const ElfW(Half) *const version = - (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); - - for (; r < end; ++r) - { - ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)]; - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], - &map->l_versions[ndx], - (void *) (l_addr + r->r_offset), - scope); - } - } - else - for (; r < end; ++r) - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, - (void *) (l_addr + r->r_offset), scope); - } -} - -#undef elf_dynamic_do_rel -#undef Rel -#undef elf_machine_rel -#undef elf_machine_rel_relative -#undef RELCOUNT_IDX diff --git a/newlib/libc/sys/linux/dl/dynamic-link.h b/newlib/libc/sys/linux/dl/dynamic-link.h deleted file mode 100644 index c1709f7c6..000000000 --- a/newlib/libc/sys/linux/dl/dynamic-link.h +++ /dev/null @@ -1,257 +0,0 @@ -/* Inline functions for dynamic linking. - Copyright (C) 1995,96,97,98,99,2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef __DYNAMIC_LINK_H__ -#define __DYNAMIC_LINK_H__ - -#include <elf.h> -#include <machine/dl-machine.h> -#include <assert.h> - -#ifndef VERSYMIDX -# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) -#endif - - -/* Global read-only variable defined in rtld.c which is nonzero if we - shall give more warning messages. */ -extern int _dl_verbose __attribute__ ((unused)); - - -/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */ - -static void __attribute__ ((unused)) -elf_get_dynamic_info (struct link_map *l) -{ - ElfW(Dyn) *dyn = l->l_ld; - ElfW(Addr) l_addr; - ElfW(Dyn) **info; - - if (! dyn) - return; - - l_addr = l->l_addr; - info = l->l_info; - - while (dyn->d_tag != DT_NULL) - { - if (dyn->d_tag < DT_NUM) - info[dyn->d_tag] = dyn; - else if (dyn->d_tag >= DT_LOPROC && - dyn->d_tag < DT_LOPROC + DT_THISPROCNUM) - info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; - else if ((Elf32_Word) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM) - info[VERSYMIDX (dyn->d_tag)] = dyn; - else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) - info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM - + DT_VERSIONTAGNUM] = dyn; - else - assert (! "bad dynamic tag"); - ++dyn; - } -#ifndef DL_RO_DYN_SECTION - if (info[DT_PLTGOT] != NULL) - info[DT_PLTGOT]->d_un.d_ptr += l_addr; - if (info[DT_STRTAB] != NULL) - info[DT_STRTAB]->d_un.d_ptr += l_addr; - if (info[DT_SYMTAB] != NULL) - info[DT_SYMTAB]->d_un.d_ptr += l_addr; -# if ! ELF_MACHINE_NO_RELA - if (info[DT_RELA] != NULL) - { - assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela))); - info[DT_RELA]->d_un.d_ptr += l_addr; - } -# endif -# if ! ELF_MACHINE_NO_REL - if (info[DT_REL] != NULL) - { - assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); - info[DT_REL]->d_un.d_ptr += l_addr; - } -# endif -#endif - if (info[DT_PLTREL] != NULL) - { -# if ELF_MACHINE_NO_RELA - assert (info[DT_PLTREL]->d_un.d_val == DT_REL); -# elif ELF_MACHINE_NO_REL - assert (info[DT_PLTREL]->d_un.d_val == DT_RELA); -# else - assert (info[DT_PLTREL]->d_un.d_val == DT_REL - || info[DT_PLTREL]->d_un.d_val == DT_RELA); -# endif - } -#ifndef DL_RO_DYN_SECTION - if (info[DT_JMPREL] != NULL) - info[DT_JMPREL]->d_un.d_ptr += l_addr; - if (info[VERSYMIDX (DT_VERSYM)] != NULL) - info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr; -#endif - if (info[DT_FLAGS] != NULL) - { - /* Flags are used. Translate to the old form where available. - Since these l_info entries are only tested for NULL pointers it - is ok if they point to the DT_FLAGS entry. */ - ElfW(Word) flags = info[DT_FLAGS]->d_un.d_val; - if (flags & DF_SYMBOLIC) - info[DT_SYMBOLIC] = info[DT_FLAGS]; - if (flags & DF_TEXTREL) - info[DT_TEXTREL] = info[DT_FLAGS]; - if (flags & DF_BIND_NOW) - info[DT_BIND_NOW] = info[DT_FLAGS]; - } - if (info[VERSYMIDX (DT_FLAGS_1)] != NULL) - l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; - if (info[DT_RUNPATH] != NULL) - /* If both RUNPATH and RPATH are given, the latter is ignored. */ - info[DT_RPATH] = NULL; -} - -# if ! ELF_MACHINE_NO_REL -# include "do-rel.h" -# endif - -# if ! ELF_MACHINE_NO_RELA -# define DO_RELA -# include "do-rel.h" -# endif - -#endif /* __DYNAMIC_LINK_H__ */ - -#ifdef RESOLVE - -/* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. - These functions are almost identical, so we use cpp magic to avoid - duplicating their code. It cannot be done in a more general function - because we must be able to completely inline. */ - -/* On some machines, notably SPARC, DT_REL* includes DT_JMPREL in its - range. Note that according to the ELF spec, this is completely legal! - But conditionally define things so that on machines we know this will - not happen we do something more optimal. */ - -# ifdef ELF_MACHINE_PLTREL_OVERLAP -# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \ - do { \ - struct { ElfW(Addr) start, size; int lazy; } ranges[3]; \ - int ranges_index; \ - \ - ranges[0].lazy = ranges[2].lazy = 0; \ - ranges[1].lazy = 1; \ - ranges[0].size = ranges[1].size = ranges[2].size = 0; \ - \ - if ((map)->l_info[DT_##RELOC]) \ - { \ - ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \ - ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \ - } \ - \ - if ((do_lazy) \ - && (map)->l_info[DT_PLTREL] \ - && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \ - { \ - ranges[1].start = D_PTR ((map), l_info[DT_JMPREL]); \ - ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ - ranges[2].start = ranges[1].start + ranges[1].size; \ - ranges[2].size = ranges[0].start + ranges[0].size - ranges[2].start; \ - ranges[0].size = ranges[1].start - ranges[0].start; \ - } \ - \ - for (ranges_index = 0; ranges_index < 3; ++ranges_index) \ - elf_dynamic_do_##reloc ((map), \ - ranges[ranges_index].start, \ - ranges[ranges_index].size, \ - ranges[ranges_index].lazy, \ - scope); \ - } while (0) -# else -# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \ - do { \ - struct { ElfW(Addr) start, size; int lazy; } ranges[2]; \ - int ranges_index; \ - ranges[0].lazy = 0; \ - ranges[0].size = ranges[1].size = 0; \ - ranges[0].start = 0; \ - \ - if ((map)->l_info[DT_##RELOC]) \ - { \ - ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \ - ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \ - } \ - if ((map)->l_info[DT_PLTREL] \ - && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \ - { \ - ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \ - \ - if ((do_lazy) \ - /* This test does not only detect whether the relocation \ - sections are in the right order, it also checks whether \ - there is a DT_REL/DT_RELA section. */ \ - || ranges[0].start + ranges[0].size != start) \ - { \ - ranges[1].start = start; \ - ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ - ranges[1].lazy = (do_lazy); \ - } \ - else \ - /* Combine processing the sections. */ \ - ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ - } \ - \ - for (ranges_index = 0; ranges_index < 2; ++ranges_index) \ - elf_dynamic_do_##reloc ((map), \ - ranges[ranges_index].start, \ - ranges[ranges_index].size, \ - ranges[ranges_index].lazy, \ - scope); \ - } while (0) -# endif - -# if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA -# define _ELF_CHECK_REL 0 -# else -# define _ELF_CHECK_REL 1 -# endif - -# if ! ELF_MACHINE_NO_REL -# define ELF_DYNAMIC_DO_REL(map, lazy) \ - _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, _ELF_CHECK_REL) -# else -# define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do. */ -# endif - -# if ! ELF_MACHINE_NO_RELA -# define ELF_DYNAMIC_DO_RELA(map, lazy) \ - _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, _ELF_CHECK_REL) -# else -# define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do. */ -# endif - -/* This can't just be an inline function because GCC is too dumb - to inline functions containing inlines themselves. */ -# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \ - do { \ - int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \ - (consider_profile)); \ - ELF_DYNAMIC_DO_REL ((map), edr_lazy); \ - ELF_DYNAMIC_DO_RELA ((map), edr_lazy); \ - } while (0) - -#endif diff --git a/newlib/libc/sys/linux/dl/kernel-features.h b/newlib/libc/sys/linux/dl/kernel-features.h deleted file mode 100644 index 562a6c765..000000000 --- a/newlib/libc/sys/linux/dl/kernel-features.h +++ /dev/null @@ -1,193 +0,0 @@ -/* Set flags signalling availability of kernel features based on given - kernel version number. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* This file must not contain any C code. At least it must be protected - to allow using the file also in assembler files. */ - -#ifndef __LINUX_KERNEL_VERSION -/* We assume the worst; all kernels should be supported. */ -# define __LINUX_KERNEL_VERSION 0 -#endif - -/* We assume for __LINUX_KERNEL_VERSION the same encoding used in - linux/version.h. I.e., the major, minor, and subminor all get a - byte with the major number being in the highest byte. This means - we can do numeric comparisons. - - In the following we will define certain symbols depending on - whether the describes kernel feature is available in the kernel - version given by __LINUX_KERNEL_VERSION. We are not always exactly - recording the correct versions in which the features were - introduced. If somebody cares these values can afterwards be - corrected. Most of the numbers here are set corresponding to - 2.2.0. */ - -/* `getcwd' system call. */ -#if __LINUX_KERNEL_VERSION >= 131584 -# define __ASSUME_GETCWD_SYSCALL 1 -#endif - -/* Real-time signal became usable in 2.1.70. */ -#if __LINUX_KERNEL_VERSION >= 131398 -# define __ASSUME_REALTIME_SIGNALS 1 -#endif - -/* When were the `pread'/`pwrite' syscalls introduced? */ -#if __LINUX_KERNEL_VERSION >= 131584 -# define __ASSUME_PREAD_SYSCALL 1 -# define __ASSUME_PWRITE_SYSCALL 1 -#endif - -/* When was `poll' introduced? */ -#if __LINUX_KERNEL_VERSION >= 131584 -# define __ASSUME_POLL_SYSCALL 1 -#endif - -/* The `lchown' syscall was introduced in 2.1.80. */ -#if __LINUX_KERNEL_VERSION >= 131408 -# define __ASSUME_LCHOWN_SYSCALL 1 -#endif - -/* When did the `setresuid' sysall became available? */ -#if __LINUX_KERNEL_VERSION >= 131584 && !defined __sparc__ -# define __ASSUME_SETRESUID_SYSCALL 1 -#endif - -/* The SIOCGIFNAME ioctl is available starting with 2.1.50. */ -#if __LINUX_KERNEL_VERSION >= 131408 -# define __ASSUME_SIOCGIFNAME 1 -#endif - -/* On x86 another `getrlimit' syscall was added in 2.3.25. */ -#if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__ -# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1 -#endif - -/* On x86 the truncate64/ftruncate64 syscalls were introduced in 2.3.31. */ -#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ -# define __ASSUME_TRUNCATE64_SYSCALL 1 -#endif - -/* On x86 the mmap2 syscall was introduced in 2.3.31. */ -#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ -# define __ASSUME_MMAP2_SYSCALL 1 -#endif - -/* On x86 the stat64/lstat64/fstat64 syscalls were introduced in 2.3.34. */ -#if __LINUX_KERNEL_VERSION >= 131874 && defined __i386__ -# define __ASSUME_STAT64_SYSCALL 1 -#endif - -/* On sparc and ARM the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64 - syscalls were introduced in 2.3.35. */ -#if __LINUX_KERNEL_VERSION >= 131875 && (defined __sparc__ || defined __arm__) -# define __ASSUME_TRUNCATE64_SYSCALL 1 -# define __ASSUME_MMAP2_SYSCALL 1 -# define __ASSUME_STAT64_SYSCALL 1 -#endif - -/* I know for sure that these are in 2.3.35 on powerpc. */ -#if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__ -# define __ASSUME_TRUNCATE64_SYSCALL 1 -# define __ASSUME_STAT64_SYSCALL 1 -# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1 -#endif - -/* Linux 2.3.39 introduced 32bit UID/GIDs and IPC64. Some platforms had 32 - bit type all along. */ -#if __LINUX_KERNEL_VERSION >= 131879 || defined __powerpc__ || defined __mips__ -# define __ASSUME_32BITUIDS 1 -# ifndef __powerpc__ -# define __ASSUME_IPC64 1 -# endif -# ifdef __sparc__ -# define __ASSUME_SETRESUID_SYSCALL 1 -# endif -#endif - -/* Linux 2.4.0 on PPC introduced a correct IPC64. */ -#if __LINUX_KERNEL_VERSION >= 132096 && defined __powerpc__ -# define __ASSUME_IPC64 1 -#endif - -/* We can use the LDTs for threading with Linux 2.3.99 and newer. */ -#if __LINUX_KERNEL_VERSION >= 131939 -# define __ASSUME_LDT_WORKS 1 -#endif - -/* The changed st_ino field appeared in 2.4.0-test6. But we cannot - distinguish this version from other 2.4.0 releases. Therefore play - save and assume it available is for 2.4.1 and up. */ -#if __LINUX_KERNEL_VERSION >= 132097 -# define __ASSUME_ST_INO_64_BIT 1 -#endif - -/* To support locking of large files a new fcntl() syscall was introduced - in 2.4.0-test7. We test for 2.4.1 for the earliest version we know - the syscall is available. */ -#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __sparc__) -# define __ASSUME_FCNTL64 1 -#endif - -/* Arm got fcntl64 in 2.4.4, PowerPC and SH have it also in 2.4.4 (I - don't know when it got introduced). */ -#if __LINUX_KERNEL_VERSION >= 132100 \ - && (defined __arm__ || defined __powerpc__ || defined __sh__) -# define __ASSUME_FCNTL64 1 -#endif - -/* The getdents64 syscall was introduced in 2.4.0-test7. We test for - 2.4.1 for the earliest version we know the syscall is available. */ -#if __LINUX_KERNEL_VERSION >= 132097 -# define __ASSUME_GETDENTS64_SYSCALL 1 -#endif - -/* When did O_DIRECTORY became available? Early in 2.3 but when? - Be safe, use 2.3.99. */ -#if __LINUX_KERNEL_VERSION >= 131939 -# define __ASSUME_O_DIRECTORY 1 -#endif - -/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes - up the page size information. */ -#if __LINUX_KERNEL_VERSION >= 132097 -# define __ASSUME_AT_PAGESIZE 1 -#endif - -/* Starting with 2.4.5 kernels PPC passes the AUXV in the standard way - and the mmap2 syscall made it into the official kernel. */ -#if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__ -# define __ASSUME_STD_AUXV 1 -# define __ASSUME_MMAP2_SYSCALL 1 -#endif - -/* There are an infinite number of PA-RISC kernel versions numbered - 2.4.0. But they've not really been released as such. We require - and expect the final version here. */ -#ifdef __hppa__ -# define __ASSUME_32BITUIDS 1 -# define __ASSUME_TRUNCATE64_SYSCALL 1 -# define __ASSUME_MMAP2_SYSCALL 1 -# define __ASSUME_STAT64_SYSCALL 1 -# define __ASSUME_IPC64 1 -# define __ASSUME_ST_INO_64_BIT 1 -# define __ASSUME_FCNTL64 1 -# define __ASSUME_GETDENTS64_SYSCALL 1 -#endif diff --git a/newlib/libc/sys/linux/dl/ldsodefs.h b/newlib/libc/sys/linux/dl/ldsodefs.h deleted file mode 100644 index e6f57ddcf..000000000 --- a/newlib/libc/sys/linux/dl/ldsodefs.h +++ /dev/null @@ -1,536 +0,0 @@ -/* Run-time dynamic linker data structures for loaded ELF shared objects. - Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _LDSODEFS_H -#define _LDSODEFS_H 1 - -#include <features.h> - -#define __need_size_t -#define __need_NULL -#include <stddef.h> -#include <string.h> - -#include <elf.h> -#include <link.h> -#include <dl-lookupcfg.h> -#include <bits/libc-lock.h> - -#include "dl-local.h" - -__BEGIN_DECLS - -/* We use this macro to refer to ELF types independent of the native wordsize. - `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ -#define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) - -#define internal_function -/* All references to the value of l_info[DT_PLTGOT], - l_info[DT_STRTAB], l_info[DT_SYMTAB], l_info[DT_RELA], - l_info[DT_REL], l_info[DT_JMPREL], and l_info[VERSYMIDX (DT_VERSYM)] - have to be accessed via the D_PTR macro. The macro is needed since for - most architectures the entry is already relocated - but for some not - and we need to relocate at access time. */ -#ifdef DL_RO_DYN_SECTION -# define D_PTR(map,i) (map->i->d_un.d_ptr + map->l_addr) -#else -# define D_PTR(map,i) map->i->d_un.d_ptr -#endif - -/* On some platforms more information than just the address of the symbol - is needed from the lookup functions. In this case we return the whole - link map. */ -#ifdef DL_LOOKUP_RETURNS_MAP -typedef struct link_map *lookup_t; -# define LOOKUP_VALUE(map) map -# define LOOKUP_VALUE_ADDRESS(map) (map ? map->l_addr : 0) -#else -typedef ElfW(Addr) lookup_t; -# define LOOKUP_VALUE(map) map->l_addr -# define LOOKUP_VALUE_ADDRESS(address) address -#endif - -/* on some architectures a pointer to a function is not just a pointer - to the actual code of the function but rather an architecture - specific descriptor. */ -#ifndef ELF_FUNCTION_PTR_IS_SPECIAL -# define DL_SYMBOL_ADDRESS(map, ref) \ - (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value) -# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr)) -# define DL_DT_INIT_ADDRESS(map, start) (start) -# define DL_DT_FINI_ADDRESS(map, start) (start) -#endif - -/* Unmap a loaded object, called by _dl_close (). */ -#ifndef DL_UNMAP_IS_SPECIAL -# define DL_UNMAP(map) \ - __munmap ((void *) (map)->l_map_start, \ - (map)->l_map_end - (map)->l_map_start) -#endif - -/* By default we do not need special support to initialize DSOs loaded - by statically linked binaries. */ -#ifndef DL_STATIC_INIT -# define DL_STATIC_INIT(map) -#endif - -/* Reloc type classes as returned by elf_machine_type_class(). - ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by - some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be - satisfied by any symbol in the executable. */ -#define ELF_RTYPE_CLASS_PLT 1 -#define ELF_RTYPE_CLASS_COPY 2 - -/* ELF uses the PF_x macros to specify the segment permissions, mmap - uses PROT_xxx. In most cases the three macros have the values 1, 2, - and 3 but not in a matching order. The following macros allows - converting from the PF_x values to PROT_xxx values. */ -#define PF_TO_PROT \ - ((PROT_READ << (PF_R * 4)) \ - | (PROT_WRITE << (PF_W * 4)) \ - | (PROT_EXEC << (PF_X * 4)) \ - | ((PROT_READ | PROT_WRITE) << ((PF_R | PF_W) * 4)) \ - | ((PROT_READ | PROT_EXEC) << ((PF_R | PF_X) * 4)) \ - | ((PROT_WRITE | PROT_EXEC) << (PF_W | PF_X) * 4) \ - | ((PROT_READ | PROT_WRITE | PROT_EXEC) << ((PF_R | PF_W | PF_X) * 4))) - - -/* For the version handling we need an array with only names and their - hash values. */ -struct r_found_version - { - const char *name; - ElfW(Word) hash; - - int hidden; - const char *filename; - }; - -/* We want to cache information about the searches for shared objects. */ - -enum r_dir_status { unknown, nonexisting, existing }; - -struct r_search_path_elem - { - /* This link is only used in the `all_dirs' member of `r_search_path'. */ - struct r_search_path_elem *next; - - /* Strings saying where the definition came from. */ - const char *what; - const char *where; - - /* Basename for this search path element. The string must end with - a slash character. */ - const char *dirname; - size_t dirnamelen; - - enum r_dir_status status[0]; - }; - -struct r_strlenpair - { - const char *str; - size_t len; - }; - - -/* A data structure for a simple single linked list of strings. */ -struct libname_list - { - const char *name; /* Name requested (before search). */ - struct libname_list *next; /* Link to next name for this object. */ - int dont_free; /* Flag whether this element should be freed - if the object is not entirely unloaded. */ - }; - - -/* Test whether given NAME matches any of the names of the given object. */ -static __inline int -__attribute__ ((unused)) -_dl_name_match_p (const char *__name, struct link_map *__map) -{ - int __found = strcmp (__name, __map->l_name) == 0; - struct libname_list *__runp = __map->l_libname; - - while (! __found && __runp != NULL) - if (strcmp (__name, __runp->name) == 0) - __found = 1; - else - __runp = __runp->next; - - return __found; -} - -/* Function used as argument for `_dl_receive_error' function. The - arguments are the error code, error string, and the objname the - error occurred in. */ -typedef void (*receiver_fct) (int, const char *, const char *); - -/* Internal functions of the run-time dynamic linker. - These can be accessed if you link again the dynamic linker - as a shared library, as in `-lld' or `/lib/ld.so' explicitly; - but are not normally of interest to user programs. - - The `-ldl' library functions in <dlfcn.h> provide a simple - user interface to run-time dynamic linking. */ - - -/* Parameters passed to the dynamic linker. */ -extern char **_dl_argv; - -/* Cached value of `getpagesize ()'. */ -extern size_t _dl_pagesize; - -/* OS version. */ -extern unsigned int _dl_osversion; - -/* File descriptor referring to the zero-fill device. */ -extern int _dl_zerofd; - -/* Name of the shared object to be profiled (if any). */ -extern const char *_dl_profile; -/* Map of shared object to be profiled. */ -extern struct link_map *_dl_profile_map; -/* Filename of the output file. */ -extern const char *_dl_profile_output; - -/* If nonzero the appropriate debug information is printed. */ -extern int _dl_debug_mask; -#define DL_DEBUG_LIBS (1 << 0) -#define DL_DEBUG_IMPCALLS (1 << 1) -#define DL_DEBUG_BINDINGS (1 << 2) -#define DL_DEBUG_SYMBOLS (1 << 3) -#define DL_DEBUG_VERSIONS (1 << 4) -#define DL_DEBUG_RELOC (1 << 5) -#define DL_DEBUG_FILES (1 << 6) -#define DL_DEBUG_STATISTICS (1 << 7) -/* This one is used only internally. */ -#define DL_DEBUG_HELP (1 << 8) - -/* Expect cache ID. */ -extern int _dl_correct_cache_id; - -/* Mask for hardware capabilities that are available. */ -extern unsigned long int _dl_hwcap; - -/* Mask for important hardware capabilities we honour. */ -extern unsigned long int _dl_hwcap_mask; - -/* File descriptor to write debug messages to. */ -extern int _dl_debug_fd; - -/* Names of shared object for which the RPATH should be ignored. */ -extern const char *_dl_inhibit_rpath; - -/* Nonzero if references should be treated as weak during runtime linking. */ -extern int _dl_dynamic_weak; - -/* The array with message we print as a last resort. */ -extern const char _dl_out_of_memory[]; - -/* Nonzero if runtime lookups should not update the .got/.plt. */ -extern int _dl_bind_not; - -/* List of search directories. */ -extern struct r_search_path_elem *_dl_all_dirs; -extern struct r_search_path_elem *_dl_init_all_dirs; - -/* OS-dependent function to open the zero-fill device. */ -extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */ - - -/* During the program run we must not modify the global data of - loaded shared object simultanously in two threads. Therefore we - protect `_dl_open' and `_dl_close' in dl-close.c. - - This must be a recursive lock since the initializer function of - the loaded object might as well require a call to this function. - At this time it is not anymore a problem to modify the tables. */ -__libc_lock_define_recursive (extern, _dl_load_lock) - - -/* Write message on the debug file descriptor. The parameters are - interpreted as for a `printf' call. All the lines start with a - tag showing the PID. */ -extern void _dl_debug_printf (const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); - -/* Write message on the debug file descriptor. The parameters are - interpreted as for a `printf' call. All the lines buf the first - start with a tag showing the PID. */ -extern void _dl_debug_printf_c (const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); - - -/* Write a message on the specified descriptor FD. The parameters are - interpreted as for a `printf' call. */ -extern void _dl_dprintf (int fd, const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - -/* Write a message on the specified descriptor standard output. The - parameters are interpreted as for a `printf' call. */ -#define _dl_printf(fmt, args...) \ - _dl_dprintf (STDOUT_FILENO, fmt, ##args) - -/* Write a message on the specified descriptor standard error. The - parameters are interpreted as for a `printf' call. */ -#define _dl_error_printf(fmt, args...) \ - _dl_dprintf (STDERR_FILENO, fmt, ##args) - -/* Write a message on the specified descriptor standard error and exit - the program. The parameters are interpreted as for a `printf' call. */ -#define _dl_fatal_printf(fmt, args...) \ - do \ - { \ - _dl_dprintf (STDERR_FILENO, fmt, ##args); \ - _exit (127); \ - } \ - while (1) - - -/* This function is called by all the internal dynamic linker functions - when they encounter an error. ERRCODE is either an `errno' code or - zero; OBJECT is the name of the problematical shared object, or null if - it is a general problem; ERRSTRING is a string describing the specific - problem. */ -extern void _dl_signal_error (int errcode, const char *object, - const char *occurred, const char *errstring) - internal_function - __attribute__ ((__noreturn__)); - -/* Like _dl_signal_error, but may return when called in the context of - _dl_receive_error. */ -extern void _dl_signal_cerror (int errcode, const char *object, - const char *occation, const char *errstring) - internal_function; - -/* Call OPERATE, receiving errors from `dl_signal_cerror'. Unlike - `_dl_catch_error' the operation is resumed after the OPERATE - function returns. - ARGS is passed as argument to OPERATE. */ -extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *), - void *args) - internal_function; - - -/* Open the shared object NAME and map in its segments. - LOADER's DT_RPATH is used in searching for NAME. - If the object is already opened, returns its existing map. - For preloaded shared objects PRELOADED is set to a non-zero - value to allow additional security checks. */ -extern struct link_map *_dl_map_object (struct link_map *loader, - const char *name, int preloaded, - int type, int trace_mode, int mode) - internal_function; - -/* Call _dl_map_object on the dependencies of MAP, and set up - MAP->l_searchlist. PRELOADS points to a vector of NPRELOADS previously - loaded objects that will be inserted into MAP->l_searchlist after MAP - but before its dependencies. */ -extern void _dl_map_object_deps (struct link_map *map, - struct link_map **preloads, - unsigned int npreloads, int trace_mode) - internal_function; - -/* Cache the locations of MAP's hash table. */ -extern void _dl_setup_hash (struct link_map *map) internal_function; - - -/* Search loaded objects' symbol tables for a definition of the symbol - referred to by UNDEF. *SYM is the symbol table entry containing the - reference; it is replaced with the defining symbol, and the base load - address of the defining object is returned. SYMBOL_SCOPE is a - null-terminated list of object scopes to search; each object's - l_searchlist (i.e. the segment of the dependency tree starting at that - object) is searched in turn. REFERENCE_NAME should name the object - containing the reference; it is used in error messages. - TYPE_CLASS describes the type of symbol we are looking for. */ -extern lookup_t _dl_lookup_symbol (const char *undef, - struct link_map *undef_map, - const ElfW(Sym) **sym, - struct r_scope_elem *symbol_scope[], - int type_class, int explicit) - internal_function; - -/* Lookup versioned symbol. */ -extern lookup_t _dl_lookup_versioned_symbol (const char *undef, - struct link_map *undef_map, - const ElfW(Sym) **sym, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - int type_class, int explicit) - internal_function; - -/* For handling RTLD_NEXT we must be able to skip shared objects. */ -extern lookup_t _dl_lookup_symbol_skip (const char *undef, - struct link_map *undef_map, - const ElfW(Sym) **sym, - struct r_scope_elem *symbol_scope[], - struct link_map *skip_this) - internal_function; - -/* For handling RTLD_NEXT with versioned symbols we must be able to - skip shared objects. */ -extern lookup_t _dl_lookup_versioned_symbol_skip (const char *undef, - struct link_map *undef_map, - const ElfW(Sym) **sym, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - struct link_map *skip_this) - internal_function; - -/* Look up symbol NAME in MAP's scope and return its run-time address. */ -extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name) - internal_function; - - -/* Structure describing the dynamic linker itself. */ -extern struct link_map _dl_rtld_map; -/* And a pointer to the map for the main map. */ -extern struct link_map *_dl_loaded; -/* Number of object in the _dl_loaded list. */ -extern unsigned int _dl_nloaded; -/* Array representing global scope. */ -extern struct r_scope_elem *_dl_global_scope[2]; -/* Direct pointer to the searchlist of the main object. */ -extern struct r_scope_elem *_dl_main_searchlist; -/* Copy of the content of `_dl_main_searchlist'. */ -extern struct r_scope_elem _dl_initial_searchlist; -/* This is zero at program start to signal that the global scope map is - allocated by rtld. Later it keeps the size of the map. It might be - reset if in _dl_close if the last global object is removed. */ -extern size_t _dl_global_scope_alloc; - -/* Allocate a `struct link_map' for a new object being loaded, - and enter it into the _dl_main_map list. */ -extern struct link_map *_dl_new_object (char *realname, const char *libname, - int type, struct link_map *loader) - internal_function; - -/* Relocate the given object (if it hasn't already been). - SCOPE is passed to _dl_lookup_symbol in symbol lookups. - If LAZY is nonzero, don't relocate its PLT. */ -extern void _dl_relocate_object (struct link_map *map, - struct r_scope_elem *scope[], - int lazy, int consider_profiling); - -/* Call _dl_signal_error with a message about an unhandled reloc type. - TYPE is the result of ELFW(R_TYPE) (r_info), i.e. an R_<CPU>_* value. - PLT is nonzero if this was a PLT reloc; it just affects the message. */ -extern void _dl_reloc_bad_type (struct link_map *map, - unsigned int type, int plt) - internal_function __attribute__ ((__noreturn__)); - -/* Check the version dependencies of all objects available through - MAP. If VERBOSE print some more diagnostics. */ -extern int _dl_check_all_versions (struct link_map *map, int verbose, - int trace_mode) - internal_function; - -/* Check the version dependencies for MAP. If VERBOSE print some more - diagnostics. */ -extern int _dl_check_map_versions (struct link_map *map, int verbose, - int trace_mode) - internal_function; - -/* Initialize the object in SCOPE by calling the constructors with - ARGC, ARGV, and ENV as the parameters. */ -extern void _dl_init (struct link_map *main_map, int argc, char **argv, - char **env) internal_function; - -/* Call the finalizer functions of all shared objects whose - initializer functions have completed. */ -extern void _dl_fini (void) internal_function; - -/* The dynamic linker calls this function before and having changing - any shared object mappings. The `r_state' member of `struct r_debug' - says what change is taking place. This function's address is - the value of the `r_brk' member. */ -extern void _dl_debug_state (void); - -/* Initialize `struct r_debug' if it has not already been done. The - argument is the run-time load address of the dynamic linker, to be put - in the `r_ldbase' member. Returns the address of the structure. */ -extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase) - internal_function; - -/* Initialize the basic data structure for the search paths. */ -extern void _dl_init_paths (const char *library_path) internal_function; - -/* Gather the information needed to install the profiling tables and start - the timers. */ -extern void _dl_start_profile (struct link_map *map, const char *output_dir) - internal_function; - -/* The actual functions used to keep book on the calls. */ -extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc); - -/* This function is simply a wrapper around the _dl_mcount function - which does not require a FROMPC parameter since this is the - calling function. */ -extern void _dl_mcount_wrapper (void *selfpc); - -/* Show the members of the auxiliary array passed up from the kernel. */ -extern void _dl_show_auxv (void) internal_function; - -/* Return all environment variables starting with `LD_', one after the - other. */ -extern char *_dl_next_ld_env_entry (char ***position) internal_function; - -/* Return an array with the names of the important hardware capabilities. */ -extern const struct r_strlenpair *_dl_important_hwcaps (const char *platform, - size_t paltform_len, - size_t *sz, - size_t *max_capstrlen) - internal_function; - -/* Look up NAME in ld.so.cache and return the file name stored there, - or null if none is found. */ -extern const char *_dl_load_cache_lookup (const char *name) - internal_function; - -/* If the system does not support MAP_COPY we cannot leave the file open - all the time since this would create problems when the file is replaced. - Therefore we provide this function to close the file and open it again - once needed. */ -extern void _dl_unload_cache (void); - -/* System-dependent function to read a file's whole contents in the - most convenient manner available. *SIZEP gets the size of the - file. On error MAP_FAILED is returned. */ -extern void *_dl_sysdep_read_whole_file (const char *file, size_t *sizep, - int prot) - internal_function; - -/* System-specific function to do initial startup for the dynamic linker. - After this, file access calls and getenv must work. This is responsible - for setting __libc_enable_secure if we need to be secure (e.g. setuid), - and for setting _dl_argc and _dl_argv, and then calling _dl_main. */ -extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, - void (*dl_main) (const ElfW(Phdr) *phdr, - ElfW(Word) phnum, - ElfW(Addr) *user_entry)); - -extern void _dl_sysdep_start_cleanup (void) - internal_function; - - -__END_DECLS - -#endif /* ldsodefs.h */ diff --git a/newlib/libc/sys/linux/dl/libintl.h b/newlib/libc/sys/linux/dl/libintl.h deleted file mode 100644 index 839210dea..000000000 --- a/newlib/libc/sys/linux/dl/libintl.h +++ /dev/null @@ -1,2 +0,0 @@ -#define N_(x) x - diff --git a/newlib/libc/sys/linux/dl/trusted-dirs.h b/newlib/libc/sys/linux/dl/trusted-dirs.h deleted file mode 100644 index 103d6e6bb..000000000 --- a/newlib/libc/sys/linux/dl/trusted-dirs.h +++ /dev/null @@ -1,7 +0,0 @@ -#define SYSTEM_DIRS \ - "/usr/local/lib/" - -#define SYSTEM_DIRS_LEN \ - 15 - -#define SYSTEM_DIRS_MAX_LEN 15 diff --git a/newlib/libc/sys/linux/dl/unsecvars.h b/newlib/libc/sys/linux/dl/unsecvars.h deleted file mode 100644 index efb951595..000000000 --- a/newlib/libc/sys/linux/dl/unsecvars.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Environment variable to be removed for SUID programs. The names are - all stuffed in a single string which means they have to be terminated - with a '\0' explicitly. */ -#define UNSECURE_ENVVARS \ - "LD_PRELOAD\0" \ - "LD_LIBRARY_PATH\0" \ - "LD_ORIGIN_PATH\0" \ - "LD_DEBUG_OUTPUT\0" \ - "LD_PROFILE\0" \ - "GCONV_PATH\0" \ - "HOSTALIASES\0" \ - "LOCALDOMAIN\0" \ - "LOCPATH\0" \ - "MALLOC_TRACE\0" \ - "NLSPATH\0" \ - "RESOLV_HOST_CONF\0" \ - "RES_OPTIONS\0" \ - "TMPDIR\0" \ - "TZDIR\0" |