1*a03ca8b9SKrzysztof Kosiński // Copyright 2017 The Chromium Authors. All rights reserved.
2*a03ca8b9SKrzysztof Kosiński // Use of this source code is governed by a BSD-style license that can be
3*a03ca8b9SKrzysztof Kosiński // found in the LICENSE file.
4*a03ca8b9SKrzysztof Kosiński
5*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/rel32_utils.h"
6*a03ca8b9SKrzysztof Kosiński
7*a03ca8b9SKrzysztof Kosiński #include <algorithm>
8*a03ca8b9SKrzysztof Kosiński
9*a03ca8b9SKrzysztof Kosiński #include "base/check_op.h"
10*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/io_utils.h"
11*a03ca8b9SKrzysztof Kosiński
12*a03ca8b9SKrzysztof Kosiński namespace zucchini {
13*a03ca8b9SKrzysztof Kosiński
14*a03ca8b9SKrzysztof Kosiński /******** Rel32ReaderX86 ********/
15*a03ca8b9SKrzysztof Kosiński
Rel32ReaderX86(ConstBufferView image,offset_t lo,offset_t hi,const std::deque<offset_t> * locations,const AddressTranslator & translator)16*a03ca8b9SKrzysztof Kosiński Rel32ReaderX86::Rel32ReaderX86(ConstBufferView image,
17*a03ca8b9SKrzysztof Kosiński offset_t lo,
18*a03ca8b9SKrzysztof Kosiński offset_t hi,
19*a03ca8b9SKrzysztof Kosiński const std::deque<offset_t>* locations,
20*a03ca8b9SKrzysztof Kosiński const AddressTranslator& translator)
21*a03ca8b9SKrzysztof Kosiński : image_(image),
22*a03ca8b9SKrzysztof Kosiński target_rva_to_offset_(translator),
23*a03ca8b9SKrzysztof Kosiński location_offset_to_rva_(translator),
24*a03ca8b9SKrzysztof Kosiński hi_(hi),
25*a03ca8b9SKrzysztof Kosiński last_(locations->end()) {
26*a03ca8b9SKrzysztof Kosiński DCHECK_LE(lo, image.size());
27*a03ca8b9SKrzysztof Kosiński DCHECK_LE(hi, image.size());
28*a03ca8b9SKrzysztof Kosiński current_ = std::lower_bound(locations->begin(), locations->end(), lo);
29*a03ca8b9SKrzysztof Kosiński }
30*a03ca8b9SKrzysztof Kosiński
31*a03ca8b9SKrzysztof Kosiński Rel32ReaderX86::~Rel32ReaderX86() = default;
32*a03ca8b9SKrzysztof Kosiński
GetNext()33*a03ca8b9SKrzysztof Kosiński std::optional<Reference> Rel32ReaderX86::GetNext() {
34*a03ca8b9SKrzysztof Kosiński while (current_ < last_ && *current_ < hi_) {
35*a03ca8b9SKrzysztof Kosiński offset_t loc_offset = *(current_++);
36*a03ca8b9SKrzysztof Kosiński DCHECK_LE(loc_offset + 4, image_.size()); // Sanity check.
37*a03ca8b9SKrzysztof Kosiński rva_t loc_rva = location_offset_to_rva_.Convert(loc_offset);
38*a03ca8b9SKrzysztof Kosiński rva_t target_rva = loc_rva + 4 + image_.read<int32_t>(loc_offset);
39*a03ca8b9SKrzysztof Kosiński offset_t target_offset = target_rva_to_offset_.Convert(target_rva);
40*a03ca8b9SKrzysztof Kosiński // |locations| is valid by assumption (see class description).
41*a03ca8b9SKrzysztof Kosiński DCHECK_NE(kInvalidOffset, target_offset);
42*a03ca8b9SKrzysztof Kosiński return Reference{loc_offset, target_offset};
43*a03ca8b9SKrzysztof Kosiński }
44*a03ca8b9SKrzysztof Kosiński return std::nullopt;
45*a03ca8b9SKrzysztof Kosiński }
46*a03ca8b9SKrzysztof Kosiński
47*a03ca8b9SKrzysztof Kosiński /******** Rel32ReceptorX86 ********/
48*a03ca8b9SKrzysztof Kosiński
Rel32WriterX86(MutableBufferView image,const AddressTranslator & translator)49*a03ca8b9SKrzysztof Kosiński Rel32WriterX86::Rel32WriterX86(MutableBufferView image,
50*a03ca8b9SKrzysztof Kosiński const AddressTranslator& translator)
51*a03ca8b9SKrzysztof Kosiński : image_(image),
52*a03ca8b9SKrzysztof Kosiński target_offset_to_rva_(translator),
53*a03ca8b9SKrzysztof Kosiński location_offset_to_rva_(translator) {}
54*a03ca8b9SKrzysztof Kosiński
55*a03ca8b9SKrzysztof Kosiński Rel32WriterX86::~Rel32WriterX86() = default;
56*a03ca8b9SKrzysztof Kosiński
PutNext(Reference ref)57*a03ca8b9SKrzysztof Kosiński void Rel32WriterX86::PutNext(Reference ref) {
58*a03ca8b9SKrzysztof Kosiński rva_t target_rva = target_offset_to_rva_.Convert(ref.target);
59*a03ca8b9SKrzysztof Kosiński rva_t loc_rva = location_offset_to_rva_.Convert(ref.location);
60*a03ca8b9SKrzysztof Kosiński
61*a03ca8b9SKrzysztof Kosiński // Subtraction underflow is okay
62*a03ca8b9SKrzysztof Kosiński uint32_t code =
63*a03ca8b9SKrzysztof Kosiński static_cast<uint32_t>(target_rva) - (static_cast<uint32_t>(loc_rva) + 4);
64*a03ca8b9SKrzysztof Kosiński image_.write<uint32_t>(ref.location, code);
65*a03ca8b9SKrzysztof Kosiński }
66*a03ca8b9SKrzysztof Kosiński
67*a03ca8b9SKrzysztof Kosiński } // namespace zucchini
68