xref: /aosp_15_r20/external/zucchini/image_index.h (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 #ifndef COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_
6*a03ca8b9SKrzysztof Kosiński #define COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_
7*a03ca8b9SKrzysztof Kosiński 
8*a03ca8b9SKrzysztof Kosiński #include <stddef.h>
9*a03ca8b9SKrzysztof Kosiński #include <stdint.h>
10*a03ca8b9SKrzysztof Kosiński 
11*a03ca8b9SKrzysztof Kosiński #include <map>
12*a03ca8b9SKrzysztof Kosiński #include <vector>
13*a03ca8b9SKrzysztof Kosiński 
14*a03ca8b9SKrzysztof Kosiński #include "base/check_op.h"
15*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/buffer_view.h"
16*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/image_utils.h"
17*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/reference_set.h"
18*a03ca8b9SKrzysztof Kosiński #include "components/zucchini/target_pool.h"
19*a03ca8b9SKrzysztof Kosiński 
20*a03ca8b9SKrzysztof Kosiński namespace zucchini {
21*a03ca8b9SKrzysztof Kosiński 
22*a03ca8b9SKrzysztof Kosiński class Disassembler;
23*a03ca8b9SKrzysztof Kosiński 
24*a03ca8b9SKrzysztof Kosiński // A class that holds annotations of an image, allowing quick access to its raw
25*a03ca8b9SKrzysztof Kosiński // and reference content. The memory overhead of storing all references is
26*a03ca8b9SKrzysztof Kosiński // relatively high, so this is only used during patch generation.
27*a03ca8b9SKrzysztof Kosiński class ImageIndex {
28*a03ca8b9SKrzysztof Kosiński  public:
29*a03ca8b9SKrzysztof Kosiński   explicit ImageIndex(ConstBufferView image);
30*a03ca8b9SKrzysztof Kosiński   ImageIndex(const ImageIndex&) = delete;
31*a03ca8b9SKrzysztof Kosiński   ImageIndex(ImageIndex&&);
32*a03ca8b9SKrzysztof Kosiński   ~ImageIndex();
33*a03ca8b9SKrzysztof Kosiński 
34*a03ca8b9SKrzysztof Kosiński   // Inserts all references read from |disasm|. This should be called exactly
35*a03ca8b9SKrzysztof Kosiński   // once. If overlap between any two references of any type is encountered,
36*a03ca8b9SKrzysztof Kosiński   // returns false and leaves the object in an invalid state. Otherwise,
37*a03ca8b9SKrzysztof Kosiński   // returns true.
38*a03ca8b9SKrzysztof Kosiński   // TODO(huangs): Refactor ReaderFactory and WriterFactory so
39*a03ca8b9SKrzysztof Kosiński   // |const Disassembler&| can be used here.
40*a03ca8b9SKrzysztof Kosiński   bool Initialize(Disassembler* disasm);
41*a03ca8b9SKrzysztof Kosiński 
42*a03ca8b9SKrzysztof Kosiński   // Returns the array size needed to accommodate all reference type values.
TypeCount()43*a03ca8b9SKrzysztof Kosiński   size_t TypeCount() const {
44*a03ca8b9SKrzysztof Kosiński     if (reference_sets_.empty())
45*a03ca8b9SKrzysztof Kosiński       return 0U;
46*a03ca8b9SKrzysztof Kosiński     return reference_sets_.rbegin()->first.value() + 1;  // Max key + 1.
47*a03ca8b9SKrzysztof Kosiński   }
48*a03ca8b9SKrzysztof Kosiński 
49*a03ca8b9SKrzysztof Kosiński   // Returns the array size needed to accommodate all pool values.
PoolCount()50*a03ca8b9SKrzysztof Kosiński   size_t PoolCount() const {
51*a03ca8b9SKrzysztof Kosiński     if (target_pools_.empty())
52*a03ca8b9SKrzysztof Kosiński       return 0U;
53*a03ca8b9SKrzysztof Kosiński     return target_pools_.rbegin()->first.value() + 1;  // Max key + 1.
54*a03ca8b9SKrzysztof Kosiński   }
55*a03ca8b9SKrzysztof Kosiński 
56*a03ca8b9SKrzysztof Kosiński   // Returns true if |image_[location]| is either:
57*a03ca8b9SKrzysztof Kosiński   // - A raw value.
58*a03ca8b9SKrzysztof Kosiński   // - The first byte of a reference.
59*a03ca8b9SKrzysztof Kosiński   bool IsToken(offset_t location) const;
60*a03ca8b9SKrzysztof Kosiński 
61*a03ca8b9SKrzysztof Kosiński   // Returns true if |image_[location]| is part of a reference.
IsReference(offset_t location)62*a03ca8b9SKrzysztof Kosiński   bool IsReference(offset_t location) const {
63*a03ca8b9SKrzysztof Kosiński     return LookupType(location) != kNoTypeTag;
64*a03ca8b9SKrzysztof Kosiński   }
65*a03ca8b9SKrzysztof Kosiński 
66*a03ca8b9SKrzysztof Kosiński   // Returns the type tag of the reference covering |location|, or kNoTypeTag if
67*a03ca8b9SKrzysztof Kosiński   // |location| is not part of a reference.
LookupType(offset_t location)68*a03ca8b9SKrzysztof Kosiński   TypeTag LookupType(offset_t location) const {
69*a03ca8b9SKrzysztof Kosiński     DCHECK_LT(location, size());
70*a03ca8b9SKrzysztof Kosiński     return type_tags_[location];
71*a03ca8b9SKrzysztof Kosiński   }
72*a03ca8b9SKrzysztof Kosiński 
73*a03ca8b9SKrzysztof Kosiński   // Returns the raw value at |location|.
GetRawValue(offset_t location)74*a03ca8b9SKrzysztof Kosiński   uint8_t GetRawValue(offset_t location) const {
75*a03ca8b9SKrzysztof Kosiński     DCHECK_LT(location, size());
76*a03ca8b9SKrzysztof Kosiński     return image_[location];
77*a03ca8b9SKrzysztof Kosiński   }
78*a03ca8b9SKrzysztof Kosiński 
target_pools()79*a03ca8b9SKrzysztof Kosiński   const std::map<PoolTag, TargetPool>& target_pools() const {
80*a03ca8b9SKrzysztof Kosiński     return target_pools_;
81*a03ca8b9SKrzysztof Kosiński   }
reference_sets()82*a03ca8b9SKrzysztof Kosiński   const std::map<TypeTag, ReferenceSet>& reference_sets() const {
83*a03ca8b9SKrzysztof Kosiński     return reference_sets_;
84*a03ca8b9SKrzysztof Kosiński   }
85*a03ca8b9SKrzysztof Kosiński 
pool(PoolTag pool_tag)86*a03ca8b9SKrzysztof Kosiński   const TargetPool& pool(PoolTag pool_tag) const {
87*a03ca8b9SKrzysztof Kosiński     return target_pools_.at(pool_tag);
88*a03ca8b9SKrzysztof Kosiński   }
refs(TypeTag type_tag)89*a03ca8b9SKrzysztof Kosiński   const ReferenceSet& refs(TypeTag type_tag) const {
90*a03ca8b9SKrzysztof Kosiński     return reference_sets_.at(type_tag);
91*a03ca8b9SKrzysztof Kosiński   }
92*a03ca8b9SKrzysztof Kosiński 
93*a03ca8b9SKrzysztof Kosiński   // Returns the size of the image.
size()94*a03ca8b9SKrzysztof Kosiński   size_t size() const { return image_.size(); }
95*a03ca8b9SKrzysztof Kosiński 
96*a03ca8b9SKrzysztof Kosiński  private:
97*a03ca8b9SKrzysztof Kosiński   // Inserts to |*this| index, all references described by |traits| read from
98*a03ca8b9SKrzysztof Kosiński   // |ref_reader|, which gets consumed. This should be called exactly once for
99*a03ca8b9SKrzysztof Kosiński   // each reference type. If overlap between any two references of any type is
100*a03ca8b9SKrzysztof Kosiński   // encountered, returns false and leaves the object in an invalid state.
101*a03ca8b9SKrzysztof Kosiński   // Otherwise, returns true.
102*a03ca8b9SKrzysztof Kosiński   bool InsertReferences(const ReferenceTypeTraits& traits,
103*a03ca8b9SKrzysztof Kosiński                         ReferenceReader&& ref_reader);
104*a03ca8b9SKrzysztof Kosiński 
105*a03ca8b9SKrzysztof Kosiński   const ConstBufferView image_;
106*a03ca8b9SKrzysztof Kosiński 
107*a03ca8b9SKrzysztof Kosiński   // Used for random access lookup of reference type, for each byte in |image_|.
108*a03ca8b9SKrzysztof Kosiński   std::vector<TypeTag> type_tags_;
109*a03ca8b9SKrzysztof Kosiński 
110*a03ca8b9SKrzysztof Kosiński   std::map<PoolTag, TargetPool> target_pools_;
111*a03ca8b9SKrzysztof Kosiński   std::map<TypeTag, ReferenceSet> reference_sets_;
112*a03ca8b9SKrzysztof Kosiński };
113*a03ca8b9SKrzysztof Kosiński 
114*a03ca8b9SKrzysztof Kosiński }  // namespace zucchini
115*a03ca8b9SKrzysztof Kosiński 
116*a03ca8b9SKrzysztof Kosiński #endif  // COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_
117