diff options
author | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2025-01-06 21:40:12 -0800 |
---|---|---|
committer | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2025-01-07 22:27:46 -0800 |
commit | 8520cebeb576ae345ae506f2d7207668cc68d1cb (patch) | |
tree | e4dbb54628cb56e03abd25d679ab86e82f82f7a8 | |
parent | 8791ea5e49c886788e6835c38ad188c025810382 (diff) | |
download | binutils-8520cebeb576ae345ae506f2d7207668cc68d1cb.zip binutils-8520cebeb576ae345ae506f2d7207668cc68d1cb.tar.gz binutils-8520cebeb576ae345ae506f2d7207668cc68d1cb.tar.bz2 |
Fix 32085 Source file not recognized for gcc 11.4.0-compiled code
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.
-rw-r--r-- | gprofng/src/Elf.cc | 38 | ||||
-rw-r--r-- | gprofng/src/Elf.h | 1 |
2 files changed, 31 insertions, 8 deletions
diff --git a/gprofng/src/Elf.cc b/gprofng/src/Elf.cc index c2c4468..b9da240 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 0735863..7c32dfe 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 |