summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--NEWS4
-rw-r--r--libio/fileops.c120
-rw-r--r--libio/iofclose.c12
-rw-r--r--libio/iofwide.c23
-rw-r--r--malloc/mtrace.pl13
-rw-r--r--wcsmbs/wcsmbsload.c88
-rw-r--r--wcsmbs/wcsmbsload.h4
8 files changed, 202 insertions, 80 deletions
diff --git a/ChangeLog b/ChangeLog
index 2b31c404e8..e7c8890dba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
2001-07-27 Ulrich Drepper <drepper@redhat.com>
+ * libio/fileops.c (_IO_new_file_fopen): Correctly locate ccs=
+ substring. Don't handle ccs= if no descriptor was allocated.
+ Normalize codeset name before calling __wcsmbs_named_conv.
+ Initialize transliteration elements. Free step data structure.
+ * libio/iofclose.c (_IO_new_fclose): Correct freeing of the step data.
+ * libio/iofwide.c (__libio_translit): Renamed from libio_translit
+ and made public. Various little cleanup changes.
+ * wcsmbs/wcsmbsload.h (struct gconv_fcts): Add towc_nsteps and
+ tomb_nsteps member.
+ * wcsmbs/wcsmbsload.c: Add some casts to avoid warnings.
+ (__wcsmbs_gconv_fcts): Initialize towc_nsteps and tomb_nsteps member.
+ (getfct): Take additional parameter with pointer to variable where the
+ number of steps is stored in. Disable code which allows to use more
+ than one step for now. Adjust all callers.
+ (free_mem): New function. Frees data associated with currently
+ selected converters.
+
* malloc/mtrace.pl: Extract addresses from DSOs.
2001-07-26 Ulrich Drepper <drepper@redhat.com>
@@ -29,7 +46,6 @@
* sysdeps/generic/tcsetattr.c (bad_speed): Accept those values.
* termios/cfsetspeed.c (speeds): Likewise.
->>>>>>> 1.5525
2001-07-26 kaz Kojima <kkojima@rr.iij4u.or.jp>
* sysdeps/sh/dl-machine.h (elf_machine_load_address): Don't use
diff --git a/NEWS b/NEWS
index c9039616a2..5144dc0610 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes. 2001-7-25
+GNU C Library NEWS -- history of user-visible changes. 2001-7-27
Copyright (C) 1992-2000, 2001 Free Software Foundation, Inc.
See the end for copying conditions.
@@ -28,6 +28,8 @@ Version 2.2.4
* The Hurd port got a lot more functionality like AIO, various stdio
extensions, etc. Mainly done by Roland McGrath.
+
+* mtrace can now lookup symbols in shared libraries.
Version 2.2.3
diff --git a/libio/fileops.c b/libio/fileops.c
index 03f71d71c0..3947fa8d6c 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -31,6 +31,7 @@
# define _POSIX_SOURCE
#endif
#include "libioP.h"
+#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -42,6 +43,8 @@
#endif
#if _LIBC
# include "../wcsmbs/wcsmbsload.h"
+# include "../iconv/gconv_charset.h"
+# include "../iconv/gconv_int.h"
# include <shlib-compat.h>
#endif
#ifndef errno
@@ -74,6 +77,12 @@ extern int errno;
# define _IO_new_file_xsputn _IO_file_xsputn
#endif
+
+#ifdef _LIBC
+extern struct __gconv_trans_data __libio_translit;
+#endif
+
+
/* An fstream can be in at most one of put mode, get mode, or putback mode.
Putback mode is a variant of get mode.
@@ -238,8 +247,9 @@ _IO_new_file_fopen (fp, filename, mode, is32not64)
int oprot = 0666;
int i;
_IO_FILE *result;
-#if _LIBC
+#ifdef _LIBC
const char *cs;
+ const char *last_recognized;
#endif
if (_IO_file_is_open (fp))
@@ -264,6 +274,9 @@ _IO_new_file_fopen (fp, filename, mode, is32not64)
__set_errno (EINVAL);
return NULL;
}
+#ifdef _LIBC
+ last_recognized = mode;
+#endif
for (i = 1; i < 4; ++i)
{
switch (*++mode)
@@ -273,11 +286,20 @@ _IO_new_file_fopen (fp, filename, mode, is32not64)
case '+':
omode = O_RDWR;
read_write &= _IO_IS_APPENDING;
+#ifdef _LIBC
+ last_recognized = mode;
+#endif
continue;
case 'x':
oflags |= O_EXCL;
+#ifdef _LIBC
+ last_recognized = mode;
+#endif
continue;
case 'b':
+#ifdef _LIBC
+ last_recognized = mode;
+#endif
default:
/* Ignore. */
continue;
@@ -289,48 +311,78 @@ _IO_new_file_fopen (fp, filename, mode, is32not64)
is32not64);
-#if _LIBC
- /* Test whether the mode string specifies the conversion. */
- cs = strstr (mode, ",ccs=");
- if (cs != NULL)
+#ifdef _LIBC
+ if (result != NULL)
{
- /* Yep. Load the appropriate conversions and set the orientation
- to wide. */
- struct gconv_fcts fcts;
- struct _IO_codecvt *cc;
+ /* Test whether the mode string specifies the conversion. */
+ cs = strstr (last_recognized + 1, ",ccs=");
+ if (cs != NULL)
+ {
+ /* Yep. Load the appropriate conversions and set the orientation
+ to wide. */
+ struct gconv_fcts fcts;
+ struct _IO_codecvt *cc;
+ char *endp = __strchrnul (cs + 5, ',');
+ char ccs[endp - (cs + 5) + 3];
+
+ *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
+ strip (ccs, ccs);
+
+ if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
+ ? upstr (ccs, cs + 5) : ccs) != 0)
+ {
+ /* Something went wrong, we cannot load the conversion modules.
+ This means we cannot proceed since the user explicitly asked
+ for these. */
+ __set_errno (EINVAL);
+ return NULL;
+ }
- if (! _IO_CHECK_WIDE (fp) || __wcsmbs_named_conv (&fcts, cs + 5) != 0)
- {
- /* Something went wrong, we cannot load the conversion modules.
- This means we cannot proceed since the user explicitly asked
- for these. */
- _IO_new_fclose (result);
- return NULL;
- }
+ assert (fcts.towc_nsteps == 1);
+ assert (fcts.tomb_nsteps == 1);
+
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
+ fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
+
+ /* Clear the state. We start all over again. */
+ memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
+ memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
+
+ cc = fp->_codecvt = &fp->_wide_data->_codecvt;
- cc = fp->_codecvt = &fp->_wide_data->_codecvt;
+ /* The functions are always the same. */
+ *cc = __libio_codecvt;
- /* The functions are always the same. */
- *cc = __libio_codecvt;
+ cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
+ cc->__cd_in.__cd.__steps = fcts.towc;
- cc->__cd_in.__cd.__nsteps = 1; /* Only one step allowed. */
- cc->__cd_in.__cd.__steps = fcts.towc;
+ cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
+ cc->__cd_in.__cd.__data[0].__internal_use = 1;
+ cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
+ cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
- cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
- cc->__cd_in.__cd.__data[0].__internal_use = 1;
- cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
- cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
+ /* XXX For now no transliteration. */
+ cc->__cd_in.__cd.__data[0].__trans = NULL;
- cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */
- cc->__cd_out.__cd.__steps = fcts.tomb;
+ cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
+ cc->__cd_out.__cd.__steps = fcts.tomb;
- cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
- cc->__cd_out.__cd.__data[0].__internal_use = 1;
- cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
- cc->__cd_out.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
+ cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
+ cc->__cd_out.__cd.__data[0].__internal_use = 1;
+ cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
+ cc->__cd_out.__cd.__data[0].__statep =
+ &result->_wide_data->_IO_state;
- /* Set the mode now. */
- result->_mode = 1;
+ /* And now the transliteration. */
+ cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
+
+ /* Set the mode now. */
+ result->_mode = 1;
+
+ /* We don't need the step data structure anymore. */
+ __gconv_release_cache (fcts.towc, fcts.towc_nsteps);
+ __gconv_release_cache (fcts.tomb, fcts.tomb_nsteps);
+ }
}
#endif /* GNU libc */
diff --git a/libio/iofclose.c b/libio/iofclose.c
index 660c118359..45bd0afa7d 100644
--- a/libio/iofclose.c
+++ b/libio/iofclose.c
@@ -72,16 +72,8 @@ _IO_new_fclose (fp)
the conversion functions. */
struct _IO_codecvt *cc = fp->_codecvt;
- if (cc->__cd_in.__cd.__steps->__shlib_handle != NULL)
- {
- --cc->__cd_in.__cd.__steps->__counter;
- __gconv_close_transform (cc->__cd_in.__cd.__steps, 1);
- }
- if (cc->__cd_out.__cd.__steps->__shlib_handle != NULL)
- {
- --cc->__cd_out.__cd.__steps->__counter;
- __gconv_close_transform (cc->__cd_out.__cd.__steps, 1);
- }
+ __gconv_release_step (cc->__cd_in.__cd.__steps);
+ __gconv_release_step (cc->__cd_out.__cd.__steps);
#endif
}
_IO_cleanup_region_end (0);
diff --git a/libio/iofwide.c b/libio/iofwide.c
index d191baaf99..aa314fe671 100644
--- a/libio/iofwide.c
+++ b/libio/iofwide.c
@@ -30,6 +30,7 @@
# include <dlfcn.h>
# include <wchar.h>
#endif
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
@@ -81,7 +82,7 @@ struct _IO_codecvt __libio_codecvt =
#ifdef _LIBC
-static struct __gconv_trans_data libio_translit =
+struct __gconv_trans_data __libio_translit =
{
.__trans_fct = __gconv_transliterate
};
@@ -134,11 +135,13 @@ _IO_fwide (fp, mode)
memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
__wcsmbs_clone_conv (&fcts);
+ assert (fcts.towc_nsteps == 1);
+ assert (fcts.tomb_nsteps == 1);
/* The functions are always the same. */
*cc = __libio_codecvt;
- cc->__cd_in.__cd.__nsteps = 1; /* Only one step allowed. */
+ cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
cc->__cd_in.__cd.__steps = fcts.towc;
cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
@@ -149,7 +152,7 @@ _IO_fwide (fp, mode)
/* XXX For now no transliteration. */
cc->__cd_in.__cd.__data[0].__trans = NULL;
- cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */
+ cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
cc->__cd_out.__cd.__steps = fcts.tomb;
cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
@@ -158,11 +161,7 @@ _IO_fwide (fp, mode)
cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
/* And now the transliteration. */
-#ifdef _LIBC
- cc->__cd_out.__cd.__data[0].__trans = &libio_translit;
-#else
- cc->__cd_out.__cd.__data[0].__trans = NULL;
-#endif
+ cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
}
#else
# ifdef _GLIBCPP_USE_WCHAR_T
@@ -188,8 +187,12 @@ _IO_fwide (fp, mode)
cc->__cd_out = iconv_open (external_ccs, internal_ccs);
if (cc->__cd_in == (iconv_t) -1 || cc->__cd_out == (iconv_t) -1)
- /* XXX */
- abort ();
+ {
+ if (cc->__cd_in != (iconv_t) -1)
+ iconv_close (cc->__cd_in);
+ /* XXX */
+ abort ();
+ }
}
# else
# error "somehow determine this from LC_CTYPE"
diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl
index e3ed5771dd..7e06c99f29 100644
--- a/malloc/mtrace.pl
+++ b/malloc/mtrace.pl
@@ -125,6 +125,19 @@ sub location {
}
}
$cache{$addr} = $str = $addr;
+ } elsif ($str =~ /^.*[[](0x[^]]*)]$/) {
+ my $addr = $1;
+ return $cache{$addr} if (exists $cache{$addr});
+ if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
+ my $line = <ADDR>;
+ chomp $line;
+ close (ADDR);
+ if ($line ne '??:0') {
+ $cache{$addr} = $line;
+ return $cache{$addr};
+ }
+ }
+ $cache{$addr} = $str = $addr;
}
return $str;
}
diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c
index f5d9426c32..c096804a68 100644
--- a/wcsmbs/wcsmbsload.c
+++ b/wcsmbs/wcsmbsload.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -41,8 +41,8 @@ static struct __gconv_step to_wc =
.__shlib_handle = NULL,
.__modname = NULL,
.__counter = INT_MAX,
- .__from_name = "ANSI_X3.4-1968//TRANSLIT",
- .__to_name = "INTERNAL",
+ .__from_name = (char *) "ANSI_X3.4-1968//TRANSLIT",
+ .__to_name = (char *) "INTERNAL",
.__fct = __gconv_transform_ascii_internal,
.__init_fct = NULL,
.__end_fct = NULL,
@@ -59,8 +59,8 @@ static struct __gconv_step to_mb =
.__shlib_handle = NULL,
.__modname = NULL,
.__counter = INT_MAX,
- .__from_name = "INTERNAL",
- .__to_name = "ANSI_X3.4-1968//TRANSLIT",
+ .__from_name = (char *) "INTERNAL",
+ .__to_name = (char *) "ANSI_X3.4-1968//TRANSLIT",
.__fct = __gconv_transform_internal_ascii,
.__init_fct = NULL,
.__end_fct = NULL,
@@ -77,22 +77,33 @@ static struct __gconv_step to_mb =
struct gconv_fcts __wcsmbs_gconv_fcts =
{
.towc = &to_wc,
- .tomb = &to_mb
+ .towc_nsteps = 1,
+ .tomb = &to_mb,
+ .tomb_nsteps = 1
};
static inline struct __gconv_step *
-getfct (const char *to, const char *from)
+getfct (const char *to, const char *from, size_t *nstepsp)
{
size_t nsteps;
struct __gconv_step *result;
+#if 0
size_t nstateful;
size_t cnt;
+#endif
if (__gconv_find_transform (to, from, &result, &nsteps, 0) != __GCONV_OK)
/* Loading the conversion step is not possible. */
return NULL;
+ /* Maybe it is someday necessary to allow more than one step.
+ Currently this is not the case since the conversions handled here
+ are from and to INTERNAL and there always is a converted for
+ that. It the directly following code is enabled the libio
+ functions will have to allocate appropriate __gconv_step_data
+ elements instead of only one. */
+#if 0
/* Count the number of stateful conversions. Since we will only
have one 'mbstate_t' object available we can only deal with one
stateful conversion. */
@@ -101,11 +112,16 @@ getfct (const char *to, const char *from)
if (result[cnt].__stateful)
++nstateful;
if (nstateful > 1)
+#else
+ if (nsteps > 1)
+#endif
{
/* We cannot handle this case. */
__gconv_close_transform (result, nsteps);
result = NULL;
}
+ else
+ *nstepsp = nsteps;
return result;
}
@@ -160,12 +176,18 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
const char *charset_name;
const char *complete_name;
struct __gconv_step *new_towc;
+ size_t new_towc_nsteps;
struct __gconv_step *new_tomb;
+ size_t new_tomb_nsteps;
int use_translit;
/* Free the old conversions. */
- __gconv_close_transform (__wcsmbs_gconv_fcts.tomb, 1);
- __gconv_close_transform (__wcsmbs_gconv_fcts.towc, 1);
+ if (__wcsmbs_gconv_fcts.tomb != &to_mb)
+ __gconv_close_transform (__wcsmbs_gconv_fcts.tomb,
+ __wcsmbs_gconv_fcts.tomb_nsteps);
+ if (__wcsmbs_gconv_fcts.towc != &to_wc)
+ __gconv_close_transform (__wcsmbs_gconv_fcts.towc,
+ __wcsmbs_gconv_fcts.towc_nsteps);
/* Get name of charset of the locale. */
charset_name = new_category->values[_NL_ITEM_INDEX(CODESET)].string;
@@ -181,9 +203,10 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
/* It is not necessary to use transliteration in this direction
since the internal character set is supposed to be able to
represent all others. */
- new_towc = getfct ("INTERNAL", complete_name);
+ new_towc = getfct ("INTERNAL", complete_name, &new_towc_nsteps);
new_tomb = (new_towc != NULL
- ? getfct (complete_name, "INTERNAL") : NULL);
+ ? getfct (complete_name, "INTERNAL", &new_tomb_nsteps)
+ : NULL);
/* If any of the conversion functions is not available we don't
use any since this would mean we cannot convert back and
@@ -197,7 +220,9 @@ __wcsmbs_load_conv (const struct locale_data *new_category)
}
__wcsmbs_gconv_fcts.tomb = new_tomb;
+ __wcsmbs_gconv_fcts.tomb_nsteps = new_tomb_nsteps;
__wcsmbs_gconv_fcts.towc = new_towc;
+ __wcsmbs_gconv_fcts.towc_nsteps = new_towc_nsteps;
}
/* Set last-used variable for current locale. */
@@ -232,27 +257,44 @@ __wcsmbs_clone_conv (struct gconv_fcts *copy)
}
-/* Clone the current conversion function set. */
+/* Get converters for named charset. */
int
internal_function
__wcsmbs_named_conv (struct gconv_fcts *copy, const char *name)
{
- copy->towc = getfct ("INTERNAL", name);
+ copy->towc = getfct ("INTERNAL", name, &copy->towc_nsteps);
if (copy->towc != NULL)
{
- copy->tomb = getfct (name, "INTERNAL");
+ copy->tomb = getfct (name, "INTERNAL", &copy->tomb_nsteps);
if (copy->tomb == NULL)
- __gconv_close_transform (copy->towc, 1);
+ __gconv_close_transform (copy->towc, copy->towc_nsteps);
}
- if (copy->towc == NULL || copy->tomb == NULL)
- return 1;
+ return copy->towc == NULL || copy->tomb == NULL ? 1 : 0;
+}
- /* Now increment the usage counters. */
- if (copy->towc->__shlib_handle != NULL)
- ++copy->towc->__counter;
- if (copy->tomb->__shlib_handle != NULL)
- ++copy->tomb->__counter;
- return 0;
+/* Free all resources if necessary. */
+static void __attribute__ ((unused))
+free_mem (void)
+{
+ if (__wcsmbs_gconv_fcts.tomb != &to_mb)
+ {
+ struct __gconv_step *old = __wcsmbs_gconv_fcts.tomb;
+ size_t nold = __wcsmbs_gconv_fcts.tomb_nsteps;
+ __wcsmbs_gconv_fcts.tomb = &to_mb;
+ __wcsmbs_gconv_fcts.tomb_nsteps = 1;
+ __gconv_release_cache (old, nold);
+ }
+
+ if (__wcsmbs_gconv_fcts.towc != &to_wc)
+ {
+ struct __gconv_step *old = __wcsmbs_gconv_fcts.towc;
+ size_t nold = __wcsmbs_gconv_fcts.towc_nsteps;
+ __wcsmbs_gconv_fcts.towc = &to_wc;
+ __wcsmbs_gconv_fcts.towc_nsteps = 1;
+ __gconv_release_cache (old, nold);
+ }
}
+
+text_set_element (__libc_subfreeres, free_mem);
diff --git a/wcsmbs/wcsmbsload.h b/wcsmbs/wcsmbsload.h
index c1bcfe0ea0..6aa6139f77 100644
--- a/wcsmbs/wcsmbsload.h
+++ b/wcsmbs/wcsmbsload.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -26,7 +26,9 @@
struct gconv_fcts
{
struct __gconv_step *towc;
+ size_t towc_nsteps;
struct __gconv_step *tomb;
+ size_t tomb_nsteps;
};
/* Set of currently active conversion functions. */