| Index: src/trusted/validator_mips/address_set.cc
|
| diff --git a/src/trusted/validator_mips/address_set.cc b/src/trusted/validator_mips/address_set.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fd89a8a92ba6686018363c3399ca58320268315b
|
| --- /dev/null
|
| +++ b/src/trusted/validator_mips/address_set.cc
|
| @@ -0,0 +1,114 @@
|
| +/*
|
| + * Copyright 2012 The Native Client Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style license that can
|
| + * be found in the LICENSE file.
|
| + * Copyright 2012, Google Inc.
|
| + */
|
| +
|
| +#include "native_client/src/trusted/validator_mips/address_set.h"
|
| +#include <assert.h>
|
| +#include <stdio.h>
|
| +#include <string.h>
|
| +
|
| +namespace nacl_mips_val {
|
| +
|
| +static const int kInstrAlignment = 4;
|
| +static const int kInstrSize = 4;
|
| +static const int kWordSize = 32;
|
| +static const int kInstrPerWord = 4 * kWordSize;
|
| +
|
| +#define UP_ALLIGN(x) (kInstrSize * ((x + kInstrSize - 1) / kInstrSize))
|
| +
|
| +AddressSet::AddressSet(uint32_t base, uint32_t size)
|
| + : base_(base), size_(size), end_(base + UP_ALLIGN(size) - kInstrSize),
|
| + bits_(new uint32_t[(end_ - base_) / kInstrPerWord + 1]) {
|
| + assert(((base % kInstrAlignment) == 0) && (size > 0));
|
| + memset(bits_, 0, sizeof(uint32_t) * ((end_ - base_) / kInstrPerWord + 1));
|
| +}
|
| +
|
| +AddressSet::~AddressSet() {
|
| + delete[] bits_;
|
| +}
|
| +
|
| +void AddressSet::Add(uint32_t address) {
|
| + if ((address - base_) < size_) {
|
| + uint32_t word_address = (address - base_) / sizeof(uint32_t);
|
| + bits_[word_address / kWordSize] |= 1 << (word_address % kWordSize);
|
| + }
|
| +}
|
| +
|
| +bool AddressSet::Contains(uint32_t address) const {
|
| + if ((address - base_) < size_) {
|
| + uint32_t word_address = (address - base_) / sizeof(uint32_t);
|
| +
|
| + return bits_[word_address / kWordSize] & (1 << (word_address % kWordSize));
|
| + } else {
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +AddressSet::Iterator AddressSet::Begin() const {
|
| + return Iterator(*this, 0, 0);
|
| +}
|
| +
|
| +AddressSet::Iterator AddressSet::End() const {
|
| + uint32_t end_index = (end_ - base_) / kInstrPerWord;
|
| + uint32_t end_shift = ((end_ - base_) / kInstrSize) % kWordSize;
|
| + return Iterator(*this, end_index, end_shift);
|
| +}
|
| +
|
| +AddressSet::Iterator::Iterator(const AddressSet &parent,
|
| + uint32_t index,
|
| + uint32_t shift)
|
| + : parent_(parent), index_(index), shift_(shift) {
|
| + Advance();
|
| +}
|
| +
|
| +AddressSet::Iterator &AddressSet::Iterator::Next() {
|
| + shift_++; // Skip the current bit, if any, and
|
| + Advance(); // seek to the next 1 bit.
|
| + return *this;
|
| +}
|
| +
|
| +bool AddressSet::Iterator::Equals(const AddressSet::Iterator &other) const {
|
| + return index_ == other.index_ && shift_ == other.shift_;
|
| +}
|
| +
|
| +uint32_t AddressSet::Iterator::GetAddress() const {
|
| + return parent_.base_ + kInstrSize * ((index_ * kWordSize) + shift_);
|
| +}
|
| +
|
| +void AddressSet::Iterator::Advance() {
|
| + uint32_t max_index = (parent_.size_ / kInstrPerWord) + 1;
|
| +
|
| + for (; index_ < max_index; index_++) {
|
| + uint32_t word = (shift_ > 31) ? 0 : parent_.bits_[index_] >> shift_;
|
| + while (word) {
|
| + if (word & 1) return;
|
| +
|
| + // A meager optimization for sparse words. Check if the first 16 slots are
|
| + // empty, and if they are, skip them. Repeat the same check for 8 slots.
|
| + // Otherwise, we will check bit by bit, to reach the next valid one.
|
| + if (!(word & 0xFFFF)) {
|
| + word >>= 16;
|
| + shift_ += 16;
|
| + } else if (!(word & 0xFF)) {
|
| + word >>= 8;
|
| + shift_ += 8;
|
| + } else {
|
| + word >>= 1;
|
| + shift_++;
|
| + }
|
| + }
|
| + shift_ = 0;
|
| + }
|
| +
|
| + // If we have moved too far, we should limit the address to
|
| + // the last valid address.
|
| + if (index_ == max_index) {
|
| + index_ = (parent_.end_ - parent_.base_) / kInstrPerWord;
|
| + shift_ = ((parent_.end_ - parent_.base_) / kInstrSize) % kWordSize;
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
|
|