Subject: bug#13783: simplify data_start configuration for Emacs

From: Paul Eggert <[email-masked]>
Date: Fri, 22 Feb 2013 17:36:13 -0800

On 02/22/13 13:34, Eli Zaretskii wrote:
>> From: Paul Eggert <[email-masked]>
>>
>> The patch omits data_start on hosts that use the system malloc,
>> since data_start is now needed only on hosts where GNU Emacs
>> supplies malloc.
> 
> You mean, gmalloc?  How does that come into play?

With the patch, data_start is used only by vm-limit.c.
And vm-limit.c is compiled only when using gmalloc,
as its isn't valid when using a system malloc.

> It seems like data_start and data_size derived from it matter only
> when displaying memory usage warnings -- is that correct?

Yes.

> If so, why doesn't this matter when system malloc is used?

When the system malloc is used Emacs can't warn about low memory,
because it has no way of knowing when memory is low.

> The MS-Windows build computes data_start and data_size inside
> unexw32.c at dump time -- is that good enough?  (I'm asking because
> your change doesn't touch the Windows build.)

Yes, it should be, but that points out a problem with the latest
patch -- it should use DATA_START for MS platforms.  Here's a further
patch to fix that, and I'm attaching the resulting combined patch,
relative to trunk bzr 111860.

=== modified file 'src/vm-limit.c'
--- src/vm-limit.c	2013-02-22 19:26:07 +0000
+++ src/vm-limit.c	2013-02-23 01:28:04 +0000
@@ -22,6 +22,7 @@
 
 #ifdef MSDOS
 #include <dpmi.h>
+extern int etext;
 #endif
 
 /* Some systems need this before <sys/resource.h>.  */
@@ -38,12 +39,16 @@
 
 /* Start of data.  It is OK if this is approximate; it's used only as
    a heuristic.  */
+#ifdef DATA_START
+# define data_start ((char *) DATA_START)
+#else
 extern char data_start[];
-#ifndef HAVE_DATA_START
+# ifndef HAVE_DATA_START
 /* Initialize to nonzero, so that it's put into data and not bss.
    Link this file's object code first, so that this symbol is near the
    start of data.  */
 char data_start[1] = { 1 };
+# endif
 #endif
 
 /*

=== modified file 'ChangeLog'
--- ChangeLog	2013-02-21 22:42:56 +0000
+++ ChangeLog	2013-02-22 08:21:55 +0000
@@ -1,3 +1,12 @@
+2013-02-22  Paul Eggert  <[email-masked]>
+
+	Simplify data_start configuration (Bug#13783).
+	* configure.ac (CRT_DIR, LIB_STANDARD, START_FILES, DATA_START)
+	(LD_FIRSTFLAG, ORDINARY_LINK, LIB_GCC): Remove.
+	(AC_CHECK_HEADERS_ONCE): Remove sys/resource.h, as it's
+	not always needed.
+	(HAVE_DATA_START): New macro.
+
 2013-02-21  Paul Eggert  <[email-masked]>
 
 	Parallelize documentation builds.

=== modified file 'admin/CPP-DEFINES'
--- admin/CPP-DEFINES	2012-12-14 18:59:00 +0000
+++ admin/CPP-DEFINES	2013-02-22 08:11:05 +0000
@@ -90,7 +90,6 @@
 BROKEN_PTY_READ_AFTER_EAGAIN
 CLASH_DETECTION
 DATA_SEG_BITS
-DATA_START
 DEFAULT_SOUND_DEVICE
 DEVICE_SEP
 DIRECTORY_SEP
@@ -408,7 +407,6 @@
 NSIG
 NSIG_MINIMUM
 NULL_DEVICE
-ORDINARY_LINK
 PAGESIZE
 PREFER_VSUSP
 PTY_ITERATION

=== modified file 'admin/ChangeLog'
--- admin/ChangeLog	2013-02-11 23:37:18 +0000
+++ admin/ChangeLog	2013-02-22 08:21:55 +0000
@@ -1,3 +1,8 @@
+2013-02-22  Paul Eggert  <[email-masked]>
+
+	Simplify data_start configuration (Bug#13783).
+	* CPP-DEFINES (DATA_START, ORDINARY_LINK): Remove.
+
 2013-02-11  Paul Eggert  <[email-masked]>
 
 	Tune by using memchr and memrchr.

=== modified file 'configure.ac'
--- configure.ac	2013-02-15 06:35:54 +0000
+++ configure.ac	2013-02-22 08:11:05 +0000
@@ -230,12 +230,6 @@
    fi
 fi
 
-CRT_DIR=
-AC_ARG_WITH([crt-dir],dnl
-[AS_HELP_STRING([--with-crt-dir=DIR],[directory containing crtn.o etc.
-The default is /usr/lib, or /usr/lib64 on some platforms.])])
-CRT_DIR="${with_crt_dir}"
-
 AC_ARG_WITH(gameuser,dnl
 [AS_HELP_STRING([--with-gameuser=USER],[user for shared game score files])])
 test "X${with_gameuser}" != X && test "${with_gameuser}" != yes \
@@ -1051,42 +1045,29 @@

 LIB_MATH=-lm
-LIB_STANDARD=
-START_FILES=
 dnl Current possibilities handled by sed (aix4-2 -> aix,
 dnl gnu-linux -> gnu/linux, etc.):
 dnl gnu, gnu/linux, gnu/kfreebsd, aix, cygwin, darwin, hpux, irix.
 dnl And special cases: berkeley-unix, usg-unix-v, ms-dos, windows-nt.
 SYSTEM_TYPE=`echo $opsys | sed -e 's/[[0-9]].*//' -e 's|-|/|'`
 
-dnl NB do not use CRT_DIR unquoted here, since it might not be set yet.
 case $opsys in
   cygwin )
     LIB_MATH=
