/*
 * 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>

#include "ScopedFd.h"
#include "utils.h"

#define USE_ASHMEM 1

#ifdef USE_ASHMEM
#include <cutils/ashmem.h>
#endif

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) {
#if !defined(NDEBUG)
#if defined(__APPLE__)
  UNIMPLEMENTED(WARNING);
#else
  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
#endif
}

MemMap* MemMap::MapAnonymous(const char* name, 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);

#ifdef USE_ASHMEM
  ScopedFd fd(ashmem_create_region(name, page_aligned_size));
  int flags = MAP_PRIVATE;
  if (fd.get() == -1) {
    PLOG(ERROR) << "ashmem_create_region failed (" << name << ")";
    return NULL;
  }
#else
  ScopedFd fd(-1);
  int flags = MAP_PRIVATE | MAP_ANONYMOUS;
#endif

  byte* actual = reinterpret_cast<byte*>(mmap(addr, page_aligned_size, prot, flags, fd.get(), 0));
  if (actual == MAP_FAILED) {
    PLOG(ERROR) << "mmap failed (" << name << ")";
    return NULL;
  }
  return new MemMap(actual, length, actual, page_aligned_size);
}

MemMap* MemMap::MapFileAtAddress(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_begin_ == NULL && base_size_ == 0) {
    return;
  }
  int result = munmap(base_begin_, base_size_);
  if (result == -1) {
    PLOG(FATAL) << "munmap failed";
  }
}

MemMap::MemMap(byte* begin, size_t size, void* base_begin, size_t base_size)
    : begin_(begin), size_(size), base_begin_(base_begin), base_size_(base_size) {
  CHECK(begin_ != NULL);
  CHECK_NE(size_, 0U);
  CHECK(base_begin_ != NULL);
  CHECK_NE(base_size_, 0U);
};

}  // namespace art
