//===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCLabel.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ELF.h"
using namespace llvm;

typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
typedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;


MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri,
                     const MCObjectFileInfo *mofi) :
  MAI(mai), MRI(mri), MOFI(mofi),
  Allocator(), Symbols(Allocator), UsedNames(Allocator),
  NextUniqueID(0),
  CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
  AllowTemporaryLabels(true) {
  MachOUniquingMap = 0;
  ELFUniquingMap = 0;
  COFFUniquingMap = 0;

  SecureLogFile = getenv("AS_SECURE_LOG_FILE");
  SecureLog = 0;
  SecureLogUsed = false;

  DwarfLocSeen = false;
}

MCContext::~MCContext() {
  // NOTE: The symbols are all allocated out of a bump pointer allocator,
  // we don't need to free them here.

  // If we have the MachO uniquing map, free it.
  delete (MachOUniqueMapTy*)MachOUniquingMap;
  delete (ELFUniqueMapTy*)ELFUniquingMap;
  delete (COFFUniqueMapTy*)COFFUniquingMap;

  // If the stream for the .secure_log_unique directive was created free it.
  delete (raw_ostream*)SecureLog;
}

//===----------------------------------------------------------------------===//
// Symbol Manipulation
//===----------------------------------------------------------------------===//

MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
  assert(!Name.empty() && "Normal symbols cannot be unnamed!");

  // Do the lookup and get the entire StringMapEntry.  We want access to the
  // key if we are creating the entry.
  StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
  MCSymbol *Sym = Entry.getValue();

  if (Sym)
    return Sym;

  Sym = CreateSymbol(Name);
  Entry.setValue(Sym);
  return Sym;
}

MCSymbol *MCContext::CreateSymbol(StringRef Name) {
  // Determine whether this is an assembler temporary or normal label, if used.
  bool isTemporary = false;
  if (AllowTemporaryLabels)
    isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());

  StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
  if (NameEntry->getValue()) {
    assert(isTemporary && "Cannot rename non temporary symbols");
    SmallString<128> NewName = Name;
    do {
      NewName.resize(Name.size());
      raw_svector_ostream(NewName) << NextUniqueID++;
      NameEntry = &UsedNames.GetOrCreateValue(NewName);
    } while (NameEntry->getValue());
  }
  NameEntry->setValue(true);

  // Ok, the entry doesn't already exist.  Have the MCSymbol object itself refer
  // to the copy of the string that is embedded in the UsedNames entry.
  MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary);

  return Result;
}

MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
  SmallString<128> NameSV;
  Name.toVector(NameSV);
  return GetOrCreateSymbol(NameSV.str());
}

MCSymbol *MCContext::CreateTempSymbol() {
  SmallString<128> NameSV;
  raw_svector_ostream(NameSV)
    << MAI.getPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
  return CreateSymbol(NameSV);
}

unsigned MCContext::NextInstance(int64_t LocalLabelVal) {
  MCLabel *&Label = Instances[LocalLabelVal];
  if (!Label)
    Label = new (*this) MCLabel(0);
  return Label->incInstance();
}

unsigned MCContext::GetInstance(int64_t LocalLabelVal) {
  MCLabel *&Label = Instances[LocalLabelVal];
  if (!Label)
    Label = new (*this) MCLabel(0);
  return Label->getInstance();
}

MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
                           Twine(LocalLabelVal) +
                           "\2" +
                           Twine(NextInstance(LocalLabelVal)));
}
MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
                                               int bORf) {
  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
                           Twine(LocalLabelVal) +
                           "\2" +
                           Twine(GetInstance(LocalLabelVal) + bORf));
}

MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
  return Symbols.lookup(Name);
}

//===----------------------------------------------------------------------===//
// Section Management
//===----------------------------------------------------------------------===//

const MCSectionMachO *MCContext::
getMachOSection(StringRef Segment, StringRef Section,
                unsigned TypeAndAttributes,
                unsigned Reserved2, SectionKind Kind) {

  // We unique sections by their segment/section pair.  The returned section
  // may not have the same flags as the requested section, if so this should be
  // diagnosed by the client as an error.

  // Create the map if it doesn't already exist.
  if (MachOUniquingMap == 0)
    MachOUniquingMap = new MachOUniqueMapTy();
  MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;

  // Form the name to look up.
  SmallString<64> Name;
  Name += Segment;
  Name.push_back(',');
  Name += Section;

  // Do the lookup, if we have a hit, return it.
  const MCSectionMachO *&Entry = Map[Name.str()];
  if (Entry) return Entry;

  // Otherwise, return a new section.
  return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
                                            Reserved2, Kind);
}

