diff options
| author | Galen Williamson <galen@vector35.com> | 2025-06-29 11:23:58 -0400 |
|---|---|---|
| committer | Galen Williamson <galen@vector35.com> | 2025-06-29 18:28:48 -0400 |
| commit | e8206bc27e1633c7e4c99907f43bf67d2f200cd5 (patch) | |
| tree | 2315bec284e9bb692a0eb8986578fe18e2289d23 /view/elf/elfview.cpp | |
| parent | 91f1eccb6c41a7ef60fd66387ffae075f88141a4 (diff) | |
[powerpc] Full merge of PowerPC disassembler PRs, including:
* Remove dependency on capstone for PowerPC disassembly #6292
* Add support for PowerPC VLE instruction set #6740
* Add support for paired-single instructions #6821
* Various post-merge fixes and tweaks to disassembly and lifting
* Removal of dependence on capstone for assembler's scoring mechanism (capstone currently disabled, but not removed from codebase yet)
Diffstat (limited to 'view/elf/elfview.cpp')
| -rw-r--r-- | view/elf/elfview.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/view/elf/elfview.cpp b/view/elf/elfview.cpp index 25e00152..d7dc1203 100644 --- a/view/elf/elfview.cpp +++ b/view/elf/elfview.cpp @@ -2875,6 +2875,8 @@ uint64_t ElfViewType::ParseHeaders(BinaryView* data, ElfIdent& ident, ElfCommonH commonHeader.arch = reader.Read16(); commonHeader.version = reader.Read32(); + bool is32bit = ident.fileClass == 1; + // parse Elf64Header if (ident.fileClass == 1) // 32-bit ELF { @@ -2908,6 +2910,37 @@ uint64_t ElfViewType::ParseHeaders(BinaryView* data, ElfIdent& ident, ElfCommonH return 0; } + // This is some disgusting code duplication, the PowerPC ELF recognizer + // needs some section information passed to it: + // (1) contents of the .ppc.EMB.apuinfo to figure out additional + // processor information (SPE, Altivec, etc.) + // (2) whether any sections have VLE flags + // + // But this function doesn't have a handle to the ElfView, so we + // duplicate the section iteration/parsing logic + // + // We're early enough in the process that if sizes aren't what we expect + // them to be, we just don't pass section info to the ELF recognizer + // function, but pass everything else to aid troubleshooting + uint16_t sectionHeaderSize = header.sectionHeaderSize; + uint32_t sectionCount = header.sectionHeaderCount; + if (is32bit && (sectionHeaderSize != sizeof(Elf32SectionHeader))) + { + m_logger->LogWarn( + "The section header size reported by e_shentsize (0x%lx) is different from the size of Elf32_Shdr (0x%lx). " + "Won't do first pass section header parsing.", + sectionHeaderSize, sizeof(Elf32SectionHeader)); + sectionCount = 0; + } + else if (!is32bit && (sectionHeaderSize != sizeof(Elf64SectionHeader))) + { + m_logger->LogWarn( + "The section header size reported by e_shentsize (0x%lx) is different from the size of Elf64_Shdr (0x%lx). " + "Won't do first pass section header parsing.", + sectionHeaderSize, sizeof(Elf64SectionHeader)); + sectionCount = 0; + } + map<string, Ref<Metadata>> metadataMap = { {"EI_CLASS", new Metadata((uint64_t) ident.fileClass)}, {"EI_DATA", new Metadata((uint64_t) ident.encoding)}, @@ -2917,6 +2950,43 @@ uint64_t ElfViewType::ParseHeaders(BinaryView* data, ElfIdent& ident, ElfCommonH {"e_flags", new Metadata((uint64_t) header.flags)}, }; + BinaryReader sectionReader(data); + sectionReader.SetEndianness(endianness); + uint64_t flagsOffset = header.sectionHeaderOffset; + if (is32bit) + flagsOffset += offsetof(Elf32SectionHeader, flags); + else + flagsOffset += offsetof(Elf64SectionHeader, flags); + + for (unsigned int i=0; i < sectionCount; ++i) + { + sectionReader.Seek(flagsOffset); + uint64_t flags; + try + { + if (is32bit) + flags = sectionReader.Read32(); + else + flags = sectionReader.Read64(); + } + catch (ReadException&) + { + m_logger->LogWarn("Failed to read section flags at offset %" PRIx64, flagsOffset); + // Note that any previously read flags values will + // still persist in the metadata map + sectionCount = 0; + break; + } + + char metaname[0x20]; + snprintf(metaname, sizeof metaname, "sectionFlags[%d]", i); + + metadataMap[metaname] = new Metadata((uint64_t)flags); + flagsOffset += header.sectionHeaderSize; + } + + metadataMap["numSections"] = new Metadata((uint64_t) sectionCount); + Ref<Metadata> metadata = new Metadata(metadataMap); // retrieve architecture // FIXME: Architecture registration methods should perhaps be virtual and take the raw data, or some additional opaque information. |
