diff options
author | Samuel Huang <huangs@chromium.org> | 2021-08-05 16:46:38 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2021-08-05 10:05:02 -0700 |
commit | fa10b05c4854c6d8a603ee47c2a213cbc23f8646 (patch) | |
tree | 94ad9d794dedc26bd0e0be4b18511d45026a0b98 /rel32_finder.h | |
parent | 3e1f64d1395c53a730475d930b663d5f6006099e (diff) | |
download | zucchini-fa10b05c4854c6d8a603ee47c2a213cbc23f8646.tar.gz |
[Zucchini] Add ARM support for ELF files.
This CL enables ARM-ELF (AArch32 and AArch64) support in Zucchini.
* Define ARM {AArch32, AArch64}ReferenceType.
* Add Rel32Finder{Arm, AArch32, AArch64} (with tests) to use
previously-added ARM disassembly code to extract rel32 references.
* Add DisassemblerElf{Arm, AArch32, AArch64} to parse ARM ELF files and
create reference readers / writers, and reference groups.
* For AArch32: Add heuristic detection of ARM vs. Thumb2 mode.
* Add IsTargetOffsetInElfSectionList() (with tests) to help ARM reject
false positive references.
* Add ReferenceBytesMixerElfArm to remove redundant reference target
information from bytewise correction data.
Bug: 918867
Change-Id: I1e6d3d8b8d174c85a3d44ca6d642b7ff0bd6a6a6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2922822
Commit-Queue: Samuel Huang <huangs@chromium.org>
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Cr-Commit-Position: refs/heads/master@{#908913}
NOKEYCHECK=True
GitOrigin-RevId: 85cc8a596f183487b395a59e80b2f654f241ab2c
Diffstat (limited to 'rel32_finder.h')
-rw-r--r-- | rel32_finder.h | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/rel32_finder.h b/rel32_finder.h index 96a23b9..3ebeb95 100644 --- a/rel32_finder.h +++ b/rel32_finder.h @@ -10,6 +10,7 @@ #include <vector> #include "components/zucchini/address_translator.h" +#include "components/zucchini/arm_utils.h" #include "components/zucchini/buffer_view.h" #include "components/zucchini/image_utils.h" @@ -198,6 +199,86 @@ class Rel32FinderX64 : public Rel32FinderIntel { NextIterators Scan(ConstBufferView region) override; }; +// Base class for ARM (AArch32 and AArch64) instructions. +template <typename ADDR_TYPE> +class Rel32FinderArm : public Rel32Finder { + public: + struct Result { + offset_t location; + rva_t target_rva; + ADDR_TYPE type; + + // For testing. + bool operator==(const Result& other) const { + return location == other.location && target_rva == other.target_rva && + type == other.type; + } + }; + + Rel32FinderArm(ConstBufferView image, const AddressTranslator& translator); + Rel32FinderArm(const Rel32FinderArm&) = delete; + const Rel32FinderArm& operator=(const Rel32FinderArm&) = delete; + ~Rel32FinderArm() override; + + // Helper for Scan*() that also assigns |rel32_|. + NextIterators SetResult(Result&& result, + ConstBufferView::const_iterator cursor, + int instr_size); + + // SetResult() for end of scan. + NextIterators SetEmptyResult(); + + protected: + // Cached results. + Result rel32_; +}; + +// AArch32 instructions. +class Rel32FinderAArch32 + : public Rel32FinderArm<AArch32Rel32Translator::AddrType> { + public: + Rel32FinderAArch32(ConstBufferView image, + const AddressTranslator& translator, + bool is_thumb2); + Rel32FinderAArch32(const Rel32FinderAArch32&) = delete; + const Rel32FinderAArch32& operator=(const Rel32FinderAArch32&) = delete; + ~Rel32FinderAArch32() override; + + const Result& GetRel32() const { return rel32_; } + + private: + // Rel32 extraction, assuming segment is in ARM mode. + NextIterators ScanA32(ConstBufferView region); + + // Rel32 extraction, assuming segment is in THUMB2 mode. + NextIterators ScanT32(ConstBufferView region); + + // Rel32Finder: + NextIterators Scan(ConstBufferView region) override; + + // Indicates whether segment is in THUMB2 or ARM mod. In general this can + // change throughout a section. However, currently we assume that this is + // constant for an entire section. + const bool is_thumb2_; +}; + +// AArch64 instructions. +class Rel32FinderAArch64 + : public Rel32FinderArm<AArch64Rel32Translator::AddrType> { + public: + Rel32FinderAArch64(ConstBufferView image, + const AddressTranslator& translator); + Rel32FinderAArch64(const Rel32FinderAArch64&) = delete; + const Rel32FinderAArch64& operator=(const Rel32FinderAArch64&) = delete; + ~Rel32FinderAArch64() override; + + const Result& GetRel32() const { return rel32_; } + + private: + // Rel32Finder: + NextIterators Scan(ConstBufferView region) override; +}; + } // namespace zucchini #endif // COMPONENTS_ZUCCHINI_REL32_FINDER_H_ |