From ba3265d04cc794d2af8b7d590a0658f7d732071c Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 2 Mar 2020 10:02:02 +0000 Subject: [PATCH] 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/ChangeLog | 9 +++ binutils/readelf.c | 80 +++++++++++++++++++-- binutils/testsuite/binutils-all/pr25543.d | 12 ++++ binutils/testsuite/binutils-all/pr25543.s | 7 ++ binutils/testsuite/binutils-all/readelf.exp | 1 + 5 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 binutils/testsuite/binutils-all/pr25543.d create mode 100644 binutils/testsuite/binutils-all/pr25543.s diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 24d17c25fb5..479061d0f04 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,12 @@ +2020-03-02 Nick Clifton + + 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. + 2020-02-27 Nick Clifton PR 25526 diff --git a/binutils/readelf.c b/binutils/readelf.c index bf84f877fc2..d4756c93b34 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 { diff --git a/binutils/testsuite/binutils-all/pr25543.d b/binutils/testsuite/binutils-all/pr25543.d new file mode 100644 index 00000000000..75f23922db9 --- /dev/null +++ b/binutils/testsuite/binutils-all/pr25543.d @@ -0,0 +1,12 @@ +#source: pr25543.s +#readelf: -p.data +#notarget: rx-* + +String dump of section '.data': + \[ 0\] line1 : This is a line without a newline at the end + \[ 34\] line2 : This is a line with a newline at the end\\n + \[ 66\] line3 : This is a line with a \\n + newline in the middle + \[ 9b\] line4 : This is a line with a \^Mcontrol character + \[ cd\] line6 : The previous line was empty\\n +#pass diff --git a/binutils/testsuite/binutils-all/pr25543.s b/binutils/testsuite/binutils-all/pr25543.s new file mode 100644 index 00000000000..71bfe05a0c8 --- /dev/null +++ b/binutils/testsuite/binutils-all/pr25543.s @@ -0,0 +1,7 @@ + .data + .asciz "line1 : This is a line without a newline at the end" + .asciz "line2 : This is a line with a newline at the end\n" + .asciz "line3 : This is a line with a \nnewline in the middle" + .asciz "line4 : This is a line with a \rcontrol character" + .asciz "" + .asciz "line6 : The previous line was empty\n" diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp index 2f9afed7d12..cc78e66ea3c 100644 --- a/binutils/testsuite/binutils-all/readelf.exp +++ b/binutils/testsuite/binutils-all/readelf.exp @@ -349,6 +349,7 @@ readelf_wi_test readelf_compressed_wa_test readelf_dump_test +run_dump_test "pr25543" # PR 13482 - Check for off-by-one errors when dumping .note sections. if {![binutils_assemble $srcdir/$subdir/version.s tmpdir/version.o]} then { -- 2.39.2