// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/profiler/module_cache.h"

#include <dlfcn.h>
#include <mach-o/getsect.h>
#include <string.h>
#include <uuid/uuid.h>

#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"

namespace base {

namespace {

#if defined(ARCH_CPU_64_BITS)
using MachHeaderType = mach_header_64;
using SegmentCommandType = segment_command_64;
constexpr uint32_t kMachHeaderMagic = MH_MAGIC_64;
constexpr uint32_t kSegmentCommand = LC_SEGMENT_64;
#else
using MachHeaderType = mach_header;
using SegmentCommandType = segment_command;
constexpr uint32_t kMachHeaderMagic = MH_MAGIC;
constexpr uint32_t kSegmentCommand = LC_SEGMENT;
#endif

// Returns the unique build ID and text segment size for a module loaded at
// |module_addr|. Returns the empty string and 0 if the function fails to get
// the build ID or size.
//
// Build IDs are created by the concatenation of the module's GUID (Windows) /
// UUID (Mac) and an "age" field that indicates how many times that GUID/UUID
// has been reused. In Windows binaries, the "age" field is present in the
// module header, but on the Mac, UUIDs are never reused and so the "age" value
// appended to the UUID is always 0.
void GetUniqueIdAndTextSize(const void* module_addr,
                            std::string* unique_id,
                            size_t* text_size) {
  const MachHeaderType* mach_header =
      reinterpret_cast<const MachHeaderType*>(module_addr);
  DCHECK_EQ(mach_header->magic, kMachHeaderMagic);

  size_t offset = sizeof(MachHeaderType);
  size_t offset_limit = sizeof(MachHeaderType) + mach_header->sizeofcmds;
  bool found_uuid = false;
  bool found_text_size = false;

  for (uint32_t i = 0; i < mach_header->ncmds; ++i) {
    if (offset + sizeof(load_command) >= offset_limit) {
      unique_id->clear();
      *text_size = 0;
      return;
    }

    const load_command* load_cmd = reinterpret_cast<const load_command*>(
        reinterpret_cast<const uint8_t*>(mach_header) + offset);

    if (offset + load_cmd->cmdsize > offset_limit) {
      // This command runs off the end of the command list. This is malformed.
      unique_id->clear();
      *text_size = 0;
      return;
    }

    if (load_cmd->cmd == LC_UUID) {
      if (load_cmd->cmdsize < sizeof(uuid_command)) {
        // This "UUID command" is too small. This is malformed.
        unique_id->clear();
      } else {
        const uuid_command* uuid_cmd =
            reinterpret_cast<const uuid_command*>(load_cmd);
        static_assert(sizeof(uuid_cmd->uuid) == sizeof(uuid_t),
                      "UUID field of UUID command should be 16 bytes.");
        // The ID comprises the UUID concatenated with the Mac's "age" value
        // which is always 0.
        unique_id->assign(HexEncode(&uuid_cmd->uuid, sizeof(uuid_cmd->uuid)) +
                          "0");
      }
      if (found_text_size)
        return;
      found_uuid = true;
    } else if (load_cmd->cmd == kSegmentCommand) {
      const SegmentCommandType* segment_cmd =
          reinterpret_cast<const SegmentCommandType*>(load_cmd);
      if (strncmp(segment_cmd->segname, SEG_TEXT,
                  sizeof(segment_cmd->segname)) == 0) {
        *text_size = segment_cmd->vmsize;
        // Compare result with library function call, which is slower than this
        // code.
        unsigned long text_size_from_libmacho;
        DCHECK(getsegmentdata(mach_header, SEG_TEXT, &text_size_from_libmacho));
        DCHECK_EQ(*text_size, text_size_from_libmacho);
      }
      if (found_uuid)
        return;
      found_text_size = true;
    }
    offset += load_cmd->cmdsize;
  }

  if (!found_uuid) {
    unique_id->clear();
  }
  if (!found_text_size) {
    *text_size = 0;
  }
}

}  // namespace

class MacModule : public ModuleCache::Module {
 public:
  MacModule(const Dl_info& dl_info)
      : base_address_(reinterpret_cast<uintptr_t>(dl_info.dli_fbase)),
        debug_basename_(FilePath(dl_info.dli_fname).BaseName()) {
    GetUniqueIdAndTextSize(dl_info.dli_fbase, &id_, &size_);
  }

  MacModule(const MacModule&) = delete;
  MacModule& operator=(const MacModule&) = delete;

  // ModuleCache::Module
  uintptr_t GetBaseAddress() const override { return base_address_; }
  std::string GetId() const override { return id_; }
  FilePath GetDebugBasename() const override { return debug_basename_; }
  size_t GetSize() const override { return size_; }
  bool IsNative() const override { return true; }

 private:
  uintptr_t base_address_;
  std::string id_;
  FilePath debug_basename_;
  size_t size_;
};

// static
std::unique_ptr<const ModuleCache::Module> ModuleCache::CreateModuleForAddress(
    uintptr_t address) {
  Dl_info info;
  if (!dladdr(reinterpret_cast<const void*>(address), &info))
    return nullptr;
  return std::make_unique<MacModule>(info);
}

}  // namespace base
