xref: /aosp_15_r20/external/zucchini/rel32_utils.cc (revision a03ca8b91e029cd15055c20c78c2e087c84792e4)
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