diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | libio/fileops.c | 120 | ||||
-rw-r--r-- | libio/iofclose.c | 12 | ||||
-rw-r--r-- | libio/iofwide.c | 23 | ||||
-rw-r--r-- | malloc/mtrace.pl | 13 | ||||
-rw-r--r-- | wcsmbs/wcsmbsload.c | 88 | ||||
-rw-r--r-- | wcsmbs/wcsmbsload.h | 4 |
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, ©->towc_nsteps); if (copy->towc != NULL) { - copy->tomb = getfct (name, "INTERNAL"); + copy->tomb = getfct (name, "INTERNAL", ©->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. */ |