1ba1da8a7b10b8a7df04f3ca47ca36ad18adad80eDaniel Dunbar//===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
2ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar//
3ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar//                     The LLVM Compiler Infrastructure
4ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar//
5ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar// This file is distributed under the University of Illinois Open Source
6ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar// License. See LICENSE.TXT for details.
7ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar//
8ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar//===----------------------------------------------------------------------===//
9ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar
10ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar#include "llvm/MC/MCContext.h"
111a5c28f4715d84d0302581a67e193d7a358bba17Chris Lattner#include "llvm/MC/MCAsmInfo.h"
12e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng#include "llvm/MC/MCObjectFileInfo.h"
130e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#include "llvm/MC/MCRegisterInfo.h"
14f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner#include "llvm/MC/MCSectionMachO.h"
1574aae4726a66733c5872588287535a984f9a94c7Chris Lattner#include "llvm/MC/MCSectionELF.h"
16eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner#include "llvm/MC/MCSectionCOFF.h"
17ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar#include "llvm/MC/MCSymbol.h"
18ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby#include "llvm/MC/MCLabel.h"
197cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby#include "llvm/MC/MCDwarf.h"
207c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner#include "llvm/ADT/SmallString.h"
217c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner#include "llvm/ADT/Twine.h"
22c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola#include "llvm/Support/ELF.h"
2382f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach#include "llvm/Support/ErrorHandling.h"
2482f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach#include "llvm/Support/SourceMgr.h"
2582f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach#include "llvm/Support/Signals.h"
26ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbarusing namespace llvm;
27ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar
28f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattnertypedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
2974aae4726a66733c5872588287535a984f9a94c7Chris Lattnertypedef StringMap<const MCSectionELF*> ELFUniqueMapTy;
30eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattnertypedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
31f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner
32f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner
330e6a052331f674dd70e28af41f654a7874405eabEvan ChengMCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri,
343662e5ce709814f6b7cb3871be71ebc5e1ada16fJim Grosbach                     const MCObjectFileInfo *mofi, const SourceMgr *mgr) :
353662e5ce709814f6b7cb3871be71ebc5e1ada16fJim Grosbach  SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi),
36f4387d9afb9100e181b96b3bca879b940715033dEli Friedman  Allocator(), Symbols(Allocator), UsedNames(Allocator),
37f4387d9afb9100e181b96b3bca879b940715033dEli Friedman  NextUniqueID(0),
38c6cf43d25853efb4a6765954eda52a45998a47f2Daniel Dunbar  CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
39c6cf43d25853efb4a6765954eda52a45998a47f2Daniel Dunbar  AllowTemporaryLabels(true) {
40f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  MachOUniquingMap = 0;
4174aae4726a66733c5872588287535a984f9a94c7Chris Lattner  ELFUniquingMap = 0;
42eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  COFFUniquingMap = 0;
43f187ac5a23213f85c3c1f0f80b3592295ee6441dKevin Enderby
44f187ac5a23213f85c3c1f0f80b3592295ee6441dKevin Enderby  SecureLogFile = getenv("AS_SECURE_LOG_FILE");
45f187ac5a23213f85c3c1f0f80b3592295ee6441dKevin Enderby  SecureLog = 0;
46f187ac5a23213f85c3c1f0f80b3592295ee6441dKevin Enderby  SecureLogUsed = false;
47c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
48c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby  DwarfLocSeen = false;
49613b7576896fbd03fe495f4ee27b404f81386774Kevin Enderby  GenDwarfForAssembly = false;
50613b7576896fbd03fe495f4ee27b404f81386774Kevin Enderby  GenDwarfFileNumber = 0;
51ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar}
52ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar
53ecc63f8687c4eb746b69336316685fe9b224adfbDaniel DunbarMCContext::~MCContext() {
54f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // NOTE: The symbols are all allocated out of a bump pointer allocator,
55c9d31524eec562f719d6818508b722b55a787d67Chris Lattner  // we don't need to free them here.
56326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
57f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // If we have the MachO uniquing map, free it.
58f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  delete (MachOUniqueMapTy*)MachOUniquingMap;
5974aae4726a66733c5872588287535a984f9a94c7Chris Lattner  delete (ELFUniqueMapTy*)ELFUniquingMap;
60eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  delete (COFFUniqueMapTy*)COFFUniquingMap;
61f187ac5a23213f85c3c1f0f80b3592295ee6441dKevin Enderby
62f187ac5a23213f85c3c1f0f80b3592295ee6441dKevin Enderby  // If the stream for the .secure_log_unique directive was created free it.
63f187ac5a23213f85c3c1f0f80b3592295ee6441dKevin Enderby  delete (raw_ostream*)SecureLog;
64ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar}
65ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar
66f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner//===----------------------------------------------------------------------===//
67f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner// Symbol Manipulation
68f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner//===----------------------------------------------------------------------===//
69f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner
709b97a73dedf736e14b04a3d1a153f10d25b2507bChris LattnerMCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) {
7100685bb5cf791fcda9fa0ceb42a6a62a07478461Chris Lattner  assert(!Name.empty() && "Normal symbols cannot be unnamed!");
72326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
73c28cc093e3b5b8601cb5024a5365a6f31f49839aChris Lattner  // Do the lookup and get the entire StringMapEntry.  We want access to the
74c28cc093e3b5b8601cb5024a5365a6f31f49839aChris Lattner  // key if we are creating the entry.
75c28cc093e3b5b8601cb5024a5365a6f31f49839aChris Lattner  StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name);
769f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  MCSymbol *Sym = Entry.getValue();
779f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola
789f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  if (Sym)
799f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola    return Sym;
809f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola
819f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  Sym = CreateSymbol(Name);
829f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  Entry.setValue(Sym);
839f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  return Sym;
849f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola}
859f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola
869f44724be058d17944dcd9ef6a6b57734b3744b8Rafael EspindolaMCSymbol *MCContext::CreateSymbol(StringRef Name) {
87c6cf43d25853efb4a6765954eda52a45998a47f2Daniel Dunbar  // Determine whether this is an assembler temporary or normal label, if used.
88c6cf43d25853efb4a6765954eda52a45998a47f2Daniel Dunbar  bool isTemporary = false;
89c6cf43d25853efb4a6765954eda52a45998a47f2Daniel Dunbar  if (AllowTemporaryLabels)
90c6cf43d25853efb4a6765954eda52a45998a47f2Daniel Dunbar    isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix());
919f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola
929f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name);
939f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  if (NameEntry->getValue()) {
949f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola    assert(isTemporary && "Cannot rename non temporary symbols");
95c18214a6e0a22ffa6886c70dbd6176ac9e91c847Benjamin Kramer    SmallString<128> NewName = Name;
969f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola    do {
97c18214a6e0a22ffa6886c70dbd6176ac9e91c847Benjamin Kramer      NewName.resize(Name.size());
98c18214a6e0a22ffa6886c70dbd6176ac9e91c847Benjamin Kramer      raw_svector_ostream(NewName) << NextUniqueID++;
99c18214a6e0a22ffa6886c70dbd6176ac9e91c847Benjamin Kramer      NameEntry = &UsedNames.GetOrCreateValue(NewName);
1009f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola    } while (NameEntry->getValue());
1019f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  }
1029f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  NameEntry->setValue(true);
103c69485e34d57e17fe2c3acab64e519d6a6945197Chris Lattner
104c28cc093e3b5b8601cb5024a5365a6f31f49839aChris Lattner  // Ok, the entry doesn't already exist.  Have the MCSymbol object itself refer
1059f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  // to the copy of the string that is embedded in the UsedNames entry.
1069f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary);
1079f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola
1089f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  return Result;
109c69485e34d57e17fe2c3acab64e519d6a6945197Chris Lattner}
110c69485e34d57e17fe2c3acab64e519d6a6945197Chris Lattner
1119b97a73dedf736e14b04a3d1a153f10d25b2507bChris LattnerMCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
1127c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner  SmallString<128> NameSV;
1137c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner  Name.toVector(NameSV);
1149b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return GetOrCreateSymbol(NameSV.str());
1157c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner}
1167c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner
1171d72a7661611395a1c4fd3a88a2151921180e510Chris LattnerMCSymbol *MCContext::CreateTempSymbol() {
1189f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  SmallString<128> NameSV;
119c18214a6e0a22ffa6886c70dbd6176ac9e91c847Benjamin Kramer  raw_svector_ostream(NameSV)
120c18214a6e0a22ffa6886c70dbd6176ac9e91c847Benjamin Kramer    << MAI.getPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
1219f44724be058d17944dcd9ef6a6b57734b3744b8Rafael Espindola  return CreateSymbol(NameSV);
12200685bb5cf791fcda9fa0ceb42a6a62a07478461Chris Lattner}
12300685bb5cf791fcda9fa0ceb42a6a62a07478461Chris Lattner
124ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderbyunsigned MCContext::NextInstance(int64_t LocalLabelVal) {
12547f9a49560cbf629ff36f3efb591d70b29471320Benjamin Kramer  MCLabel *&Label = Instances[LocalLabelVal];
12647f9a49560cbf629ff36f3efb591d70b29471320Benjamin Kramer  if (!Label)
12747f9a49560cbf629ff36f3efb591d70b29471320Benjamin Kramer    Label = new (*this) MCLabel(0);
12847f9a49560cbf629ff36f3efb591d70b29471320Benjamin Kramer  return Label->incInstance();
129ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby}
130ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby
131ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderbyunsigned MCContext::GetInstance(int64_t LocalLabelVal) {
13247f9a49560cbf629ff36f3efb591d70b29471320Benjamin Kramer  MCLabel *&Label = Instances[LocalLabelVal];
13347f9a49560cbf629ff36f3efb591d70b29471320Benjamin Kramer  if (!Label)
13447f9a49560cbf629ff36f3efb591d70b29471320Benjamin Kramer    Label = new (*this) MCLabel(0);
13547f9a49560cbf629ff36f3efb591d70b29471320Benjamin Kramer  return Label->getInstance();
136ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby}
137ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby
138ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin EnderbyMCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) {
139ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
140ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby                           Twine(LocalLabelVal) +
141ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby                           "\2" +
1423472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                           Twine(NextInstance(LocalLabelVal)));
143ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby}
144ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin EnderbyMCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal,
145ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby                                               int bORf) {
146ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby  return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) +
147ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby                           Twine(LocalLabelVal) +
148ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby                           "\2" +
1493472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                           Twine(GetInstance(LocalLabelVal) + bORf));
150ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby}
151ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby
1522928c83b010f7cfdb0f819199d806f6942a7d995Daniel DunbarMCSymbol *MCContext::LookupSymbol(StringRef Name) const {
153ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar  return Symbols.lookup(Name);
154ecc63f8687c4eb746b69336316685fe9b224adfbDaniel Dunbar}
155f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner
156f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner//===----------------------------------------------------------------------===//
157f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner// Section Management
158f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner//===----------------------------------------------------------------------===//
159f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner
160f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattnerconst MCSectionMachO *MCContext::
161f0559e4b242e85d4b9d1dd08758814c599bdce13Chris LattnergetMachOSection(StringRef Segment, StringRef Section,
162f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner                unsigned TypeAndAttributes,
163f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner                unsigned Reserved2, SectionKind Kind) {
164326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
165f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // We unique sections by their segment/section pair.  The returned section
166f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // may not have the same flags as the requested section, if so this should be
167f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // diagnosed by the client as an error.
168326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
169f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // Create the map if it doesn't already exist.
170f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  if (MachOUniquingMap == 0)
171f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner    MachOUniquingMap = new MachOUniqueMapTy();
172f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;
173326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
174f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // Form the name to look up.
175f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  SmallString<64> Name;
176f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  Name += Segment;
177f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  Name.push_back(',');
178f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  Name += Section;
179326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
180f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // Do the lookup, if we have a hit, return it.
181f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  const MCSectionMachO *&Entry = Map[Name.str()];
182f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  if (Entry) return Entry;
183326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
184f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner  // Otherwise, return a new section.
18574aae4726a66733c5872588287535a984f9a94c7Chris Lattner  return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
18674aae4726a66733c5872588287535a984f9a94c7Chris Lattner                                            Reserved2, Kind);
187f0559e4b242e85d4b9d1dd08758814c599bdce13Chris Lattner}
18874aae4726a66733c5872588287535a984f9a94c7Chris Lattner
1894283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindolaconst MCSectionELF *MCContext::
19074aae4726a66733c5872588287535a984f9a94c7Chris LattnergetELFSection(StringRef Section, unsigned Type, unsigned Flags,
1912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola              SectionKind Kind) {
1922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  return getELFSection(Section, Type, Flags, Kind, 0, "");
1932ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
1942ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
1952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindolaconst MCSectionELF *MCContext::
1962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael EspindolagetELFSection(StringRef Section, unsigned Type, unsigned Flags,
1972ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola              SectionKind Kind, unsigned EntrySize, StringRef Group) {
19874aae4726a66733c5872588287535a984f9a94c7Chris Lattner  if (ELFUniquingMap == 0)
19974aae4726a66733c5872588287535a984f9a94c7Chris Lattner    ELFUniquingMap = new ELFUniqueMapTy();
20074aae4726a66733c5872588287535a984f9a94c7Chris Lattner  ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap;
201326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
20274aae4726a66733c5872588287535a984f9a94c7Chris Lattner  // Do the lookup, if we have a hit, return it.
20374aae4726a66733c5872588287535a984f9a94c7Chris Lattner  StringMapEntry<const MCSectionELF*> &Entry = Map.GetOrCreateValue(Section);
20474aae4726a66733c5872588287535a984f9a94c7Chris Lattner  if (Entry.getValue()) return Entry.getValue();
205326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
206186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung  // Possibly refine the entry size first.
207186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung  if (!EntrySize) {
208186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung    EntrySize = MCSectionELF::DetermineEntrySize(Kind);
209186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung  }
2102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
2112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  MCSymbol *GroupSym = NULL;
2122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  if (!Group.empty())
2132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola    GroupSym = GetOrCreateSymbol(Group);
2142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
21574aae4726a66733c5872588287535a984f9a94c7Chris Lattner  MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags,
2162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                                                  Kind, EntrySize, GroupSym);
21774aae4726a66733c5872588287535a984f9a94c7Chris Lattner  Entry.setValue(Result);
21874aae4726a66733c5872588287535a984f9a94c7Chris Lattner  return Result;
21974aae4726a66733c5872588287535a984f9a94c7Chris Lattner}
22074aae4726a66733c5872588287535a984f9a94c7Chris Lattner
2212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindolaconst MCSectionELF *MCContext::CreateELFGroupSection() {
2222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  MCSectionELF *Result =
223c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola    new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0,
2242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola                             SectionKind::getReadOnly(), 4, NULL);
2252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola  return Result;
2262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola}
2272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola
2286e5ce287b0e53c264af0ba37169ad964e19b5bb7Chris Lattnerconst MCSection *MCContext::getCOFFSection(StringRef Section,
2296e5ce287b0e53c264af0ba37169ad964e19b5bb7Chris Lattner                                           unsigned Characteristics,
2306e5ce287b0e53c264af0ba37169ad964e19b5bb7Chris Lattner                                           int Selection,
2316e5ce287b0e53c264af0ba37169ad964e19b5bb7Chris Lattner                                           SectionKind Kind) {
232eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  if (COFFUniquingMap == 0)
233eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner    COFFUniquingMap = new COFFUniqueMapTy();
234eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap;
235326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
236eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  // Do the lookup, if we have a hit, return it.
237eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section);
238eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  if (Entry.getValue()) return Entry.getValue();
239326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
2406e5ce287b0e53c264af0ba37169ad964e19b5bb7Chris Lattner  MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(),
2416e5ce287b0e53c264af0ba37169ad964e19b5bb7Chris Lattner                                                    Characteristics,
2426e5ce287b0e53c264af0ba37169ad964e19b5bb7Chris Lattner                                                    Selection, Kind);
243326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
244eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  Entry.setValue(Result);
245eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner  return Result;
246eb40a0fd98c44ecc6360e7fab33cf9e9911bed4fChris Lattner}
2477cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
2487cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//===----------------------------------------------------------------------===//
2497cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// Dwarf Management
2507cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//===----------------------------------------------------------------------===//
2517cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
2527cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby/// GetDwarfFile - takes a file name an number to place in the dwarf file and
2537cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby/// directory tables.  If the file number has already been allocated it is an
2547cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby/// error and zero is returned and the client reports the error, else the
2557cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby/// allocated file number is returned.  The file numbers may be in any order.
25644d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewyckyunsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
25744d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky                                 unsigned FileNumber) {
2587cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // TODO: a FileNumber of zero says to use the next available file number.
2597cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
2607cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // to not be less than one.  This needs to be change to be not less than zero.
2617cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
2627cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // Make space for this FileNumber in the MCDwarfFiles vector if needed.
2637cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  if (FileNumber >= MCDwarfFiles.size()) {
2647cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    MCDwarfFiles.resize(FileNumber + 1);
2657cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  } else {
2667cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber];
2677cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    if (ExistingFile)
2687cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby      // It is an error to use see the same number more than once.
2697cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby      return 0;
2707cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  }
2717cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
2727cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // Get the new MCDwarfFile slot for this FileNumber.
2737cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  MCDwarfFile *&File = MCDwarfFiles[FileNumber];
2747cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
27544d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky  if (Directory.empty()) {
27644d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky    // Separate the directory part from the basename of the FileName.
27744d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky    std::pair<StringRef, StringRef> Slash = FileName.rsplit('/');
27844d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky    Directory = Slash.second;
279064e48a3dce1fd29a35b4b1b01a8c4b67e29c74aKevin Enderby    if (!Directory.empty()) {
280064e48a3dce1fd29a35b4b1b01a8c4b67e29c74aKevin Enderby      Directory = Slash.first;
281064e48a3dce1fd29a35b4b1b01a8c4b67e29c74aKevin Enderby      FileName = Slash.second;
282064e48a3dce1fd29a35b4b1b01a8c4b67e29c74aKevin Enderby    }
28344d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky  }
2847cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
2857cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // Find or make a entry in the MCDwarfDirs vector for this Directory.
2867cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // Capture directory name.
28744d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky  unsigned DirIndex;
28844d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky  if (Directory.empty()) {
28944d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky    // For FileNames with no directories a DirIndex of 0 is used.
29044d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky    DirIndex = 0;
2917cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  } else {
29218ad76bb9aa1970958c52887eb4a648d1bac0a0eNick Lewycky    DirIndex = 0;
29318ad76bb9aa1970958c52887eb4a648d1bac0a0eNick Lewycky    for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) {
2943bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer      if (Directory == MCDwarfDirs[DirIndex])
295232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby        break;
2967cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    }
2977cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    if (DirIndex >= MCDwarfDirs.size()) {
2983bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer      char *Buf = static_cast<char *>(Allocate(Directory.size()));
2993bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer      memcpy(Buf, Directory.data(), Directory.size());
3003bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer      MCDwarfDirs.push_back(StringRef(Buf, Directory.size()));
3017cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    }
302b07ce60981368f816af4caa3257e1e4ebf059133Kevin Enderby    // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
303b07ce60981368f816af4caa3257e1e4ebf059133Kevin Enderby    // no directories.  MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
30444d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky    // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
30544d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky    // are stored at MCDwarfFiles[FileNumber].Name .
306b07ce60981368f816af4caa3257e1e4ebf059133Kevin Enderby    DirIndex++;
3077cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  }
308326990f1eb7ff005adabe46a1f982eff8835813eMichael J. Spencer
3097cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles
3107cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // vector.
31144d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky  char *Buf = static_cast<char *>(Allocate(FileName.size()));
31244d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky  memcpy(Buf, FileName.data(), FileName.size());
31344d798d9763bc32aaf49fe7c10d604845f4b6685Nick Lewycky  File = new (*this) MCDwarfFile(StringRef(Buf, FileName.size()), DirIndex);
3147cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
3157cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  // return the allocated FileNumber.
3167cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  return FileNumber;
3177cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby}
318c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
3193f55c24df9527de345f6cc960944840a7a101c6aKevin Enderby/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
320c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby/// currently is assigned and false otherwise.
3213f55c24df9527de345f6cc960944840a7a101c6aKevin Enderbybool MCContext::isValidDwarfFileNumber(unsigned FileNumber) {
322c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby  if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
323c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    return false;
324c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
3253f55c24df9527de345f6cc960944840a7a101c6aKevin Enderby  return MCDwarfFiles[FileNumber] != 0;
326c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby}
32782f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach
32882f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbachvoid MCContext::FatalError(SMLoc Loc, const Twine &Msg) {
32982f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  // If we have a source manager and a location, use it. Otherwise just
33082f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  // use the generic report_fatal_error().
33182f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  if (!SrcMgr || Loc == SMLoc())
33282f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach    report_fatal_error(Msg);
33382f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach
33482f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  // Use the source manager to print the message.
33582f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
33682f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach
33782f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  // If we reached here, we are failing ungracefully. Run the interrupt handlers
33882f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  // to make sure any special cleanups get done, in particular that we remove
33982f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  // files registered with RemoveFileOnSignal.
34082f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  sys::RunInterruptHandlers();
34182f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach  exit(1);
34282f4ce5081fc9cfbf34bbe61eb0412e7ca4dc3dfJim Grosbach}
343