[PATCH 1/3] Make UTF-8 output simpler and easier to read.

Andrew C Aitchison werdna@aitchison.me.uk
Sat Sep 13 15:12:27 GMT 2025


---
 binutils/nm.c      | 19 +++++++++----------
 binutils/objdump.c | 19 +++++++++----------
 binutils/readelf.c | 19 +++++++++----------
 binutils/strings.c | 23 +++++++++++------------
 4 files changed, 38 insertions(+), 42 deletions(-)

diff --git a/binutils/nm.c b/binutils/nm.c
index 4ea5c1190e7..95d85a069c0 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -553,22 +553,21 @@ display_utf8 (const unsigned char * in, char * out, unsigned int * consumed)
       switch (nchars)
 	{
 	case 2:
-	  out += sprintf (out, "\\u%02x%02x",
-		  ((in[0] & 0x1c) >> 2),
-		  ((in[0] & 0x03) << 6) | (in[1] & 0x3f));
+	  out += sprintf (out, "\\u%04x",
+		  ((in[0] & 0x1f) << 6) | (in[1] & 0x3f));
 	  break;
 
 	case 3:
-	  out += sprintf (out, "\\u%02x%02x",
-		  ((in[0] & 0x0f) << 4) | ((in[1] & 0x3c) >> 2),
-		  ((in[1] & 0x03) << 6) | ((in[2] & 0x3f)));
+	  out += sprintf (out, "\\u%04x",
+		  ((in[0] & 0x0f) << 12) | ((in[1] & 0x3f) << 6) | ((in[2] & 0x3f)) );
 	  break;
 
 	case 4:
-	  out += sprintf (out, "\\u%02x%02x%02x",
-		  ((in[0] & 0x07) << 2) | ((in[1] & 0x30) >> 4),
-		  ((in[1] & 0x0f) << 4) | ((in[2] & 0x3c) >> 2),
-		  ((in[2] & 0x03) << 6) | ((in[3] & 0x3f)));
+	  out += sprintf (out, "\\u%06x",
+		    ((in[0] & 0x07) << 18)
+		  | ((in[1] & 0x3f) << 12)
+		  | ((in[2] & 0x3f) << 6)
+		  | ((in[3] & 0x3f)) );
 	  break;
 	default:
 	  /* URG.  */
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 513f6162204..490b909cd89 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -646,22 +646,21 @@ display_utf8 (const unsigned char * in, char * out, unsigned int * consumed)
       switch (nchars)
 	{
 	case 2:
-	  out += sprintf (out, "\\u%02x%02x",
-		  ((in[0] & 0x1c) >> 2),
-		  ((in[0] & 0x03) << 6) | (in[1] & 0x3f));
+	  out += sprintf (out, "\\u%04x",
+		  ((in[0] & 0x1f) << 6) | (in[1] & 0x3f));
 	  break;
 
 	case 3:
-	  out += sprintf (out, "\\u%02x%02x",
-		  ((in[0] & 0x0f) << 4) | ((in[1] & 0x3c) >> 2),
-		  ((in[1] & 0x03) << 6) | ((in[2] & 0x3f)));
+	  out += sprintf (out, "\\u%04x",
+		  ((in[0] & 0x0f) << 12) | ((in[1] & 0x3f) << 6) | ((in[2] & 0x3f)) );
 	  break;
 
 	case 4:
-	  out += sprintf (out, "\\u%02x%02x%02x",
-		  ((in[0] & 0x07) << 2) | ((in[1] & 0x30) >> 4),
-		  ((in[1] & 0x0f) << 4) | ((in[2] & 0x3c) >> 2),
-		  ((in[2] & 0x03) << 6) | ((in[3] & 0x3f)));
+	  out += sprintf (out, "\\u%06x",
+		    ((in[0] & 0x07) << 18)
+		  | ((in[1] & 0x3f) << 12)
+		  | ((in[2] & 0x3f) << 6)
+		  | ((in[3] & 0x3f)) );
 	  break;
 	default:
 	  /* URG.  */
diff --git a/binutils/readelf.c b/binutils/readelf.c
index fd9722c8afc..469b9baf928 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -833,24 +833,23 @@ print_symbol_name (signed int width, const char * symbol)
 		case 2:
 		  if (width_remaining < 6)
 		    break;
-		  printf ("\\u%02x%02x",
-			  (bytes[0] & 0x1c) >> 2,
-			  ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
+		  printf ("\\u%04x",
+				  ((bytes[0] & 0x1f) << 6) | (bytes[1] & 0x3f));
 		  break;
 		case 3:
 		  if (width_remaining < 6)
 		    break;
-		  printf ("\\u%02x%02x",
-			  ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
-			  ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
+		  printf ("\\u%04x",
+				  ((bytes[0] & 0x0f) << 12) | ((bytes[1] & 0x3f) << 6) | ((bytes[2] & 0x3f)) );
 		  break;
 		case 4:
 		  if (width_remaining < 8)
 		    break;
-		  printf ("\\u%02x%02x%02x",
-			  ((bytes[0] & 0x07) << 2) | ((bytes[1] & 0x30) >> 4),
-			  ((bytes[1] & 0x0f) << 4) | ((bytes[2] & 0x3c) >> 2),
-			  ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
+		  printf ( "\\u%06x",
+			     ((bytes[0] & 0x07) << 18)
+			   | ((bytes[1] & 0x3f) << 12)
+			   | ((bytes[2] & 0x3f) << 6)
+			   | ((bytes[3] & 0x3f)) );
 
 		  break;
 		default:
diff --git a/binutils/strings.c b/binutils/strings.c
index 38da6381edf..a8f489b9bf0 100644
--- a/binutils/strings.c
+++ b/binutils/strings.c
@@ -739,27 +739,26 @@ display_utf8_char (const unsigned char * buffer)
     case unicode_escape:
     case unicode_highlight:
       if (unicode_display == unicode_highlight && isatty (1))
-	printf ("\x1B[31;47m"); /* Red.  */
+        printf ("\x1B[31;47m"); /* Red.  */
 
       switch (utf8_len)
-	{
+        {
 	case 2:
-	  printf ("\\u%02x%02x",
-		  ((buffer[0] & 0x1c) >> 2),
-		  ((buffer[0] & 0x03) << 6) | (buffer[1] & 0x3f));
+	  printf ("\\u%04x",
+	    ((buffer[0] & 0x1f) << 6) | (buffer[1] & 0x3f));
 	  break;
 
 	case 3:
-	  printf ("\\u%02x%02x",
-		  ((buffer[0] & 0x0f) << 4) | ((buffer[1] & 0x3c) >> 2),
-		  ((buffer[1] & 0x03) << 6) | ((buffer[2] & 0x3f)));
+	  printf ("\\u%04x",
+	    ((buffer[0] & 0x0f) << 12) | ((buffer[1] & 0x3f) << 6) | ((buffer[2] & 0x3f)) );
 	  break;
 
 	case 4:
-	  printf ("\\u%02x%02x%02x",
-		  ((buffer[0] & 0x07) << 2) | ((buffer[1] & 0x30) >> 4),
-		  ((buffer[1] & 0x0f) << 4) | ((buffer[2] & 0x3c) >> 2),
-		  ((buffer[2] & 0x03) << 6) | ((buffer[3] & 0x3f)));
+	  printf("\\u%06x",
+		 ((buffer[0] & 0x07) << 18)
+		 | ((buffer[1] & 0x3f) << 12)
+		 | ((buffer[2] & 0x3f) << 6)
+		 | ((buffer[3] & 0x3f)) );
 	  break;
 	default:
 	  /* URG.  */
-- 
2.48.1



More information about the Binutils mailing list