//===- lib/ReaderWriter/MachO/TLVPass.cpp ---------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This linker pass transforms all TLV references to real references.
///
//===----------------------------------------------------------------------===//

#include "ArchHandler.h"
#include "File.h"
#include "MachOPasses.h"
#include "lld/Core/Simple.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"

namespace lld {
namespace mach_o {

//
// TLVP Entry Atom created by the TLV pass.
//
class TLVPEntryAtom : public SimpleDefinedAtom {
public:
  TLVPEntryAtom(const File &file, bool is64, StringRef name)
      : SimpleDefinedAtom(file), _is64(is64), _name(name) {}

  ContentType contentType() const override {
    return DefinedAtom::typeTLVInitializerPtr;
  }

  Alignment alignment() const override {
    return _is64 ? 8 : 4;
  }

  uint64_t size() const override {
    return _is64 ? 8 : 4;
  }

  ContentPermissions permissions() const override {
    return DefinedAtom::permRW_;
  }

  ArrayRef<uint8_t> rawContent() const override {
    static const uint8_t zeros[] =
      { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    return llvm::makeArrayRef(zeros, size());
  }

  StringRef slotName() const {
    return _name;
  }

private:
  const bool _is64;
  StringRef _name;
};

class TLVPass : public Pass {
public:
  TLVPass(const MachOLinkingContext &context)
      : _ctx(context), _archHandler(_ctx.archHandler()),
        _file("<mach-o TLV Pass>") {}

private:

  std::error_code perform(SimpleFile &mergedFile) override {

    bool allowTLV = _ctx.minOS("10.7", "1.0");

    for (const DefinedAtom *atom : mergedFile.defined()) {
      for (const Reference *ref : *atom) {
        if (!_archHandler.isTLVAccess(*ref))
          continue;

        if (!allowTLV)
          return make_dynamic_error_code(
            "targeted OS version does not support use of thread local "
            "variables in " + atom->name() + " for architecture " +
            _ctx.archName());

        const Atom *target = ref->target();
        assert(target != nullptr);

        const DefinedAtom *tlvpEntry = makeTLVPEntry(target);
        const_cast<Reference*>(ref)->setTarget(tlvpEntry);
        _archHandler.updateReferenceToTLV(ref);
      }
    }

    std::vector<const TLVPEntryAtom*> entries;
    entries.reserve(_targetToTLVP.size());
    for (auto &it : _targetToTLVP)
      entries.push_back(it.second);
    std::sort(entries.begin(), entries.end(),
              [](const TLVPEntryAtom *lhs, const TLVPEntryAtom *rhs) {
                return (lhs->slotName().compare(rhs->slotName()) < 0);
              });

    for (const TLVPEntryAtom *slot : entries)
      mergedFile.addAtom(*slot);

    return std::error_code();
  }

  const DefinedAtom *makeTLVPEntry(const Atom *target) {
    auto pos = _targetToTLVP.find(target);

    if (pos != _targetToTLVP.end())
      return pos->second;

    TLVPEntryAtom *tlvpEntry = new (_file.allocator())
      TLVPEntryAtom(_file, _ctx.is64Bit(), target->name());
    _targetToTLVP[target] = tlvpEntry;
    const ArchHandler::ReferenceInfo &nlInfo =
      _archHandler.stubInfo().nonLazyPointerReferenceToBinder;
    tlvpEntry->addReference(Reference::KindNamespace::mach_o, nlInfo.arch,
                            nlInfo.kind, 0, target, 0);
    return tlvpEntry;
  }

  const MachOLinkingContext &_ctx;
  mach_o::ArchHandler &_archHandler;
  MachOFile _file;
  llvm::DenseMap<const Atom*, const TLVPEntryAtom*> _targetToTLVP;
};

void addTLVPass(PassManager &pm, const MachOLinkingContext &ctx) {
  assert(ctx.needsTLVPass());
  pm.add(llvm::make_unique<TLVPass>(ctx));
}


} // end namesapce mach_o
} // end namesapce lld
