123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef COMPONENTS_ZUCCHINI_ABS32_UTILS_H_
- #define COMPONENTS_ZUCCHINI_ABS32_UTILS_H_
- #include <stddef.h>
- #include <stdint.h>
- #include <deque>
- #include "components/zucchini/address_translator.h"
- #include "components/zucchini/buffer_view.h"
- #include "components/zucchini/image_utils.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace zucchini {
- // A class to represent an abs32 address (32-bit or 64-bit). Accessors are
- // provided to translate from / to RVA, and to read / write the represented
- // abs32 address from / to an image.
- class AbsoluteAddress {
- public:
- AbsoluteAddress(Bitness bitness, uint64_t image_base);
- AbsoluteAddress(AbsoluteAddress&&);
- ~AbsoluteAddress();
- // Attempts to translate |rva| to an abs32 address. On success, assigns
- // |value_| to the result and returns true. On failure (invalid |rva| or
- // overflow), returns false.
- bool FromRva(rva_t rva);
- // Returns the RVA for |value_|, or |kInvalidRva| if the represented value
- // address does not correspond to a valid RVA.
- rva_t ToRva() const;
- // Attempts to read the abs32 address at |image[offset]| into |value_|. On
- // success, updates |value_| and returns true. On failure (invalid |offset|),
- // returns false.
- bool Read(offset_t offset, const ConstBufferView& image);
- // Attempts to write |value_| to to |(*image)[offset]|. On success, performs
- // the write and returns true. On failure (invalid |offset|), returns false.
- bool Write(offset_t offset, MutableBufferView* image);
- uint32_t width() const { return WidthOf(bitness_); }
- // Exposing |value_| for testing.
- uint64_t* mutable_value() { return &value_; }
- private:
- const Bitness bitness_;
- const uint64_t image_base_; // Accommodates 32-bit and 64-bit.
- uint64_t value_; // Accommodates 32-bit and 64-bit.
- };
- // A class to extract Win32 abs32 references from |abs32_locations| within
- // |image_| bounded by |[lo, hi)|. GetNext() is used to successively return
- // data as Units, which are locations and (potentially out-of-bound) RVAs.
- // |addr| determines the bitness of abs32 values stored, and mediates all reads.
- class Abs32RvaExtractorWin32 {
- public:
- struct Unit {
- offset_t location;
- rva_t target_rva;
- };
- // Requires |lo| <= |hi|, and they must not straddle a reference body (with
- // length |addr.width()|) in |abs32_locations|.
- Abs32RvaExtractorWin32(ConstBufferView image,
- AbsoluteAddress&& addr,
- const std::deque<offset_t>& abs32_locations,
- offset_t lo,
- offset_t hi);
- Abs32RvaExtractorWin32(Abs32RvaExtractorWin32&&);
- ~Abs32RvaExtractorWin32();
- // Visits given abs32 locations, rejects invalid locations and non-existent
- // RVAs, and returns reference as Unit, or absl::nullopt on completion.
- absl::optional<Unit> GetNext();
- private:
- ConstBufferView image_;
- AbsoluteAddress addr_;
- std::deque<offset_t>::const_iterator cur_abs32_;
- std::deque<offset_t>::const_iterator end_abs32_;
- };
- // A reader for Win32 abs32 references that filters and translates results from
- // |abs32_rva_extractor_|.
- class Abs32ReaderWin32 : public ReferenceReader {
- public:
- Abs32ReaderWin32(Abs32RvaExtractorWin32&& abs32_rva_extractor,
- const AddressTranslator& translator);
- Abs32ReaderWin32(const Abs32ReaderWin32&) = delete;
- const Abs32ReaderWin32& operator=(const Abs32ReaderWin32&) = delete;
- ~Abs32ReaderWin32() override;
- // ReferenceReader:
- absl::optional<Reference> GetNext() override;
- private:
- Abs32RvaExtractorWin32 abs32_rva_extractor_;
- AddressTranslator::RvaToOffsetCache target_rva_to_offset_;
- };
- // A writer for Win32 abs32 references. |addr| determines the bitness of the
- // abs32 values stored, and mediates all writes.
- class Abs32WriterWin32 : public ReferenceWriter {
- public:
- Abs32WriterWin32(MutableBufferView image,
- AbsoluteAddress&& addr,
- const AddressTranslator& translator);
- Abs32WriterWin32(const Abs32WriterWin32&) = delete;
- const Abs32WriterWin32& operator=(const Abs32WriterWin32&) = delete;
- ~Abs32WriterWin32() override;
- // ReferenceWriter:
- void PutNext(Reference ref) override;
- private:
- MutableBufferView image_;
- AbsoluteAddress addr_;
- AddressTranslator::OffsetToRvaCache target_offset_to_rva_;
- };
- // Given a list of abs32 |locations|, removes all elements whose targets cannot
- // be translated. Returns the number of elements removed.
- size_t RemoveUntranslatableAbs32(ConstBufferView image,
- AbsoluteAddress&& addr,
- const AddressTranslator& translator,
- std::deque<offset_t>* locations);
- // Given a sorted list of abs32 |locations|, removes all elements whose body
- // (with |width| given) overlaps with the body of a previous element.
- size_t RemoveOverlappingAbs32Locations(uint32_t width,
- std::deque<offset_t>* locations);
- } // namespace zucchini
- #endif // COMPONENTS_ZUCCHINI_ABS32_UTILS_H_
|