xref: /aosp_15_r20/external/zucchini/abs32_utils.h (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_ZUCCHINI_ABS32_UTILS_H_
6 #define COMPONENTS_ZUCCHINI_ABS32_UTILS_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <optional>
12 #include <vector>
13 
14 #include "components/zucchini/address_translator.h"
15 #include "components/zucchini/buffer_view.h"
16 #include "components/zucchini/image_utils.h"
17 
18 namespace zucchini {
19 
20 // A class to represent an abs32 address (32-bit or 64-bit). Accessors are
21 // provided to translate from / to RVA, and to read / write the represented
22 // abs32 address from / to an image.
23 class AbsoluteAddress {
24  public:
25   AbsoluteAddress(Bitness bitness, uint64_t image_base);
26   AbsoluteAddress(AbsoluteAddress&&);
27   ~AbsoluteAddress();
28 
29   // Attempts to translate |rva| to an abs32 address. On success, assigns
30   // |value_| to the result and returns true. On failure (invalid |rva| or
31   // overflow), returns false.
32   bool FromRva(rva_t rva);
33 
34   // Returns the RVA for |value_|, or |kInvalidRva| if the represented value
35   // address does not correspond to a valid RVA.
36   rva_t ToRva() const;
37 
38   // Attempts to read the abs32 address at |image[offset]| into |value_|. On
39   // success, updates |value_| and returns true. On failure (invalid |offset|),
40   // returns false.
41   bool Read(offset_t offset, const ConstBufferView& image);
42 
43   // Attempts to write |value_| to to |(*image)[offset]|. On success, performs
44   // the write and returns true. On failure (invalid |offset|), returns false.
45   bool Write(offset_t offset, MutableBufferView* image);
46 
width()47   uint32_t width() const { return WidthOf(bitness_); }
48 
49   // Exposing |value_| for testing.
mutable_value()50   uint64_t* mutable_value() { return &value_; }
51 
52  private:
53   const Bitness bitness_;
54   const uint64_t image_base_;  // Accommodates 32-bit and 64-bit.
55   uint64_t value_;             // Accommodates 32-bit and 64-bit.
56 };
57 
58 // A class to extract Win32 abs32 references from |abs32_locations| within
59 // |image_| bounded by |[lo, hi)|. GetNext() is used to successively return
60 // data as Units, which are locations and (potentially out-of-bound) RVAs.
61 // |addr| determines the bitness of abs32 values stored, and mediates all reads.
62 class Abs32RvaExtractorWin32 {
63  public:
64   struct Unit {
65     offset_t location;
66     rva_t target_rva;
67   };
68 
69   // Requires |lo| <= |hi|, and they must not straddle a reference body (with
70   // length |addr.width()|) in |abs32_locations|.
71   Abs32RvaExtractorWin32(ConstBufferView image,
72                          AbsoluteAddress&& addr,
73                          const std::vector<offset_t>& abs32_locations,
74                          offset_t lo,
75                          offset_t hi);
76   Abs32RvaExtractorWin32(Abs32RvaExtractorWin32&&);
77   ~Abs32RvaExtractorWin32();
78 
79   // Visits given abs32 locations, rejects invalid locations and non-existent
80   // RVAs, and returns reference as Unit, or std::nullopt on completion.
81   std::optional<Unit> GetNext();
82 
83  private:
84   ConstBufferView image_;
85   AbsoluteAddress addr_;
86   std::vector<offset_t>::const_iterator cur_abs32_;
87   std::vector<offset_t>::const_iterator end_abs32_;
88 };
89 
90 // A reader for Win32 abs32 references that filters and translates results from
91 // |abs32_rva_extractor_|.
92 class Abs32ReaderWin32 : public ReferenceReader {
93  public:
94   Abs32ReaderWin32(Abs32RvaExtractorWin32&& abs32_rva_extractor,
95                    const AddressTranslator& translator);
96   Abs32ReaderWin32(const Abs32ReaderWin32&) = delete;
97   const Abs32ReaderWin32& operator=(const Abs32ReaderWin32&) = delete;
98   ~Abs32ReaderWin32() override;
99 
100   // ReferenceReader:
101   std::optional<Reference> GetNext() override;
102 
103  private:
104   Abs32RvaExtractorWin32 abs32_rva_extractor_;
105   AddressTranslator::RvaToOffsetCache target_rva_to_offset_;
106 };
107 
108 // A writer for Win32 abs32 references. |addr| determines the bitness of the
109 // abs32 values stored, and mediates all writes.
110 class Abs32WriterWin32 : public ReferenceWriter {
111  public:
112   Abs32WriterWin32(MutableBufferView image,
113                    AbsoluteAddress&& addr,
114                    const AddressTranslator& translator);
115   Abs32WriterWin32(const Abs32WriterWin32&) = delete;
116   const Abs32WriterWin32& operator=(const Abs32WriterWin32&) = delete;
117   ~Abs32WriterWin32() override;
118 
119   // ReferenceWriter:
120   void PutNext(Reference ref) override;
121 
122  private:
123   MutableBufferView image_;
124   AbsoluteAddress addr_;
125   AddressTranslator::OffsetToRvaCache target_offset_to_rva_;
126 };
127 
128 // Given a list of abs32 |locations|, removes all elements whose targets cannot
129 // be translated. Returns the number of elements removed.
130 size_t RemoveUntranslatableAbs32(ConstBufferView image,
131                                  AbsoluteAddress&& addr,
132                                  const AddressTranslator& translator,
133                                  std::vector<offset_t>* locations);
134 
135 // Given a sorted list of abs32 |locations|, removes all elements whose body
136 // (with |width| given) overlaps with the body of a previous element.
137 size_t RemoveOverlappingAbs32Locations(uint32_t width,
138                                        std::vector<offset_t>* locations);
139 
140 }  // namespace zucchini
141 
142 #endif  // COMPONENTS_ZUCCHINI_ABS32_UTILS_H_
143