aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog14
-rw-r--r--binutils/nm.c95
-rw-r--r--binutils/testsuite/binutils-all/nm.exp18
3 files changed, 94 insertions, 33 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 364fddb..0fb9e16 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,17 @@
+2019-05-01 Nick Clifton <nickc@redhat.com>
+
+ PR 24507
+ * nm.c: (print_format): New variable.
+ (value_format_32bit, value_format_64bit): Delete.
+ (set_print_radix): Remove code to alter value_format strings.
+ (set_output_format): Record chosen format in print_format.
+ (get_print_format): New function - constructs a printf formatting
+ string according to the requirements of size, radix, and output
+ format.
+ (print_value): Use get_print_format.
+ * testsuite/binutils-all/nm.exp: Add tests of "nm --format=posix"
+ and "nm -t d".
+
2019-04-30 Alan Modra <amodra@gmail.com>
* wrstabs.c (stab_start_class_type): Add assert to work around
diff --git a/binutils/nm.c b/binutils/nm.c
index 256f7e2..fd3f731 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -141,6 +141,7 @@ static struct output_fns formats[] =
/* The output format to use. */
static struct output_fns *format = &formats[FORMAT_DEFAULT];
+static unsigned int print_format = FORMAT_DEFAULT;
/* Command options. */
@@ -168,17 +169,6 @@ static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
static int filename_per_file = 0; /* Once per file, on its own line. */
static int filename_per_symbol = 0; /* Once per symbol, at start of line. */
-/* Print formats for printing a symbol value. */
-static char value_format_32bit[] = "%08lx";
-#if BFD_HOST_64BIT_LONG
-static char value_format_64bit[] = "%016lx";
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
-static char value_format_64bit[] = "%016llx";
-#else
-static char value_format_64bit[] = "%016I64x";
-#endif
-#endif
static int print_width = 0;
static int print_radix = 16;
/* Print formats for printing stab info. */
@@ -303,29 +293,15 @@ set_print_radix (char *radix)
{
switch (*radix)
{
- case 'x':
- break;
- case 'd':
- case 'o':
- if (*radix == 'd')
- print_radix = 10;
- else
- print_radix = 8;
- value_format_32bit[4] = *radix;
-#if BFD_HOST_64BIT_LONG
- value_format_64bit[5] = *radix;
-#elif BFD_HOST_64BIT_LONG_LONG
-#ifndef __MSVCRT__
- value_format_64bit[6] = *radix;
-#else
- value_format_64bit[7] = *radix;
-#endif
-#endif
- other_format[3] = desc_format[3] = *radix;
- break;
+ case 'x': print_radix = 16; break;
+ case 'd': print_radix = 10; break;
+ case 'o': print_radix = 8; break;
+
default:
fatal (_("%s: invalid radix"), radix);
}
+
+ other_format[3] = desc_format[3] = *radix;
}
static void
@@ -351,6 +327,7 @@ set_output_format (char *f)
fatal (_("%s: invalid output format"), f);
}
format = &formats[i];
+ print_format = i;
}
static const char *
@@ -1480,6 +1457,58 @@ print_symbol_filename_posix (bfd *archive_bfd, bfd *abfd)
}
}
+/* Construct a formatting string for printing symbol values. */
+
+static const char *
+get_print_format (void)
+{
+ static const char * saved_format = NULL;
+
+ /* See if we have already constructed the format. */
+ if (saved_format)
+ return saved_format;
+
+ const char * padding;
+ if (print_format == FORMAT_POSIX)
+ {
+ /* POSIX compatible output does not have any padding. */
+ padding = "";
+ }
+ else if (print_width == 32)
+ {
+ padding ="08";
+ }
+ else /* print_width == 64 */
+ {
+ padding = "016";
+ }
+
+ const char * length = "l";
+ if (print_width == 64)
+ {
+#if BFD_HOST_64BIT_LONG
+ ;
+#elif BFD_HOST_64BIT_LONG_LONG
+#ifndef __MSVCRT__
+ length = "ll";
+#else
+ length = "I64";
+#endif
+#endif
+ }
+
+ const char * radix = NULL;
+ switch (print_radix)
+ {
+ case 8: radix = "o"; break;
+ case 10: radix = "d"; break;
+ case 16: radix = "x"; break;
+ }
+
+ saved_format = concat ("%", padding, length, radix, NULL);
+ return saved_format;
+}
+
/* Print a symbol value. */
static void
@@ -1488,12 +1517,12 @@ print_value (bfd *abfd ATTRIBUTE_UNUSED, bfd_vma val)
switch (print_width)
{
case 32:
- printf (value_format_32bit, (unsigned long) val);
+ printf (get_print_format (), (unsigned long) val);
break;
case 64:
#if BFD_HOST_64BIT_LONG || BFD_HOST_64BIT_LONG_LONG
- printf (value_format_64bit, val);
+ printf (get_print_format (), val);
#else
/* We have a 64 bit value to print, but the host is only 32 bit. */
if (print_radix == 16)
diff --git a/binutils/testsuite/binutils-all/nm.exp b/binutils/testsuite/binutils-all/nm.exp
index a2ef799..64a969e 100644
--- a/binutils/testsuite/binutils-all/nm.exp
+++ b/binutils/testsuite/binutils-all/nm.exp
@@ -119,6 +119,24 @@ if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
} else {
fail "nm -P"
}
+
+ # Test nm -t d
+ # Look for leading zeroes and only the digits 0..9 in the actual value.
+ set got [binutils_run $NM "$NMFLAGS -t d $tempfile"]
+ if [regexp "0+\[1-9\]\[0-9\]* T text_symbol3" $got] then {
+ pass "nm -t d"
+ } else {
+ fail "nm -t d"
+ }
+
+ # Test nm --format=posix
+ # ref: PR 24507 - no leading zeros.
+ set got [binutils_run $NM "$NMFLAGS --format=posix $tempfile"]
+ if [regexp "text_symbol3 T \[1-9a-f\]\[0-9a-f\]*" $got] then {
+ pass "nm --format posix"
+ } else {
+ fail "nm --format posix"
+ }
}
# Test nm --size-sort