From ba3265d04cc794d2af8b7d590a0658f7d732071c Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 2 Mar 2020 10:02:02 +0000 Subject: Restore readelf's string dump to previous behaviour where newlines were caused line breaks. PR 25543 * readelf.c (dump_section_as_strings): Display new-line characters as \n and then insert a line break. * testsuite/binutils-all/pr25543.s: New test. * testsuite/binutils-all/pr25543.d: Test driver. * testsuite/binutils-all/readelf.exp: Run the new test. --- binutils/readelf.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 7 deletions(-) (limited to 'binutils/readelf.c') diff --git a/binutils/readelf.c b/binutils/readelf.c index bf84f87..d4756c9 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -13732,6 +13732,14 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) end = start + num_bytes; some_strings_shown = FALSE; +#ifdef HAVE_MBSTATE_T + mbstate_t state; + /* Initialise the multibyte conversion state. */ + memset (& state, 0, sizeof (state)); +#endif + + bfd_boolean continuing = FALSE; + while (data < end) { while (!ISPRINT (* data)) @@ -13742,18 +13750,76 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) { size_t maxlen = end - data; + if (continuing) + { + printf (" "); + continuing = FALSE; + } + else + { #ifndef __MSVCRT__ - /* PR 11128: Use two separate invocations in order to work - around bugs in the Solaris 8 implementation of printf. */ - printf (" [%6tx] ", data - start); + /* PR 11128: Use two separate invocations in order to work + around bugs in the Solaris 8 implementation of printf. */ + printf (" [%6tx] ", data - start); #else - printf (" [%6Ix] ", (size_t) (data - start)); + printf (" [%6Ix] ", (size_t) (data - start)); #endif + } + if (maxlen > 0) { - print_symbol ((int) maxlen, (const char *) data); - putchar ('\n'); - data += strnlen ((const char *) data, maxlen); + char c; + + while (maxlen) + { + c = *data++; + + if (c == 0) + break; + + /* PR 25543: Treat new-lines as string-ending characters. */ + if (c == '\n') + { + printf ("\\n\n"); + if (*data != 0) + continuing = TRUE; + break; + } + + /* Do not print control characters directly as they can affect terminal + settings. Such characters usually appear in the names generated + by the assembler for local labels. */ + if (ISCNTRL (c)) + { + printf ("^%c", c + 0x40); + } + else if (ISPRINT (c)) + { + putchar (c); + } + else + { + size_t n; +#ifdef HAVE_MBSTATE_T + wchar_t w; +#endif + /* Let printf do the hard work of displaying multibyte characters. */ + printf ("%.1s", data - 1); +#ifdef HAVE_MBSTATE_T + /* Try to find out how many bytes made up the character that was + just printed. Advance the symbol pointer past the bytes that + were displayed. */ + n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state); +#else + n = 1; +#endif + if (n != (size_t) -1 && n != (size_t) -2 && n > 0) + data += (n - 1); + } + } + + if (c != '\n') + putchar ('\n'); } else { -- cgit v1.1