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