summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--elf/dl-load.c131
-rw-r--r--sysdeps/unix/sysv/linux/init-first.c6
-rw-r--r--time/strftime.c56
4 files changed, 113 insertions, 94 deletions
diff --git a/ChangeLog b/ChangeLog
index 382a99ea3b..df7ac2ad09 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 1998-09-11  Ulrich Drepper  <drepper@cygnus.com>
 
+	* time/strftime.c (my_strftime): Delay use of *tp values until
+	latest possible point to allow partly initialized structures
+	(e.g., from strptime).
+
+	* sysdeps/unix/sysv/linux/init-first.c [!PIC]: Define __libc_init_first
+	using init-first.h.
+
+1998-04-30 18:20  H.J. Lu  <hjl@gnu.org>
+
+	* elf/dl-load.c (_dl_init_paths): Don't check the dynamic
+	loader if PIC is not defined.
+
+1998-09-11  Ulrich Drepper  <drepper@cygnus.com>
+
 	* iconvdata/Makefile (modules): Add CSN_369103, CWI, DEC-MCS,
 	ECMA-CYRILLIC, GOST_19768-74, GREEK-CCITT, GREEK7, GREEK7-OLD, INIS,
 	INIS-8, INIS-CYRILLIC, ISO_6937-2, ISO_2033, ISO_5427, ISO_5427-EXT,
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 1082205a23..ba01300bfa 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -458,11 +458,13 @@ _dl_init_paths (const char *llp)
   struct r_search_path_elem *pelem, **aelem;
   size_t round_size;
 
+#ifdef PIC
   /* We have in `search_path' the information about the RPATH of the
      dynamic loader.  Now fill in the information about the applications
      RPATH and the directories addressed by the LD_LIBRARY_PATH environment
      variable.  */
   struct link_map *l;
+#endif
 
   /* Number of elements in the library path.  */
   size_t nllp;
@@ -526,84 +528,83 @@ _dl_init_paths (const char *llp)
     }
   *aelem = NULL;
 
+#ifdef PIC
+  /* This points to the map of the main object.  */
   l = _dl_loaded;
