[binutils-gdb] readelf vs. mapping symbols

Alan Modra amodra@sourceware.org
Fri Jan 30 21:20:35 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bd1dff62e881beec4183eb931041fc8840eed719

commit bd1dff62e881beec4183eb931041fc8840eed719
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Jan 31 07:05:55 2026 +1030

    readelf vs. mapping symbols
    
    This reverts commit 45cf0b829303, which isn't needed after commit
    6d7e5bcca5.   Mapping symbols are like any other local symbol, and
    shouldn't appear after the end of a section.
    
    The real bug that resulted in both of these commits is that st_value
    in an executable or shared library is the symbol address.  It was
    wrong to compare an address against a section size (you'd need to
    subtract off the section vma first).  The second commit limited the
    warning to ET_REL where st_value is a section offset and thus can be
    compared directly to the section size.

Diff:
---
 binutils/readelf.c | 27 +++++++--------------------
 1 file changed, 7 insertions(+), 20 deletions(-)

diff --git a/binutils/readelf.c b/binutils/readelf.c
index f50d9281ea4..c98569a14b4 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -14748,18 +14748,6 @@ print_symbol_size (uint64_t vma, int base)
     }
 }
 
-/* The AArch64, ARM and RISC-V architectures define mapping
-   symbols (eg $d, $x, $t) which sometime should be ignored.  */
-
-static bool
-is_mapping_symbol (const char * name)
-{
-  return name[0] == '$'
-    && name [1] != 0
-    /* FIXME: Check that name[1] is lower case ASCII ?  */
-    && name [2] == 0;
-}
-
 /* Print information on a single symbol.  */
 
 static void
@@ -14894,11 +14882,9 @@ print_symbol (Filedata *           filedata,
     warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
 	  symbol_index, printable_section_name (filedata, section), section->sh_info);
 
-  /* Local symbols (in objec files) whose value is larger than their section's
-     size are suspicious especially if that section is mergeable - and hence
-     might change offsets of the contents inside the section.   Note - for
-     some reason we can get mapping symbols that do not relate to their
-     section's contents - so we ignore those type of symbol as well.  */
+  /* Local symbols in ET_REL whose value is larger than their
+     section's size are suspicious if that section is mergeable - and
+     hence might change offsets of the contents inside the section.  */
   if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
       && filedata->file_header.e_type == ET_REL
       && ! is_special
@@ -14906,8 +14892,7 @@ print_symbol (Filedata *           filedata,
       && psym->st_shndx < filedata->file_header.e_shnum
       && filedata->section_headers != NULL
       && (filedata->section_headers[psym->st_shndx].sh_flags & SHF_MERGE)
-      && psym->st_value > filedata->section_headers[psym->st_shndx].sh_size
-      && ! is_mapping_symbol (strtab + psym->st_name))
+      && psym->st_value > filedata->section_headers[psym->st_shndx].sh_size)
     warn (_("local symbol %s has a value (%#" PRIx64 ") which is larger than mergeable section %s's size (%#" PRIx64 ")\n"),
 	  strtab + psym->st_name,
 	  psym->st_value,
@@ -23476,7 +23461,9 @@ get_symbol_for_build_attribute (Filedata *filedata,
 
 	/* The AArch64, ARM and RISC-V architectures define mapping symbols
 	   (eg $d, $x, $t) which we want to ignore.  */
-	if (is_mapping_symbol (ba_cache.strtab + sym->st_name))
+	if (ba_cache.strtab[sym->st_name] == '$'
+	    && ba_cache.strtab[sym->st_name + 1] != 0
+	    && ba_cache.strtab[sym->st_name + 2] == 0)
 	  continue;
 
 	if (is_open_attr)


More information about the Binutils-cvs mailing list