<commit_before>/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Instruments code to check for incorrect heap access. This checks
// for dereferencing 0 (null pointer access), reading past the valid
// top of sbrk()-addressible memory, and incorrect alignment notation.
//

#include "asmjs/shared-constants.h"
#include "ir/bits.h"
#include "ir/import-utils.h"
#include "ir/load-utils.h"
#include "pass.h"
#include "wasm-builder.h"
#include "wasm.h"

namespace wasm {

static const Name GET_SBRK_PTR("emscripten_get_sbrk_ptr");
static const Name SBRK("sbrk");
static const Name SEGFAULT_IMPORT("segfault");
static const Name ALIGNFAULT_IMPORT("alignfault");

static Name getLoadName(Load* curr) {
  std::string ret = "SAFE_HEAP_LOAD_";
  ret += curr->type.toString();
  ret += "_" + std::to_string(curr->bytes) + "_";
  if (LoadUtils::isSignRelevant(curr) && !curr->signed_) {
    ret += "U_";
  }
  if (curr->isAtomic) {
    ret += "A";
  } else {
    ret += std::to_string(curr->align);
  }
  return ret;
}

static Name getStoreName(Store* curr) {
  std::string ret = "SAFE_HEAP_STORE_";
  ret += curr->valueType.toString();
  ret += "_" + std::to_string(curr->bytes) + "_";
  if (curr->isAtomic) {
    ret += "A";
  } else {
    ret += std::to_string(curr->align);
  }
  return ret;
}

struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> {
  // If the getSbrkPtr function is implemented in the wasm, we must not
  // instrument that, as it would lead to infinite recursion of it calling
  // SAFE_HEAP_LOAD that calls it and so forth.
  // As well as the getSbrkPtr function we also avoid instrumenting the
  // module start function.  This is because this function is used in
  // shared memory builds to load the passive memory segments, which in
  // turn means that value of sbrk() is not available.
  Name getSbrkPtr;

  bool isFunctionParallel() override { return true; }

  AccessInstrumenter* create() override {
    return new AccessInstrumenter(getSbrkPtr);
  }

  AccessInstrumenter(Name getSbrkPtr) : getSbrkPtr(getSbrkPtr) {}

  void visitLoad(Load* curr) {
    if (getFunction()->name == getModule()->start ||
        getFunction()->name == getSbrkPtr || curr->type == Type::unreachable) {
      return;
    }
    Builder builder(*getModule());<commit_msg>Add comment a followup to #3424. NFC. (#3449)<commit_after>/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Instruments code to check for incorrect heap access. This checks
// for dereferencing 0 (null pointer access), reading past the valid
// top of sbrk()-addressible memory, and incorrect alignment notation.
//

#include "asmjs/shared-constants.h"
#include "ir/bits.h"
#include "ir/import-utils.h"
#include "ir/load-utils.h"
#include "pass.h"
#include "wasm-builder.h"
#include "wasm.h"

namespace wasm {

static const Name GET_SBRK_PTR("emscripten_get_sbrk_ptr");
static const Name SBRK("sbrk");
static const Name SEGFAULT_IMPORT("segfault");
static const Name ALIGNFAULT_IMPORT("alignfault");

static Name getLoadName(Load* curr) {
  std::string ret = "SAFE_HEAP_LOAD_";
  ret += curr->type.toString();
  ret += "_" + std::to_string(curr->bytes) + "_";
  if (LoadUtils::isSignRelevant(curr) && !curr->signed_) {
    ret += "U_";
  }
  if (curr->isAtomic) {
    ret += "A";
  } else {
    ret += std::to_string(curr->align);
  }
  return ret;
}

static Name getStoreName(Store* curr) {
  std::string ret = "SAFE_HEAP_STORE_";
  ret += curr->valueType.toString();
  ret += "_" + std::to_string(curr->bytes) + "_";
  if (curr->isAtomic) {
    ret += "A";
  } else {
    ret += std::to_string(curr->align);
  }
  return ret;
}

struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> {
  // If the getSbrkPtr function is implemented in the wasm, we must not
  // instrument that, as it would lead to infinite recursion of it calling
  // SAFE_HEAP_LOAD that calls it and so forth.
  // As well as the getSbrkPtr function we also avoid instrumenting the
  // module start function.  This is because this function is used in
  // shared memory builds to load the passive memory segments, which in
  // turn means that value of sbrk() is not available.
  Name getSbrkPtr;

  bool isFunctionParallel() override { return true; }

  AccessInstrumenter* create() override {
    return new AccessInstrumenter(getSbrkPtr);
  }

  AccessInstrumenter(Name getSbrkPtr) : getSbrkPtr(getSbrkPtr) {}

  void visitLoad(Load* curr) {
    // As well as the getSbrkPtr function we also avoid insturmenting the
    // module start function.  This is because this function is used in
    // shared memory builds to load the passive memory segments, which in
    // turn means that value of sbrk() is not available.
    if (getFunction()->name == getModule()->start ||
        getFunction()->name == getSbrkPtr || curr->type == Type::unreachable) {
      return;
    }
    Builder builder(*getModule());
{'fraction_non_alphanumeric': 0.11587275424427229, 'fraction_numerical': 0.004285478819845063, 'mean_word_length': 3.850519584332534, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5865724', 'n_tokens_mistral': 1884, 'n_tokens_neox': 1864, 'n_words': 640}