-    START_FILES='pre-crt0.o'
     ;;
   darwin )
     ## Adding -lm confuses the dynamic linker, so omit it.
     LIB_MATH=
-    START_FILES='pre-crt0.o'
     ;;
   freebsd )
-    LIB_STANDARD='-lgcc -lc -lgcc $(CRT_DIR)/crtn.o'
-    START_FILES='pre-crt0.o $(CRT_DIR)/crt1.o $(CRT_DIR)/crti.o'
     SYSTEM_TYPE=berkeley-unix
     ;;
   gnu-linux | gnu-kfreebsd )
-    LIB_STANDARD='-lgcc -lc -lgcc $(CRT_DIR)/crtn.o'
-    START_FILES='pre-crt0.o $(CRT_DIR)/crt1.o $(CRT_DIR)/crti.o'
     ;;
   hpux10-20 | hpux11 )
-    LIB_STANDARD=-lc
-    START_FILES='pre-crt0.o $(CRT_DIR)/crt0.o'
     ;;
   dnl NB this may be adjusted below.
   netbsd | openbsd )
-    LIB_STANDARD='-lgcc -lc -lgcc $(CRT_DIR)/crtend.o'
-    START_FILES='pre-crt0.o $(CRT_DIR)/crt0.o $(CRT_DIR)/crtbegin.o'
     SYSTEM_TYPE=berkeley-unix
     ;;
 
@@ -1097,96 +1078,9 @@
 esac
 
 AC_SUBST(LIB_MATH)
