aboutsummaryrefslogtreecommitdiff
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 382a99e..df7ac2a 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 1082205..ba01300 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 0931e99..6c293e3 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 f724bf3..594cbbf 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. */