aboutsummaryrefslogtreecommitdiff
path: root/rel32_finder.h
diff options
context:
space:
mode:
authorSamuel Huang <huangs@chromium.org>2021-08-05 16:46:38 +0000
committerCopybara-Service <copybara-worker@google.com>2021-08-05 10:05:02 -0700
commitfa10b05c4854c6d8a603ee47c2a213cbc23f8646 (patch)
tree94ad9d794dedc26bd0e0be4b18511d45026a0b98 /rel32_finder.h
parent3e1f64d1395c53a730475d930b663d5f6006099e (diff)
downloadzucchini-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.h81
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_