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