#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(*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)
          && !(limit >= start && limit < end)
          && !(base <= start && limit > end))
        << 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(length_ != 0);
  CHECK(base_addr_ != NULL);
  CHECK(base_length_ != 0);
};

}  // namespace art