-  if (l != NULL)
-    {
-      /* We should never get here when initializing in a static application.
-	 If this is a dynamically linked application _dl_loaded always
-	 points to the main map which is not dlopen()ed.  */
-      assert (l->l_type != lt_loaded);
-
-      if (l->l_info[DT_RPATH])
-	{
-	  /* Allocate room for the search path and fill in information
-	     from RPATH.  */
-	  l->l_rpath_dirs =
-	    decompose_rpath ((const char *)
-			     (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr
-			      + l->l_info[DT_RPATH]->d_un.d_val),
-			     nllp, l);
-	}
-      else
-	{
-	  /* If we have no LD_LIBRARY_PATH and no RPATH we must tell
-	     this somehow to prevent we look this up again and again.  */
-	  if (nllp == 0)
-	    l->l_rpath_dirs = (struct r_search_path_elem **) -1l;
-	  else
-	    {
-	      l->l_rpath_dirs = (struct r_search_path_elem **)
-		malloc ((nllp + 1) * sizeof (*l->l_rpath_dirs));
-	      if (l->l_rpath_dirs == NULL)
-		_dl_signal_error (ENOMEM, NULL,
-				  "cannot create cache for search path");
-	      l->l_rpath_dirs[0] = NULL;
-	    }
-	}
 
-      /* We don't need to search the list of fake entries which is searched
-	 when no dynamic objects were loaded at this time.  */
-      fake_path_list = NULL;
+  /* We should never get here when initializing in a static application.
+     If this is a dynamically linked application _dl_loaded always
+     points to the main map which is not dlopen()ed.  */
+  assert (l->l_type != lt_loaded);
 
-      if (nllp > 0)
-	{
-	  char *copy = local_strdup (llp);
-
-	  /* Decompose the LD_LIBRARY_PATH and fill in the result.
-	     First search for the next place to enter elements.  */
-	  struct r_search_path_elem **result = l->l_rpath_dirs;
-	  while (*result != NULL)
-	    ++result;
-
-	  /* We need to take care that the LD_LIBRARY_PATH environment
-	     variable can contain a semicolon.  */
-	  (void) fillin_rpath (copy, result, ":;",
-			       __libc_enable_secure ? system_dirs : NULL,
-			       "LD_LIBRARY_PATH", NULL);
-	}
+  if (l->l_info[DT_RPATH])
+    {
+      /* Allocate room for the search path and fill in information
+	 from RPATH.  */
+      l->l_rpath_dirs =
+	decompose_rpath ((const char *)
+			 (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr
+			  + l->l_info[DT_RPATH]->d_un.d_val),
+			 nllp, l);
     }
   else
     {
-      /* This is a statically linked program but we still have to
-	 take care for the LD_LIBRARY_PATH environment variable.  We
-	 use a fake link_map entry.  This will only contain the
-	 l_rpath_dirs information.  */
-
+      /* If we have no LD_LIBRARY_PATH and no RPATH we must tell
+	 this somehow to prevent we look this up again and again.  */
       if (nllp == 0)
-	fake_path_list = NULL;
+	l->l_rpath_dirs = (struct r_search_path_elem **) -1l;
       else
 	{
-	  fake_path_list = (struct r_search_path_elem **)
-	    malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
-	  if (fake_path_list == NULL)
+	  l->l_rpath_dirs = (struct r_search_path_elem **)
+	    malloc ((nllp + 1) * sizeof (*l->l_rpath_dirs));
+	  if (l->l_rpath_dirs == NULL)
 	    _dl_signal_error (ENOMEM, NULL,
 			      "cannot create cache for search path");
-
-	  (void) fillin_rpath (local_strdup (llp), fake_path_list, ":;",
-			       __libc_enable_secure ? system_dirs : NULL,
-			       "LD_LIBRARY_PATH", NULL);
+	  l->l_rpath_dirs[0] = NULL;
 	}
     }
+
+  /* We don't need to search the list of fake entries which is searched
+     when no dynamic objects were loaded at this time.  */
+  fake_path_list = NULL;
+
+  if (nllp > 0)
+    {
+      char *copy = local_strdup (llp);
+
+      /* Decompose the LD_LIBRARY_PATH and fill in the result.
+	 First search for the next place to enter elements.  */
+      struct r_search_path_elem **result = l->l_rpath_dirs;
+      while (*result != NULL)
+	++result;
+
+      /* We need to take care that the LD_LIBRARY_PATH environment
+	 variable can contain a semicolon.  */
+      (void) fillin_rpath (copy, result, ":;",
+			   __libc_enable_secure ? system_dirs : NULL,
+			   "LD_LIBRARY_PATH", NULL);
+    }
+#else	/* !PIC */
+  /* This is a statically linked program but we still have to take
+     care for the LD_LIBRARY_PATH environment variable.  We use a fake
+     link_map entry.  This will only contain the l_rpath_dirs
+     information.  */
+
+  if (nllp == 0)
+    fake_path_list = NULL;
+  else
+    {
+      fake_path_list = (struct r_search_path_elem **)
+	malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
+      if (fake_path_list == NULL)
+	_dl_signal_error (ENOMEM, NULL,
+			  "cannot create cache for search path");
+
+      (void) fillin_rpath (local_strdup (llp), fake_path_list, ":;",
+			   __libc_enable_secure ? system_dirs : NULL,
+			   "LD_LIBRARY_PATH", NULL);
+    }
+#endif	/* PIC */
 }
 
 
diff --git a/sysdeps/unix/sysv/linux/init-first.c b/sysdeps/unix/sysv/linux/init-first.c
index 0931e99113..6c293e3926 100644
--- a/sysdeps/unix/sysv/linux/init-first.c
+++ b/sysdeps/unix/sysv/linux/init-first.c
@@ -93,11 +93,7 @@ __libc_init_first (void)
 }
 
 #else
