[PATCH 4/4] binutils: Add UTF-8 tests
Alice Carlotti
alice.carlotti@arm.com
Thu Sep 25 18:13:40 GMT 2025
The UTF-8 support in nm, objdump, readelf and strings was completely
untested. This patch adds tests with various combinations of valid and
invalid encodings.
The unicode.exp file is based on an incomplete patch [1] that was posted by
Nick but not fully committed. The unicode-symbols test input covers all
relevant edge cases, but the checks are deliberately lax for now because
I'm unsure what the correct output should be in some cases.
[1] https://sourceware.org/pipermail/binutils/2021-November/118453.html
Co-Authored-by: Nick Clifton <nickc@redhat.com>
---
Note: The diff for unicode-symbols.s in this email has been edited to replace
bytes larger than 0x7f with a hex string "<XX>", for ease of review (and to
avoid upsetting mail clients). The corresponding tests are lax enough that
they will still pass, so it shouldn't matter that CI will run with the edited
patch instead of the original.
diff --git a/binutils/testsuite/binutils-all/nm.hex.unicode-symbols b/binutils/testsuite/binutils-all/nm.hex.unicode-symbols
new file mode 100644
index 0000000000000000000000000000000000000000..14fe8a47c537f7a9d3d17409ddac33575c442464
--- /dev/null
+++ b/binutils/testsuite/binutils-all/nm.hex.unicode-symbols
@@ -0,0 +1,4 @@
+# TODO: Tighten these checks
+#...
+.*AA.*
+#...
diff --git a/binutils/testsuite/binutils-all/objdump.highlight.unicode-symbols b/binutils/testsuite/binutils-all/objdump.highlight.unicode-symbols
new file mode 100644
index 0000000000000000000000000000000000000000..43b5bd13c278cb6f72f3ef87772495485abd59db
--- /dev/null
+++ b/binutils/testsuite/binutils-all/objdump.highlight.unicode-symbols
@@ -0,0 +1,4 @@
+# TODO: Tighten these checks
+#...
+.*AA.*
+#pass
diff --git a/binutils/testsuite/binutils-all/readelf.invalid.unicode-symbols b/binutils/testsuite/binutils-all/readelf.invalid.unicode-symbols
new file mode 100644
index 0000000000000000000000000000000000000000..43b5bd13c278cb6f72f3ef87772495485abd59db
--- /dev/null
+++ b/binutils/testsuite/binutils-all/readelf.invalid.unicode-symbols
@@ -0,0 +1,4 @@
+# TODO: Tighten these checks
+#...
+.*AA.*
+#pass
diff --git a/binutils/testsuite/binutils-all/strings.escape.unicode b/binutils/testsuite/binutils-all/strings.escape.unicode
new file mode 100644
index 0000000000000000000000000000000000000000..f081d540010c97dd77ff59960911434e9001ba9d
--- /dev/null
+++ b/binutils/testsuite/binutils-all/strings.escape.unicode
@@ -0,0 +1,9 @@
+#...
+Fk\\u00b1\\u2203\\U0001d49c
+abcd
+fghi
+klmn
+pqqr
+sttu
+vwwx
+#...
diff --git a/binutils/testsuite/binutils-all/unicode-symbols.s b/binutils/testsuite/binutils-all/unicode-symbols.s
new file mode 100644
index 0000000000000000000000000000000000000000..419aacccc91c92ff5be764f374d7b2de7cd004b9
--- /dev/null
+++ b/binutils/testsuite/binutils-all/unicode-symbols.s
@@ -0,0 +1,36 @@
+foo<C2><B1><E2><88><83><F0><9D><92><9C>AA:
+ .string "Hi!!"
+foo<F8><8D><93><94>BBBBBBB:
+ .string "Hi!!"
+foo<F7><8D><93><94>CCCCCCC:
+ .string "Hi!!"
+foo<ED><A1><82>DDDDDDDD:
+ .string "Hi!!"
+foo<C1><BF>EEEEEEEEE:
+ .string "Hi!!"
+foo<E0><9F><BD>FFFFFFFF:
+ .string "Hi!!"
+foo<C2>GGGGGGGGGG:
+ .string "Hi!!"
+foo<E2>HHHHHHHHHH:
+ .string "Hi!!"
+foo<E2><88>IIIIIIIII:
+ .string "Hi!!"
+foo<F0>JJJJJJJJJJ:
+ .string "Hi!!"
+foo<F0><9D>KKKKKKKKK:
+ .string "Hi!!"
+foo<F0><9D><92>LLLLLLLL:
+ .string "Hi!!"
+fooMMMMMMMMMM<C2>:
+ .string "Hi!!"
+fooNNNNNNNNNN<E2>:
+ .string "Hi!!"
+fooOOOOOOOOO<E2><88>:
+ .string "Hi!!"
+fooPPPPPPPPPP<F0>:
+ .string "Hi!!"
+fooQQQQQQQQQ<F0><9D>:
+ .string "Hi!!"
+fooRRRRRRRR<F0><9D><92>:
+ .string "Hi!!"
diff --git a/binutils/testsuite/binutils-all/unicode.exp b/binutils/testsuite/binutils-all/unicode.exp
new file mode 100644
index 0000000000000000000000000000000000000000..ca4356b3b82ddc9bf5db7186cdf81517b79892f1
--- /dev/null
+++ b/binutils/testsuite/binutils-all/unicode.exp
@@ -0,0 +1,85 @@
+# Copyright (C) 2021 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Written by Nick Clifton <nickc@redhat.com>
+
+proc unicode_test { program options binary_file regexp_file } {
+
+ global srcdir
+ global subdir
+
+ set testname "unicode $program $options [file rootname [file tail $binary_file]]"
+
+ send_log "exec $program $options $binary_file > prog.out\n"
+ set got [remote_exec host "$program $options $binary_file" "" "/dev/null" "prog.out"]
+
+ if { [lindex $got 0] != 0 } then {
+ fail "$testname (reason: execution failed)"
+ send_log $got
+ send_log "\n"
+ return
+ }
+
+ if { ![string match "" [lindex $got 1]] } then {
+ fail "$testname (reason: error output)"
+ send_log $got
+ send_log "\n"
+ return
+ }
+
+ if { [regexp_diff prog.out $srcdir/$subdir/$regexp_file] } then {
+ send_log [file_contents prog.out]
+ send_log "\n"
+ fail $testname
+ return
+ }
+
+ pass $testname
+}
+
+# Assemble the strings test file.
+if {![binutils_assemble $srcdir/$subdir/unicode.s tmpdir/unicode.o]} then {
+ unsupported "unicode string tests (failed to assemble test file)"
+} else {
+ if ![is_remote host] {
+ set tempfile tmpdir/unicode.o
+ } else {
+ set tempfile [remote_download host tmpdir/unicode.o]
+ }
+
+ global STRINGS
+ unicode_test $STRINGS {--unicode=escape} $tempfile strings.escape.unicode
+ unicode_test $STRINGS {-d --unicode=escape} $tempfile strings.escape.unicode
+}
+
+# Assemble the symbols test file.
+if {![binutils_assemble $srcdir/$subdir/unicode-symbols.s tmpdir/unicode-symbols.o]} then {
+ unsupported "unicode symbol tests (failed to assemble test file)"
+} else {
+ if ![is_remote host] {
+ set tempfile tmpdir/unicode-symbols.o
+ } else {
+ set tempfile [remote_download host tmpdir/unicode-symbols.o]
+ }
+
+ global NM OBJDUMP READELF
+ unicode_test $NM {--unicode=hex} $tempfile nm.hex.unicode-symbols
+ unicode_test $OBJDUMP {-tUh} $tempfile objdump.highlight.unicode-symbols
+
+ if [is_elf_format] {
+ unicode_test $READELF {-sUi} $tempfile readelf.invalid.unicode-symbols
+ }
+}
diff --git a/binutils/testsuite/binutils-all/unicode.s b/binutils/testsuite/binutils-all/unicode.s
new file mode 100644
index 0000000000000000000000000000000000000000..6299198a526224d73ecf4b207124b333d8db22e8
--- /dev/null
+++ b/binutils/testsuite/binutils-all/unicode.s
@@ -0,0 +1,28 @@
+foo:
+ .byte 'F
+ .byte 'k
+ .byte 0xc2, 0xb1 /* \u00b1 */
+ .byte 0xe2, 0x88, 0x83 /* \u2203 */
+ .byte 0xf0, 0x9d, 0x92, 0x9c /* \U0001d49c */
+ .byte 0xf8, 0x8d, 0x93, 0x94 /* Invalid - prefix indicates >4 bytes */
+ .byte 'A, 'B
+ .byte 0xf7, 0x8d, 0x93, 0x94 /* Out of range (> 0x10ffff) */
+ .byte 'A, 'B
+ .byte 0xed, 0xa1, 0x82 /* \ud842 - surrogate pair value */
+ .byte 'A, 'B
+ .byte 0xc1, 0xbf /* Overlong encoding */
+ .byte 'A, 'B
+ .byte 0xe0, 0x9f, 0xbd /* Overlong encoding */
+ .byte 'A, 'B
+ .byte 0xc2 /* Missing continuation bytes */
+ .byte 'a, 'b, 'c, 'd
+ .byte 0xe2 /* Missing continuation bytes */
+ .byte 'f, 'g, 'h, 'i
+ .byte 0xe2, 0x88 /* Missing continuation bytes */
+ .byte 'k, 'l, 'm, 'n
+ .byte 0xf0 /* Missing continuation bytes */
+ .byte 'p, 'q, 'q, 'r
+ .byte 0xf0, 0x9d /* Missing continuation bytes */
+ .byte 's, 't, 't, 'u
+ .byte 0xf0, 0x9d, 0x92 /* Missing continuation bytes */
+ .byte 'v, 'w, 'w, 'x
More information about the Binutils
mailing list