(realloc): Handle NULL for first parameter correctly.
[platform/upstream/glibc.git] / elf / dl-minimal.c
index 6592ca0..b72faa0 100644 (file)
@@ -1,28 +1,29 @@
 /* Minimal replacements for basic facilities used in the dynamic linker.
-   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+   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 Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   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
-   Library General Public License for more details.
+   Lesser 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.  */
+   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 <elf/ldsodefs.h>
+#include <ldsodefs.h>
 #include <stdio-common/_itoa.h>
 
 #include <assert.h>
 
 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)
 {
@@ -101,6 +111,8 @@ 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);
@@ -113,9 +125,9 @@ realloc (void *ptr, size_t n)
 #include <setjmp.h>
 
 int weak_function
-__sigjmp_save (sigjmp_buf env, int savemask)
+__sigjmp_save (sigjmp_buf env, int savemask __attribute__ ((unused)))
 {
-  env[0].__mask_was_saved = savemask;
+  env[0].__mask_was_saved = 0;
   return 0;
 }
 
@@ -130,7 +142,7 @@ longjmp (jmp_buf env, int val)
    in the whole error list.  */
 
 char * weak_function
-_strerror_internal (int errnum, char *buf, size_t buflen)
+__strerror_r (int errnum, char *buf, size_t buflen)
 {
   char *msg;
 
@@ -177,13 +189,10 @@ void weak_function
 __assert_fail (const char *assertion,
               const char *file, unsigned int line, const char *function)
 {
-  char buf[64];
-  buf[sizeof buf - 1] = '\0';
-  _dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
-                   file, ": ", _itoa_word (line, buf + sizeof buf - 1, 10, 0),
-                   ": ", function ?: "", function ? ": " : "",
-                   "Assertion `", assertion, "' failed!\n",
-                   NULL);
+  _dl_fatal_printf ("\
+Inconsistency detected by ld.so: %s: %u: %s%sAssertion `%s' failed!\n",
+                   file, line, function ?: "", function ? ": " : "",
+                   assertion);
 
 }
 
@@ -192,13 +201,69 @@ __assert_perror_fail (int errnum,
                      const char *file, unsigned int line,
                      const char *function)
 {
-  char buf[64];
-  buf[sizeof buf - 1] = '\0';
-  _dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
-                   file, ": ", _itoa_word (line, buf + sizeof buf - 1, 10, 0),
-                   ": ", function ?: "", function ? ": " : "",
-                   "Unexpected error: ", strerror (errnum), "\n", NULL);
-
+  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;
+}