const MCSectionELF *MCContext::
getELFSection(StringRef Section, unsigned Type, unsigned Flags,
              SectionKind Kind) {
  return getELFSection(Section, Type, Flags, Kind, 0, "");
}

const MCSectionELF *MCContext::
getELFSection(StringRef Section, unsigned Type, unsigned Flags,
              SectionKind Kind, unsigned EntrySize, StringRef Group) {
  if (ELFUniquingMap == 0)
    ELFUniquingMap = new ELFUniqueMapTy();
  ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;

  // Do the lookup, if we have a hit, return it.
  StringMapEntry<const MCSectionELF*> &Entry = Map.GetOrCreateValue(Section);
  if (Entry.getValue()) return Entry.getValue();

  // Possibly refine the entry size first.
  if (!EntrySize) {
    EntrySize = MCSectionELF::DetermineEntrySize(Kind);
  }

  MCSymbol *GroupSym = NULL;
  if (!Group.empty())
    GroupSym = GetOrCreateSymbol(Group);

  MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags,
                                                  Kind, EntrySize, GroupSym);
  Entry.setValue(Result);
  return Result;
}

const MCSectionELF *MCContext::CreateELFGroupSection() {
  MCSectionELF *Result =
    new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0,
                             SectionKind::getReadOnly(), 4, NULL);
  return Result;
}

const MCSection *MCContext::getCOFFSection(StringRef Section,
                                           unsigned Characteristics,
                                           int Selection,
                                           SectionKind Kind) {
  if (COFFUniquingMap == 0)
    COFFUniquingMap = new COFFUniqueMapTy();
  COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;

  // Do the lookup, if we have a hit, return it.
  StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
  if (Entry.getValue()) return Entry.getValue();

  MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
                                                    Characteristics,
                                                    Selection, Kind);

  Entry.setValue(Result);
  return Result;
}

//===----------------------------------------------------------------------===//
// Dwarf Management
//===----------------------------------------------------------------------===//

/// GetDwarfFile - takes a file name an number to place in the dwarf file and
/// directory tables.  If the file number has already been allocated it is an
/// error and zero is returned and the client reports the error, else the
/// allocated file number is returned.  The file numbers may be in any order.
unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) {
  // TODO: a FileNumber of zero says to use the next available file number.
  // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
  // to not be less than one.  This needs to be change to be not less than zero.

  // Make space for this FileNumber in the MCDwarfFiles vector if needed.
  if (FileNumber >= MCDwarfFiles.size()) {
    MCDwarfFiles.resize(FileNumber + 1);
  } else {
    MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber];
    if (ExistingFile)
      // It is an error to use see the same number more than once.
      return 0;
  }

  // Get the new MCDwarfFile slot for this FileNumber.
  MCDwarfFile *&File = MCDwarfFiles[FileNumber];

  // Separate the directory part from the basename of the FileName.
  std::pair<StringRef, StringRef> Slash = FileName.rsplit('/');

  // Find or make a entry in the MCDwarfDirs vector for this Directory.
  StringRef Name;
  unsigned DirIndex;
  // Capture directory name.
  if (Slash.second.empty()) {
    Name = Slash.first;
    DirIndex = 0; // For FileNames with no directories a DirIndex of 0 is used.
  } else {
    StringRef Directory = Slash.first;
    Name = Slash.second;
    DirIndex = 0;
    for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
      if (Directory == MCDwarfDirs[DirIndex])
        break;
    }
    if (DirIndex >= MCDwarfDirs.size()) {
      char *Buf = static_cast<char *>(Allocate(Directory.size()));
      memcpy(Buf, Directory.data(), Directory.size());
      MCDwarfDirs.push_back(StringRef(Buf, Directory.size()));
    }
    // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
    // no directories.  MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
    // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames are
    // stored at MCDwarfFiles[FileNumber].Name .
    DirIndex++;
  }

  // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles
  // vector.
  char *Buf = static_cast<char *>(Allocate(Name.size()));
  memcpy(Buf, Name.data(), Name.size());
  File = new (*this) MCDwarfFile(StringRef(Buf, Name.size()), DirIndex);

  // return the allocated FileNumber.
  return FileNumber;
}

/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
/// currently is assigned and false otherwise.
bool MCContext::isValidDwarfFileNumber(unsigned FileNumber) {
  if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
    return false;

  return MCDwarfFiles[FileNumber] != 0;
}
