Fix 32085 Source file not recognized for gcc 11.4.0-compiled code

Message ID 20250107054158.800337-1-vladimir.mezentsev@oracle.com
State New
Headers
Series Fix 32085 Source file not recognized for gcc 11.4.0-compiled code |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Vladimir Mezentsev Jan. 7, 2025, 5:41 a.m. UTC
  From: Vladimir Mezentsev <vladimir.mezentsev@oracle.com>

gprofng cannot read compressed section.
In the next release we plan to use libbfd everywhere instead of our ELF reader.
But in this release I use bfd_get_full_section_contents() only
when bfd_is_section_compressed() returns true.

gprofng/ChangeLog
2025-01-06  Vladimir Mezentsev  <vladimir.mezentsev@oracle.com>

	PR gprofng/32085
	* src/Elf.cc: Use bfd_get_full_section_contents to decompress a section.
	* src/Elf.h: Define SEC_DECOMPRESSED.
---
 gprofng/src/Elf.cc | 38 ++++++++++++++++++++++++++++++--------
 gprofng/src/Elf.h  |  1 +
 2 files changed, 31 insertions(+), 8 deletions(-)
  

Patch

diff --git a/gprofng/src/Elf.cc b/gprofng/src/Elf.cc
index c2c44684472..b9da2403bef 100644
--- a/gprofng/src/Elf.cc
+++ b/gprofng/src/Elf.cc
@@ -265,9 +265,14 @@  Elf::~Elf ()
       for (int i = 0; i < (int) ehdrp->e_shnum; i++)
 	{
 	  Elf_Data *p = data[i];
-	  if (p && !mmap_on_file && (p->d_flags & SHF_SUNW_ABSENT) == 0)
-	    free (p->d_buf);
-	  delete p;
+	  if (p)
+	    {
+	      if (p->d_flags & SEC_DECOMPRESSED)
+		free (p->d_buf);
+	      else if (!mmap_on_file && (p->d_flags & SHF_SUNW_ABSENT) == 0)
+		free (p->d_buf);
+	      delete p;
+	    }
 	}
       free (data);
     }
@@ -443,11 +448,28 @@  Elf::elf_getdata (unsigned int sec)
 		}
 	    }
 	}
-      edta->d_buf = get_data (shdr->sh_offset, (size_t) shdr->sh_size, NULL);
-      edta->d_flags = shdr->sh_flags;
-      edta->d_size = ((edta->d_buf == NULL) || (shdr->sh_type == SHT_NOBITS)) ? 0 : shdr->sh_size;
-      edta->d_off = shdr->sh_offset;
-      edta->d_align = shdr->sh_addralign;
+
+      sec_ptr sp = shdr->bfd_section;
+      if (sp && bfd_is_section_compressed (abfd, sp))
+	{
+	  bfd_byte *p = NULL;
+	  if (bfd_get_full_section_contents (abfd, sp, &p))
+	    {
+	      edta->d_buf = p;
+	      edta->d_size = p ? sp->size : 0;
+	      edta->d_off = 0;
+	      edta->d_flags = shdr->sh_flags | SEC_DECOMPRESSED;
+	      edta->d_align = shdr->sh_addralign;
+	    }
+	}
+      else
+	{
+	  edta->d_buf = get_data (shdr->sh_offset, (size_t) shdr->sh_size, NULL);
+	  edta->d_flags = shdr->sh_flags;
+	  edta->d_size = ((edta->d_buf == NULL) || (shdr->sh_type == SHT_NOBITS)) ? 0 : shdr->sh_size;
+	  edta->d_off = shdr->sh_offset;
+	  edta->d_align = shdr->sh_addralign;
+	}
     }
   return edta;
 }
diff --git a/gprofng/src/Elf.h b/gprofng/src/Elf.h
index 073586314bb..7c32dfe10b1 100644
--- a/gprofng/src/Elf.h
+++ b/gprofng/src/Elf.h
@@ -41,6 +41,7 @@  template <typename Key_t, typename Value_t> class Map;
 #define GELF_R_TYPE(info)   ((((uint64_t)(info))<<56)>>56)
 
 #define	SHF_SUNW_ABSENT		0x00200000	/* section data not present */
+#define	SEC_DECOMPRESSED	0x00400000	/* bfd allocated this memory */
 
 // Ancillary values.
 #define ANC_SUNW_NULL       0