-AC_SUBST(START_FILES)
 AC_DEFINE_UNQUOTED(SYSTEM_TYPE, "$SYSTEM_TYPE",
   [The type of system you are compiling for; sets `system-type'.])
 
-dnl Not all platforms use crtn.o files.  Check if the current one does.
-crt_files=
-
-for file in x $LIB_STANDARD $START_FILES; do
-  case "$file" in
-    *CRT_DIR*) crt_files="$crt_files `echo $file | sed -e 's|.*/||'`" ;;
-  esac
-done
-
-if test "x$crt_files" != x; then
-
-  ## If user specified a crt-dir, use that unconditionally.
-  crt_gcc=no
-
-  if test "X$CRT_DIR" = "X"; then
-
-    CRT_DIR=/usr/lib            # default
-
-    case "$canonical" in
-      x86_64-*-linux-gnu* | s390x-*-linux-gnu*)
-      ## On x86-64 and s390x GNU/Linux distributions, the standard library
-      ## can be in a variety of places.  We only try /usr/lib64 and /usr/lib.
-      ## For anything else (eg /usr/lib32), it is up the user to specify
-      ## the location (bug#5655).
-      ## Test for crtn.o, not just the directory, because sometimes the
-      ## directory exists but does not have the relevant files (bug#1287).
-      ## FIXME better to test for binary compatibility somehow.
-      test -e /usr/lib64/crtn.o && CRT_DIR=/usr/lib64
-      ;;
-
-      powerpc64-*-linux-gnu* | sparc64-*-linux-gnu*) CRT_DIR=/usr/lib64 ;;
-    esac
-
-    case "$opsys" in
-      hpux10-20) CRT_DIR=/lib ;;
-    esac
-
-    test "x${GCC}" = xyes && crt_gcc=yes
-
-  fi                            # CRT_DIR = ""
-
-  crt_missing=
-
-  for file in $crt_files; do
-
-    ## If we're using gcc, try to determine it automatically by asking
-    ## gcc.  [If this doesn't work, CRT_DIR will remain at the
-    ## system-dependent default from above.]
-    if test $crt_gcc = yes && test ! -e $CRT_DIR/$file; then
-
-       crt_file=`$CC --print-file-name=$file 2>/dev/null`
-       case "$crt_file" in
-         */*)
-           CRT_DIR=`AS_DIRNAME(["$crt_file"])`
-           ;;
-       esac
-    fi
-
-    dnl We expect all the files to be in a single directory, so after the
-    dnl first there is no point asking gcc.
-    crt_gcc=no
-
-    test -e $CRT_DIR/$file || crt_missing="$crt_missing $file"
-  done                          # $crt_files
-
-  test "x$crt_missing" = x || \
-    AC_MSG_ERROR([Required file(s) not found:$crt_missing
-Try using the --with-crt-dir option.])
-
-fi                              # crt_files != ""
-
-AC_SUBST(CRT_DIR)
-
-case $opsys in
-  netbsd | openbsd )
-    if test -f $CRT_DIR/crti.o; then
-
-        test -f $CRT_DIR/crtn.o || \
-          AC_MSG_ERROR([Required file not found: crtn.o])
-
-        LIB_STANDARD='-lgcc -lc -lgcc $(CRT_DIR)/crtend.o $(CRT_DIR)/crtn.o'
-        START_FILES='pre-crt0.o $(CRT_DIR)/crt0.o $(CRT_DIR)/crti.o $(CRT_DIR)/crtbegin.o'
-    fi
-    ;;
-esac
-
 
 pre_PKG_CONFIG_CFLAGS=$CFLAGS
 pre_PKG_CONFIG_LIBS=$LIBS
@@ -1304,7 +1198,7 @@
 AC_CHECK_HEADERS_ONCE(
   linux/version.h sys/systeminfo.h
   coff.h pty.h
-  sys/vlimit.h sys/resource.h
+  sys/resource.h
   sys/utsname.h pwd.h utmp.h util.h)
 
 AC_MSG_CHECKING(if personality LINUX32 can be set)
@@ -1521,8 +1415,6 @@
      CFLAGS="$CFLAGS -I${GNUSTEP_SYSTEM_HEADERS} ${GNUSTEP_LOCAL_HEADERS}"
      LDFLAGS="$LDFLAGS -L${GNUSTEP_SYSTEM_LIBRARIES} ${GNUSTEP_LOCAL_LIBRARIES}"
      LIBS_GNUSTEP="-lgnustep-gui -lgnustep-base -lobjc -lpthread"
-     LIB_STANDARD=
-     START_FILES=
      dnl GNUstep defines BASE_NATIVE_OBJC_EXCEPTIONS to 0 or 1.
      dnl If they had chosen to either define it or not, we could have
      dnl just used AC_CHECK_DECL here.
@@ -1611,7 +1503,6 @@
 AC_SUBST(ns_self_contained)
 AC_SUBST(NS_OBJ)
 AC_SUBST(NS_OBJC_OBJ)
-AC_SUBST(LIB_STANDARD)
 
 HAVE_W32=no
 W32_OBJ=
@@ -1751,6 +1642,20 @@
 else
   test "$doug_lea_malloc" != "yes" && GMALLOC_OBJ=gmalloc.o
   VMLIMIT_OBJ=vm-limit.o
+
+  AC_CHECK_HEADERS([sys/vlimit.h])
+  AC_CACHE_CHECK([for data_start], [emacs_cv_data_start],
+    [AC_LINK_IFELSE(
+       [AC_LANG_PROGRAM(
+	 [[extern char data_start[]; char ch;]],
+	 [[return data_start == &ch;]])],
+       [emacs_cv_data_start=yes],
+       [emacs_cv_data_start=no])])
+  if test $emacs_cv_data_start = yes; then
+    AC_DEFINE([HAVE_DATA_START], 1,
+      [Define to 1 if data_start is the address of the start
+       of the main data segment.])
+  fi
 fi
 AC_SUBST(GMALLOC_OBJ)
 AC_SUBST(VMLIMIT_OBJ)
@@ -3735,9 +3640,7 @@
 esac

-dnl Used in vm-limit.c
-AH_TEMPLATE(DATA_START, [Address of the start of the data segment.])
-dnl Used in lisp.h, emacs.c, mem-limits.h
+dnl Used in lisp.h, emacs.c, vm-limit.c
 dnl NEWS.18 describes this as "a number which contains
 dnl the high bits to be inclusive or'ed with pointers that are unpacked."
 AH_TEMPLATE(DATA_SEG_BITS, [Extra bits to be or'd in with any pointers
@@ -3745,23 +3648,15 @@
 dnl if Emacs uses fewer than 32 bits for the value field of a LISP_OBJECT.
 
 case $opsys in
-  gnu)
-    dnl libc defines data_start.
-    AC_DEFINE(DATA_START, [({ extern int data_start; (char *) &data_start; })])
-    ;;
-
   aix*)
     dnl This works with 32-bit executables; Emacs doesn't support 64-bit.
-    AC_DEFINE(DATA_START, [0x20000000])
     AC_DEFINE(DATA_SEG_BITS, [0x20000000])
     ;;
   hpux*)
     dnl The data segment on this machine always starts at address 0x40000000.
-    AC_DEFINE(DATA_START, [0x40000000])
     AC_DEFINE(DATA_SEG_BITS, [0x40000000])
     ;;
   irix6-5)
-    AC_DEFINE(DATA_START, [0x10000000])
     AC_DEFINE(DATA_SEG_BITS, [0x10000000])
     ;;
 esac
@@ -4321,88 +4216,6 @@
 
 AC_SUBST(LD_SWITCH_SYSTEM_TEMACS)
 
-
-LD_FIRSTFLAG=
-ORDINARY_LINK=
-case "$opsys" in
-  ## gnu: GNU needs its own crt0.
-  aix4-2|cygwin|darwin|gnu|hpux*|irix6-5|sol2*|unixware) ORDINARY_LINK=yes ;;
-
-  ## On post 1.3 releases of NetBSD, gcc -nostdlib also clears the
-  ## library search parth, i.e. it won't search /usr/lib for libc and
-  ## friends.  Using -nostartfiles instead avoids this problem, and
-  ## will also work on earlier NetBSD releases.
-  netbsd|openbsd) LD_FIRSTFLAG="-nostartfiles" ;;
-
-  ## powerpc*: NAKAJI Hiroyuki <[email-masked]> says
-  ##   MkLinux/LinuxPPC needs this.
-  ## s390x-* only supports opsys = gnu-linux so it can be added here.
-  gnu-*)
-    case "$canonical" in
-      powerpc*|s390x-*) LD_FIRSTFLAG="-nostdlib" ;;
-    esac
-    ;;
-esac
-
-
-if test "x$ORDINARY_LINK" = "xyes"; then
-
-  LD_FIRSTFLAG=""
-  AC_DEFINE(ORDINARY_LINK, 1, [Define if the C compiler is the linker.])
-
-## The system files defining neither ORDINARY_LINK nor LD_FIRSTFLAG are:
-## freebsd, gnu-* not on powerpc*|s390x*.
-elif test "x$GCC" = "xyes" && test "x$LD_FIRSTFLAG" = "x"; then
-
-  ## Versions of GCC >= 2.0 put their library, libgcc.a, in obscure
-  ## places that are difficult to figure out at make time.  Fortunately,
-  ## these same versions allow you to pass arbitrary flags on to the
-  ## linker, so there is no reason not to use it as a linker.
-  ##
-  ## Well, it is not quite perfect.  The "-nostdlib" keeps GCC from
-  ## searching for libraries in its internal directories, so we have to
-  ## ask GCC explicitly where to find libgcc.a (LIB_GCC below).
-  LD_FIRSTFLAG="-nostdlib"
-fi
-
-## FIXME? What setting of EDIT_LDFLAGS should this have?
-test "$NS_IMPL_GNUSTEP" = "yes" && LD_FIRSTFLAG="-rdynamic"
-
-AC_SUBST(LD_FIRSTFLAG)
-
-
-## FIXME? The logic here is not precisely the same as that above.
-## There is no check here for a pre-defined LD_FIRSTFLAG.
-## Should we only be setting LIB_GCC if LD ~ -nostdlib?
-LIB_GCC=
-if test "x$GCC" = "xyes" && test "x$ORDINARY_LINK" != "xyes"; then
-
-  case "$opsys" in
-    freebsd|netbsd|openbsd) LIB_GCC= ;;
-
-    gnu-*)
-      ## [email-masked] reported that the lgcc_s flag is necessary to
-      ## build on ARM EABI under GNU/Linux.  (Bug#5518)
-      case $host_cpu in
-      arm*)
-        LIB_GCC="-lgcc_s"
-	;;
-      *)
-        ## FIXME? s/gnu-linux.h used to define LIB_GCC as below, then
-        ## immediately undefine it again and redefine it to empty.
-        ## Was the C_SWITCH_X_SITE part really necessary?
-##      LIB_GCC=`$CC $C_SWITCH_X_SITE -print-libgcc-file-name`
-        LIB_GCC=
-	;;
-      esac
-      ;;
-
-    ## Ask GCC where to find libgcc.a.
-    *) LIB_GCC=`$CC -print-libgcc-file-name 2> /dev/null` ;;
-  esac
-fi                              dnl if $GCC
-AC_SUBST(LIB_GCC)
-
 ## Common for all window systems
 if test "$window_system" != "none"; then
   AC_DEFINE(HAVE_WINDOW_SYSTEM, 1, [Define if you have a window system.])

=== modified file 'etc/ChangeLog'
--- etc/ChangeLog	2013-02-19 14:44:03 +0000
+++ etc/ChangeLog	2013-02-22 08:21:55 +0000
@@ -1,3 +1,10 @@
+2013-02-22  Paul Eggert  <[email-masked]>
+
+	Simplify data_start configuration (Bug#13783).
+	* PROBLEMS (LIBS_SYSTEM, LIBS_MACHINE, LIBS_STANDARD): Remove.
+	Remove legacy-systems section, as this stuff is no longer
+	applicable with current linking strategies.
+
 2013-02-14  Michael Albinus  <[email-masked]>
 
 	* NEWS: Tramp methods "scpc" and "rsyncc" are discontinued.

=== modified file 'etc/PROBLEMS'
--- etc/PROBLEMS	2013-02-11 00:35:37 +0000
+++ etc/PROBLEMS	2013-02-22 08:11:05 +0000
@@ -432,21 +432,7 @@
 installed in the shared library, and then relink Emacs.
 
 If you have already installed the name resolver in the file libresolv.a,
-then you need to compile Emacs to use that library.  The easiest way to
-do this is to add to config.h a definition of LIBS_SYSTEM, LIBS_MACHINE
-or LIB_STANDARD which uses -lresolv.  Watch out!  If you redefine a macro
-that is already in use in your configuration to supply some other libraries,
-be careful not to lose the others.
-
-Thus, you could start by adding this to config.h:
-
-#define LIBS_SYSTEM -lresolv
-
-Then if this gives you an error for redefining a macro, and you see that
-config.h already defines LIBS_SYSTEM as -lfoo -lbar at some other point
-(possibly in an included file) you could change it to say this:
-
-#define LIBS_SYSTEM -lresolv -lfoo -lbar
+then you need to compile Emacs to use that library.
 
 *** Emacs does not know your host's fully-qualified domain name.
 
@@ -3179,25 +3165,6 @@
 
 This problem seems to be a matter of configuring the DECserver to use
 7 bit characters rather than 8 bit characters.
-
-* Build problems on legacy systems
-
-** SunOS: Emacs gets error message from linker on Sun.
-
-If the error message says that a symbol such as `f68881_used' or
-`ffpa_used' or `start_float' is undefined, this probably indicates
-that you have compiled some libraries, such as the X libraries,
-with a floating point option other than the default.
-
-It's not terribly hard to make this work with small changes in
-crt0.c together with linking with Fcrt1.o, Wcrt1.o or Mcrt1.o.
-However, the easiest approach is to build Xlib with the default
-floating point option: -fsoft.
-
-** HPUX 10.20: Emacs crashes during dumping on the HPPA machine.
-
-This seems to be due to a GCC bug; it is fixed in GCC 2.8.1.
-
 
 This file is part of GNU Emacs.

=== modified file 'src/ChangeLog'
--- src/ChangeLog	2013-02-22 19:23:12 +0000
+++ src/ChangeLog	2013-02-22 20:10:54 +0000
@@ -1,5 +1,36 @@
 2013-02-22  Paul Eggert  <[email-masked]>
 
+	Simplify data_start configuration (Bug#13783).
+	This is a followon simplification to the fix for Bug#13650.
+	* Makefile.in (LD_FIRSTFLAG, LIB_GCC, CRT_DIR, LIB_STANDARD)
+	(START_FILES): Remove.  All uses removed.
+	(otherobj): Remove $(VMLIMIT_OBJ), as it's now first.
+	(ALLOBJS): Move here from autodeps.mk, and with VMLIMITS_OBJ first.
+	(buildobj.h): Use it.
+	($(ALLOBJS)): Depend on globals.h.
+	(temacs$(EXEEXT)): Use $(ALLOBJS).
+	* autodeps.mk (ALLOBJS): Move to Makefile.in.
+	* deps.mk (vm-limit.o):
+	* makefile.w32-in ($(BLD)/vm-limit.$(O)):
+	Do not depend on mem-limits.h.
+	* emacs.c (__do_global_ctors, __do_global_ctors_aux)
+	(__do_global_dtors, __CTOR_LIST__, __DTOR_LIST__)
+	[__GNUC__ && !ORDINARY_LINK]: Remove.
+	* mem-limits.h, pre-crt0.c: Remove.
+	* unexaix.c, unexcoff.c: Don't include mem-limits.h.
+	* unexcoff.c (etext): New decl.
+	(make_hdr): Use it instead of start_of_data.
+	* vm-limit.c: Move most of mem-limits.h's contents here.
+	(data_start): New decl.  It's OK if this is approximate,
+	so simplify-away some unnecessary exactness.
+	(POINTER): Remove; all uses removed.
+	(data_space_start): Now char *, to avoid casts.
+	(exceeds_lisp_ptr): New function, replacing the old
+	EXCEEDS_LISP_PTR macro.  All uses changed.
+	(check_memory_limits): Simplify and remove casts.
+	(start_of_data) [!CANNOT_DUMP || !SYSTEM_MALLOC]: Remove.
+	(memory_warnings): Use data_start instead of start_of_data.
+
 	Assume C89 or better.
 	* ralloc.c (SIZE, POINTER, NIL):
 	* vm-limit.c (POINTER):

=== modified file 'src/Makefile.in'
--- src/Makefile.in	2013-01-02 16:13:04 +0000
+++ src/Makefile.in	2013-02-22 20:10:54 +0000
@@ -36,7 +36,6 @@
 CFLAGS = @CFLAGS@
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
-LD_FIRSTFLAG=@LD_FIRSTFLAG@
 EXEEXT = @EXEEXT@
 version = @version@
 # Substitute an assignment for the MAKE variable, because
@@ -102,10 +101,8 @@
 ## System-specific LDFLAGS.
 LD_SWITCH_SYSTEM=@LD_SWITCH_SYSTEM@
 
-## This holds any special options for linking temacs only (ie, not
-## used by configure).  Not used elsewhere because it sometimes
-## contains options that have to do with using Emacs's crt0,
-## which are only good with temacs.
+## This holds any special options for linking temacs only (i.e., not
+## used by configure).
 LD_SWITCH_SYSTEM_TEMACS=@LD_SWITCH_SYSTEM_TEMACS@
 
 ## Flags to pass to ld only for temacs.
@@ -120,14 +117,6 @@
 ## Some systems define this to request special libraries.
 LIBS_SYSTEM=@LIBS_SYSTEM@
 
-## Where to find libgcc.a, if using gcc and necessary.
-LIB_GCC=@LIB_GCC@
-
-CRT_DIR=@CRT_DIR@
-## May use $CRT_DIR.
-LIB_STANDARD=@LIB_STANDARD@
-START_FILES = @START_FILES@
-
 ## -lm, or empty.
 LIB_MATH=@LIB_MATH@
 
@@ -389,17 +378,16 @@
 
 ## List of object files that make-docfile should not be told about.
 otherobj= $(TERMCAP_OBJ) $(PRE_ALLOC_OBJ) $(GMALLOC_OBJ) $(RALLOC_OBJ) \
-  $(POST_ALLOC_OBJ) $(VMLIMIT_OBJ) $(WIDGET_OBJ) $(LIBOBJS)
+  $(POST_ALLOC_OBJ) $(WIDGET_OBJ) $(LIBOBJS)
 
+## All object files linked into temacs.  $(VMLIMIT_OBJ) should be first.
+ALLOBJS = $(VMLIMIT_OBJ) $(obj) $(otherobj)
 
 ## Configure inserts the file lisp.mk at this point, defining $lisp.
 @lisp_frag@

 ## Construct full set of libraries to be linked.
-## Note that SunOS needs -lm to come before -lc; otherwise, you get
-## duplicated symbols.  If the standard libraries were compiled
-## with GCC, we might need LIB_GCC again after them.
 LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
    $(LIBX_OTHER) $(LIBSOUND) \
    $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \
@@ -409,7 +397,7 @@
    $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
    $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
    $(LIBACL_LIBS) $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(LIB_PTHREAD_SIGMASK) \
-   $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC)
+   $(LIB_MATH)
 
 all: emacs$(EXEEXT) $(OTHER_FILES)
 .PHONY: all
@@ -456,7 +444,7 @@
 	cd $(libsrc); $(MAKE) $(MFLAGS) make-docfile$(EXEEXT)
 
 buildobj.h: Makefile
-	echo "#define BUILDOBJ \"$(obj) $(otherobj) " "\"" > buildobj.h
+	echo "#define BUILDOBJ \"$(ALLOBJS) " "\"" >$@
 
 globals.h: gl-stamp; @true
 
@@ -468,15 +456,15 @@
 	$(srcdir)/../build-aux/move-if-change gl-tmp globals.h
 	echo timestamp > $@
 
-$(obj) $(otherobj): globals.h
+$(ALLOBJS): globals.h
 
 $(lib)/libgnu.a: $(config_h)
 	cd $(lib) && $(MAKE) libgnu.a
 
-temacs$(EXEEXT): $(START_FILES) stamp-oldxmenu $(obj) $(otherobj) \
+temacs$(EXEEXT): stamp-oldxmenu $(ALLOBJS) \
 	         $(lib)/libgnu.a $(W32_RES)
-	$(CC) $(LD_FIRSTFLAG) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
-	  -o temacs $(START_FILES) $(obj) $(otherobj) $(lib)/libgnu.a $(LIBES) \
+	$(CC) $(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
+	  -o temacs $(ALLOBJS) $(lib)/libgnu.a $(LIBES) \
 	  $(W32_RES_LINK)
 	test "$(CANNOT_DUMP)" = "yes" || \
 	  test "X$(PAXCTL)" = X || $(PAXCTL) -r temacs$(EXEEXT)

=== modified file 'src/autodeps.mk'
--- src/autodeps.mk	2010-07-08 03:31:04 +0000
+++ src/autodeps.mk	2013-02-22 20:10:54 +0000
@@ -2,5 +2,4 @@
 
 ## This is inserted in src/Makefile if AUTO_DEPEND=yes.
 
-ALLOBJS=$(START_FILES) ${obj} ${otherobj}
 -include $(ALLOBJS:%.o=${DEPDIR}/%.d)

=== modified file 'src/deps.mk'
--- src/deps.mk	2013-01-02 16:13:04 +0000
+++ src/deps.mk	2013-02-22 08:11:05 +0000
@@ -144,7 +144,7 @@
    dispextern.h lisp.h globals.h $(config_h) systime.h coding.h composite.h
 gmalloc.o: gmalloc.c $(config_h)
 ralloc.o: ralloc.c lisp.h $(config_h)
-vm-limit.o: vm-limit.c mem-limits.h lisp.h globals.h $(config_h)
+vm-limit.o: vm-limit.c lisp.h globals.h $(config_h)
 marker.o: marker.c buffer.h character.h lisp.h globals.h $(config_h)
 minibuf.o: minibuf.c syntax.h frame.h window.h keyboard.h systime.h \
    buffer.h commands.h character.h msdos.h $(INTERVALS_H) keymap.h \

=== modified file 'src/emacs.c'
--- src/emacs.c	2013-02-07 06:23:54 +0000
+++ src/emacs.c	2013-02-22 08:11:05 +0000
@@ -521,32 +521,6 @@
 static char const dump_tz[] = "UtC0";
 #endif
 
-#ifndef ORDINARY_LINK
-/* We don't include crtbegin.o and crtend.o in the link,
-   so these functions and variables might be missed.
-   Provide dummy definitions to avoid error.
-   (We don't have any real constructors or destructors.)  */
-#ifdef __GNUC__
-
-/* Define a dummy function F.  Declare F too, to pacify gcc
-   -Wmissing-prototypes.  */
-#define DEFINE_DUMMY_FUNCTION(f) \
-  void f (void) ATTRIBUTE_CONST EXTERNALLY_VISIBLE; void f (void) {}
-
-#ifndef GCC_CTORS_IN_LIBC
-DEFINE_DUMMY_FUNCTION (__do_global_ctors)
-DEFINE_DUMMY_FUNCTION (__do_global_ctors_aux)
-DEFINE_DUMMY_FUNCTION (__do_global_dtors)
-/* GNU/Linux has a bug in its library; avoid an error.  */
-#ifndef GNU_LINUX
-char * __CTOR_LIST__[2] EXTERNALLY_VISIBLE = { (char *) (-1), 0 };
-#endif
-char * __DTOR_LIST__[2] EXTERNALLY_VISIBLE = { (char *) (-1), 0 };
-#endif /* GCC_CTORS_IN_LIBC */
-DEFINE_DUMMY_FUNCTION (__main)
-#endif /* __GNUC__ */
-#endif /* ORDINARY_LINK */
-
 /* Test whether the next argument in ARGV matches SSTR or a prefix of
    LSTR (at least MINLEN characters).  If so, then if VALPTR is non-null
    (the argument is supposed to have a value) store in *VALPTR either

=== modified file 'src/makefile.w32-in'
--- src/makefile.w32-in	2013-02-13 00:50:38 +0000
+++ src/makefile.w32-in	2013-02-22 08:11:05 +0000
@@ -1492,7 +1492,6 @@
 
 $(BLD)/vm-limit.$(O) : \
 	$(SRC)/vm-limit.c \
-	$(SRC)/mem-limits.h \
 	$(SRC)/w32heap.h \
 	$(NT_INC)/unistd.h \
 	$(CONFIG_H) \

=== removed file 'src/mem-limits.h'
--- src/mem-limits.h	2013-01-01 09:11:05 +0000
+++ src/mem-limits.h	1970-01-01 00:00:00 +0000
@@ -1,43 +0,0 @@
-/* Includes for memory limit warnings.
-   Copyright (C) 1990, 1993-1996, 2001-2013 Free Software Foundation,
-   Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#ifdef MSDOS
-#include <dpmi.h>
-extern int etext;
-#endif
-
-/* Some systems need this before <sys/resource.h>.  */
-#include <sys/types.h>
-
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/time.h>
-# include <sys/resource.h>
-#else
-# if HAVE_SYS_VLIMIT_H
-#  include <sys/vlimit.h>	/* Obsolete, says glibc */
-# endif
-#endif
-
-extern char *start_of_data (void) ATTRIBUTE_CONST;
-#if USE_LSB_TAG || UINTPTR_MAX <= VAL_MAX
-#define EXCEEDS_LISP_PTR(ptr) 0
-#else
-#define EXCEEDS_LISP_PTR(ptr) \
-  (((uintptr_t) (ptr) & ~DATA_SEG_BITS) >> VALBITS)
-#endif

=== removed file 'src/pre-crt0.c'
--- src/pre-crt0.c	2013-02-12 18:33:42 +0000
+++ src/pre-crt0.c	1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-/* This file is loaded before crt0.o on machines where we do not
-   remap part of the data space into text space in unexec.
-   On these machines, there is no problem with standard crt0.o's
-   that make environ an initialized variable.  However, we do
-   need to make sure the label data_start exists anyway.  */
-
-/* Create a label to appear at the beginning of data space.
-   Its value is nonzero so that it cannot be put into bss.  */
-
-int data_start = 1;

=== modified file 'src/unexaix.c'
--- src/unexaix.c	2013-02-15 06:35:54 +0000
+++ src/unexaix.c	2013-02-22 08:11:05 +0000
@@ -59,8 +59,6 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-#include "mem-limits.h"
-
 extern char _data[];
 extern char _text[];

=== modified file 'src/unexcoff.c'
--- src/unexcoff.c	2013-01-02 16:13:04 +0000
+++ src/unexcoff.c	2013-02-22 19:43:17 +0000
@@ -99,7 +99,7 @@
 
 #include <sys/file.h>
 
-#include "mem-limits.h"
+extern int etext[];
 
 static long block_copy_start;		/* Old executable start point */
 static struct filehdr f_hdr;		/* File header */
@@ -168,7 +168,7 @@
   pagemask = getpagesize () - 1;
 
   /* Adjust text/data boundary. */
-  data_start = (int) start_of_data ();
+  data_start = (int) (etext + 1);
   data_start = ADDR_CORRECT (data_start);
   data_start = data_start & ~pagemask; /* (Down) to page boundary. */

=== modified file 'src/vm-limit.c'
--- src/vm-limit.c	2013-02-22 19:23:12 +0000
+++ src/vm-limit.c	2013-02-23 01:28:50 +0000
@@ -19,7 +19,37 @@
 #include <config.h>
 #include <unistd.h> /* for 'environ', on AIX */
 #include "lisp.h"
-#include "mem-limits.h"
+
+#ifdef MSDOS
+#include <dpmi.h>
+extern int etext;
+#endif
+
+/* Some systems need this before <sys/resource.h>.  */
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/time.h>
+# include <sys/resource.h>
+#else
+# if HAVE_SYS_VLIMIT_H
+#  include <sys/vlimit.h>	/* Obsolete, says glibc */
+# endif
+#endif
+
+/* Start of data.  It is OK if this is approximate; it's used only as
+   a heuristic.  */
+#ifdef DATA_START
+# define data_start ((char *) DATA_START)
+#else
+extern char data_start[];
+# ifndef HAVE_DATA_START
+/* Initialize to nonzero, so that it's put into data and not bss.
+   Link this file's object code first, so that this symbol is near the
+   start of data.  */
+char data_start[1] = { 1 };
+# endif
+#endif
 
 /*
   Level number of warnings already issued.
@@ -35,12 +65,20 @@
    0 means don't issue them.  */
 static void (*warn_function) (const char *);
 
-/* Start of data space; can be changed by calling malloc_init.  */
-static void *data_space_start;
+/* Start of data space; can be changed by calling memory_warnings.  */
+static char *data_space_start;
 
 /* Number of bytes of writable memory we can expect to be able to get.  */
 static size_t lim_data;
 
+/* Return true if PTR cannot be represented as an Emacs Lisp object.  */
+static bool
+exceeds_lisp_ptr (void *ptr)
+{
+  return (! USE_LSB_TAG
+	  && VAL_MAX < UINTPTR_MAX
+	  && ((uintptr_t) ptr & ~DATA_SEG_BITS) >> VALBITS != 0);
+}
 
 #ifdef HAVE_GETRLIMIT
 
@@ -122,10 +160,12 @@
 {
 #ifdef REL_ALLOC
   extern void *(*real_morecore) (ptrdiff_t);
+#else
+  void *(*real_morecore) (ptrdiff_t) = 0;
 #endif
   extern void *(*__morecore) (ptrdiff_t);
 
-  void *cp;
+  char *cp;
   size_t five_percent;
   size_t data_size;
   enum warnlevel new_warnlevel;
@@ -135,13 +175,8 @@
   five_percent = lim_data / 20;
 
   /* Find current end of memory and issue warning if getting near max */
-#ifdef REL_ALLOC
-  if (real_morecore)
-    cp = (char *) (*real_morecore) (0);
-  else
-#endif
-  cp = (char *) (*__morecore) (0);
-  data_size = (char *) cp - (char *) data_space_start;
+  cp = (real_morecore ? real_morecore : __morecore) (0);
+  data_size = cp - data_space_start;
 
   if (!warn_function)
     return;
@@ -188,49 +223,10 @@
 	warnlevel = warned_85;
     }
 
-  if (EXCEEDS_LISP_PTR (cp))
+  if (exceeds_lisp_ptr (cp))
     (*warn_function) ("Warning: memory in use exceeds lisp pointer size");
 }
 
-#if !defined (CANNOT_DUMP) || !defined (SYSTEM_MALLOC)
-/* Some systems that cannot dump also cannot implement these.  */
-
-/*
- *	Return the address of the start of the data segment prior to
- *	doing an unexec.  After unexec the return value is undefined.
- *	See crt0.c for further information and definition of data_start.
- *
- *	Apparently, on BSD systems this is etext at startup.  On
- *	USG systems (swapping) this is highly mmu dependent and
- *	is also dependent on whether or not the program is running
- *	with shared text.  Generally there is a (possibly large)
- *	gap between end of text and start of data with shared text.
- *
- */
-
-char *
-start_of_data (void)
-{
-#ifdef BSD_SYSTEM
-  extern char etext;
-  return (void *) &etext;
-#elif defined DATA_START
-  return (void *) DATA_START;
-#elif defined ORDINARY_LINK
-  /*
-   * This is a hack.  Since we're not linking crt0.c or pre_crt0.c,
-   * data_start isn't defined.  We take the address of environ, which
-   * is known to live at or near the start of the system crt0.c, and
-   * we don't sweat the handful of bytes that might lose.
-   */
-  return (void *) &environ;
-#else
-  extern int data_start;
-  return (void *) &data_start;
-#endif
-}
-#endif /* (not CANNOT_DUMP or not SYSTEM_MALLOC) */
-
 /* Enable memory usage warnings.
    START says where the end of pure storage is.
    WARNFUN specifies the function to call to issue a warning.  */
@@ -240,10 +236,7 @@
 {
   extern void (* __after_morecore_hook) (void);     /* From gmalloc.c */
 
-  if (start)
-    data_space_start = start;
-  else
-    data_space_start = start_of_data ();
+  data_space_start = start ? start : data_start;
 
   warn_function = warnfun;
   __after_morecore_hook = check_memory_limits;