117 lines
3.7 KiB
C++
117 lines
3.7 KiB
C++
// Copyright 2017 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_
|
|
#define COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
#include "base/check_op.h"
|
|
#include "components/zucchini/buffer_view.h"
|
|
#include "components/zucchini/image_utils.h"
|
|
#include "components/zucchini/reference_set.h"
|
|
#include "components/zucchini/target_pool.h"
|
|
|
|
namespace zucchini {
|
|
|
|
class Disassembler;
|
|
|
|
// A class that holds annotations of an image, allowing quick access to its raw
|
|
// and reference content. The memory overhead of storing all references is
|
|
// relatively high, so this is only used during patch generation.
|
|
class ImageIndex {
|
|
public:
|
|
explicit ImageIndex(ConstBufferView image);
|
|
ImageIndex(const ImageIndex&) = delete;
|
|
ImageIndex(ImageIndex&&);
|
|
~ImageIndex();
|
|
|
|
// Inserts all references read from |disasm|. This should be called exactly
|
|
// once. If overlap between any two references of any type is encountered,
|
|
// returns false and leaves the object in an invalid state. Otherwise,
|
|
// returns true.
|
|
// TODO(huangs): Refactor ReaderFactory and WriterFactory so
|
|
// |const Disassembler&| can be used here.
|
|
bool Initialize(Disassembler* disasm);
|
|
|
|
// Returns the array size needed to accommodate all reference type values.
|
|
size_t TypeCount() const {
|
|
if (reference_sets_.empty())
|
|
return 0U;
|
|
return reference_sets_.rbegin()->first.value() + 1; // Max key + 1.
|
|
}
|
|
|
|
// Returns the array size needed to accommodate all pool values.
|
|
size_t PoolCount() const {
|
|
if (target_pools_.empty())
|
|
return 0U;
|
|
return target_pools_.rbegin()->first.value() + 1; // Max key + 1.
|
|
}
|
|
|
|
// Returns true if |image_[location]| is either:
|
|
// - A raw value.
|
|
// - The first byte of a reference.
|
|
bool IsToken(offset_t location) const;
|
|
|
|
// Returns true if |image_[location]| is part of a reference.
|
|
bool IsReference(offset_t location) const {
|
|
return LookupType(location) != kNoTypeTag;
|
|
}
|
|
|
|
// Returns the type tag of the reference covering |location|, or kNoTypeTag if
|
|
// |location| is not part of a reference.
|
|
TypeTag LookupType(offset_t location) const {
|
|
DCHECK_LT(location, size());
|
|
return type_tags_[location];
|
|
}
|
|
|
|
// Returns the raw value at |location|.
|
|
uint8_t GetRawValue(offset_t location) const {
|
|
DCHECK_LT(location, size());
|
|
return image_[location];
|
|
}
|
|
|
|
const std::map<PoolTag, TargetPool>& target_pools() const {
|
|
return target_pools_;
|
|
}
|
|
const std::map<TypeTag, ReferenceSet>& reference_sets() const {
|
|
return reference_sets_;
|
|
}
|
|
|
|
const TargetPool& pool(PoolTag pool_tag) const {
|
|
return target_pools_.at(pool_tag);
|
|
}
|
|
const ReferenceSet& refs(TypeTag type_tag) const {
|
|
return reference_sets_.at(type_tag);
|
|
}
|
|
|
|
// Returns the size of the image.
|
|
size_t size() const { return image_.size(); }
|
|
|
|
private:
|
|
// Inserts to |*this| index, all references described by |traits| read from
|
|
// |ref_reader|, which gets consumed. This should be called exactly once for
|
|
// each reference type. If overlap between any two references of any type is
|
|
// encountered, returns false and leaves the object in an invalid state.
|
|
// Otherwise, returns true.
|
|
bool InsertReferences(const ReferenceTypeTraits& traits,
|
|
ReferenceReader&& ref_reader);
|
|
|
|
const ConstBufferView image_;
|
|
|
|
// Used for random access lookup of reference type, for each byte in |image_|.
|
|
std::vector<TypeTag> type_tags_;
|
|
|
|
std::map<PoolTag, TargetPool> target_pools_;
|
|
std::map<TypeTag, ReferenceSet> reference_sets_;
|
|
};
|
|
|
|
} // namespace zucchini
|
|
|
|
#endif // COMPONENTS_ZUCCHINI_IMAGE_INDEX_H_
|