-void
-__libc_init_first (int argc, char **argv, char **envp)
-{
-  init (argc, argv, envp);
-}
+SYSDEP_CALL_INIT(__libc_init_first, init);
 #endif
 
 
diff --git a/time/strftime.c b/time/strftime.c
index f724bf3e3b..594cbbfe16 100644
--- a/time/strftime.c
+++ b/time/strftime.c
@@ -416,15 +416,25 @@ my_strftime (s, maxsize, format, tp)
 {
   int hour12 = tp->tm_hour;
 #ifdef _NL_CURRENT
-  const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);
-  const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);
-  const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);
-  const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);
-  const char *const ampm = _NL_CURRENT (LC_TIME,
-					hour12 > 11 ? PM_STR : AM_STR);
-  size_t aw_len = strlen (a_wkday);
-  size_t am_len = strlen (a_month);
-  size_t ap_len = strlen (ampm);
+  /* We cannot make the following values variables since we must dealy
+     the evaluation of these values until really needed since some
+     expressions might not be valid in every situation.  The `struct tm'
+     might be generated by a strptime() call and therefore initialized
+     only a few elements.  Dereference the pointers only if the format
+     requires this.  Then it is ok to fail if the pointers are invalid.  */
+# define a_wkday _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday)
+# define f_wkday _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday)
+# define f_wkday _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday)
+# define a_month _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon)
+# define f_month _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon)
+# define ampm _NL_CURRENT (LC_TIME, hour12 > 11 ? PM_STR : AM_STR)
+
+# define aw_len strlen (a_wkday)
+# define am_len strlen (a_month)
+# define ap_len strlen (ampm)
+
+# define wkday_len strlen (f_wkday)
+# define month_len strlen (f_month)
 #else
 # if !HAVE_STRFTIME
   const char *const f_wkday = weekday_name[tp->tm_wday];
@@ -435,14 +445,12 @@ my_strftime (s, maxsize, format, tp)
   size_t aw_len = 3;
   size_t am_len = 3;
   size_t ap_len = 2;
-# endif
-#endif
-#if defined _NL_CURRENT || !HAVE_STRFTIME
+
   size_t wkday_len = strlen (f_wkday);
   size_t month_len = strlen (f_month);
+# endif
 #endif
   const char *zone;
-  size_t zonelen;
   size_t i = 0;
   char *p = s;
   const char *f;
@@ -457,21 +465,12 @@ my_strftime (s, maxsize, format, tp)
      POSIX does not require it.  Do the right thing instead.  */
   zone = (const char *) tp->tm_zone;
 #endif
-#if HAVE_TZNAME
+#if HAVE_TZNAME && HAVE_TZSET
   /* POSIX.1 8.1.1 requires that whenever strftime() is called, the
      time zone names contained in the external variable `tzname' shall
      be set as if the tzset() function had been called.  */
-# if HAVE_TZSET
   tzset ();
-# endif
-
-  if (!(zone && *zone) && tp->tm_isdst >= 0)
-    zone = tzname[tp->tm_isdst];
 #endif
-  if (! zone)
-    zone = "";		/* POSIX.2 requires the empty string here.  */
-
-  zonelen = strlen (zone);
 
   if (hour12 > 12)
     hour12 -= 12;
@@ -1146,7 +1145,16 @@ my_strftime (s, maxsize, format, tp)
 	      to_uppcase = 0;
 	      to_lowcase = 1;
 	    }
-	  cpy (zonelen, zone);
+
+#if HAVE_TZNAME
+	  /* The tzset() call might have changed the value.  */
+	  if (!(zone && *zone) && tp->tm_isdst >= 0)
+	    zone = tzname[tp->tm_isdst];
+#endif
+	  if (! zone)
+	    zone = "";		/* POSIX.2 requires the empty string here.  */
+
+	  cpy (strlen (zone), zone);
 	  break;
 
 	case 'z':		/* GNU extension.  */