#include "mem_map.h"

#include <sys/mman.h>

#include "utils.h"

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * 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.
 */

#include "mem_map.h"

#include <sys/mman.h>

namespace art {

size_t ParseHex(const std::string& string) {
  CHECK_EQ(8U, string.size());
  const char* str = string.c_str();
  char* end;
  size_t value = strtoul(str, &end, 16);
  CHECK(end != str) << "Failed to parse hexadecimal value from " << string;
  CHECK_EQ(*end, '\0') << "Failed to parse hexadecimal value from " << string;
  return value;
}

void CheckMapRequest(byte* addr, size_t length) {
#ifndef NDEBUG
  if (addr == NULL) {
    return;
  }
  size_t base = reinterpret_cast<size_t>(addr);
  size_t limit = base + length;

  std::string maps;
  bool read = ReadFileToString("/proc/self/maps", &maps);
  if (!read) {
    PLOG(FATAL) << "Failed to read /proc/self/maps";
  }
  // Quick and dirty parse of output like shown below. We only focus
  // on grabbing the two 32-bit hex values at the start of each line
  // and will fail on wider addresses found on 64-bit systems.

  // 00008000-0001f000 r-xp 00000000 b3:01 273        /system/bin/toolbox
  // 0001f000-00021000 rw-p 00017000 b3:01 273        /system/bin/toolbox
  // 00021000-00029000 rw-p 00000000 00:00 0          [heap]
  // 40011000-40053000 r-xp 00000000 b3:01 1050       /system/lib/libc.so
  // 40053000-40056000 rw-p 00042000 b3:01 1050       /system/lib/libc.so
  // 40056000-40061000 rw-p 00000000 00:00 0
  // 40061000-40063000 r-xp 00000000 b3:01 1107       /system/lib/libusbhost.so
  // 40063000-40064000 rw-p 00002000 b3:01 1107       /system/lib/libusbhost.so
  // 4009d000-400a0000 r-xp 00000000 b3:01 1022       /system/lib/liblog.so
  // 400a0000-400a1000 rw-p 00003000 b3:01 1022       /system/lib/liblog.so
  // 400b7000-400cc000 r-xp 00000000 b3:01 932        /system/lib/libm.so
  // 400cc000-400cd000 rw-p 00015000 b3:01 932        /system/lib/libm.so
  // 400cf000-400d0000 r--p 00000000 00:00 0
  // 400e4000-400ec000 r--s 00000000 00:0b 388        /dev/__properties__ (deleted)
  // 400ec000-400fa000 r-xp 00000000 b3:01 1101       /system/lib/libcutils.so
  // 400fa000-400fb000 rw-p 0000e000 b3:01 1101       /system/lib/libcutils.so
  // 400fb000-4010a000 rw-p 00000000 00:00 0
  // 4010d000-4010e000 r-xp 00000000 b3:01 929        /system/lib/libstdc++.so
  // 4010e000-4010f000 rw-p 00001000 b3:01 929        /system/lib/libstdc++.so
  // b0001000-b0009000 r-xp 00001000 b3:01 1098       /system/bin/linker
  // b0009000-b000a000 rw-p 00009000 b3:01 1098       /system/bin/linker
  // b000a000-b0015000 rw-p 00000000 00:00 0
  // bee35000-bee56000 rw-p 00000000 00:00 0          [stack]
  // ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]

  for (size_t i = 0; i < maps.size(); i++) {
    size_t remaining = maps.size() - i;
    if (remaining < 8+1+8) {  // 00008000-0001f000
      LOG(FATAL) << "Failed to parse at pos " << i << "\n" << maps;
    }
    std::string start_str = maps.substr(i, 8);
    std::string end_str = maps.substr(i+1+8, 8);
    uint32_t start = ParseHex(start_str);
    uint32_t end = ParseHex(end_str);
    CHECK(!(base >= start && base < end)       // start of new within old
          && !(limit > start && limit < end)  // end of new within old
          && !(base <= start && limit > end))  // start/end of new includes all of old
        << StringPrintf("Requested region %08x-%08x overlaps with existing map %08x-%08x\n",
                        base, limit, start, end)
        << maps;
    i += 8+1+8;
    i = maps.find('\n', i);
    CHECK(i != std::string::npos) << "Failed to find newline from pos " << i << "\n" << maps;
  }
#endif
}

MemMap* MemMap::Map(byte* addr, size_t length, int prot) {
  CHECK_NE(0U, length);
  CHECK_NE(0, prot);
  size_t page_aligned_size = RoundUp(length, kPageSize);
  CheckMapRequest(addr, page_aligned_size);
  byte* actual = reinterpret_cast<byte*>(mmap(addr,
                                              page_aligned_size,
                                              prot,
                                              MAP_PRIVATE | MAP_ANONYMOUS,
                                              -1,
                                              0));
  if (actual == MAP_FAILED) {
    PLOG(ERROR) << "mmap failed";
    return NULL;
  }
  return new MemMap(actual, length, actual, page_aligned_size);
}

MemMap* MemMap::Map(byte* addr, size_t length, int prot, int flags, int fd, off_t start) {
  CHECK_NE(0U, length);
  CHECK_NE(0, prot);
  CHECK_NE(0, flags & (MAP_SHARED | MAP_PRIVATE));
  // adjust to be page-aligned
  int page_offset = start % kPageSize;
  off_t page_aligned_offset = start - page_offset;
  size_t page_aligned_size = RoundUp(length + page_offset, kPageSize);
  CheckMapRequest(addr, page_aligned_size);
  byte* actual = reinterpret_cast<byte*>(mmap(addr,
                                              page_aligned_size,
                                              prot,
                                              flags,
                                              fd,
                                              page_aligned_offset));
  if (actual == MAP_FAILED) {
    PLOG(ERROR) << "mmap failed";
    return NULL;
  }
  return new MemMap(actual + page_offset, length, actual, page_aligned_size);
}

MemMap::~MemMap() {
  if (base_addr_ == NULL && base_length_ == 0) {
    return;
  }
  int result = munmap(base_addr_, base_length_);
  base_addr_ = NULL;
  base_length_ = 0;
  if (result == -1) {
    PLOG(FATAL) << "munmap failed";
  }
}

MemMap::MemMap(byte* addr, size_t length, void* base_addr, size_t base_length)
    : addr_(addr), length_(length), base_addr_(base_addr), base_length_(base_length) {
  CHECK(addr_ != NULL);
  CHECK_NE(length_, 0U);
  CHECK(base_addr_ != NULL);
  CHECK_NE(base_length_, 0U);
};

}  // namespace art
