aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog9
-rw-r--r--binutils/readelf.c80
-rw-r--r--binutils/testsuite/binutils-all/pr25543.d12
-rw-r--r--binutils/testsuite/binutils-all/pr25543.s7
-rw-r--r--binutils/testsuite/binutils-all/readelf.exp1
5 files changed, 102 insertions, 7 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 24d17c2..479061d 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,12 @@
+2020-03-02 Nick Clifton <nickc@redhat.com>
+
+ 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 <nickc@redhat.com>
PR 25526
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
{
diff --git a/binutils/testsuite/binutils-all/pr25543.d b/binutils/testsuite/binutils-all/pr25543.d
new file mode 100644
index 0000000..75f2392
--- /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 0000000..71bfe05
--- /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 2f9afed..cc78e66 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 {