Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

490 lines
19 KiB

  1. //===- MCContext.h - Machine Code Context -----------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef LLVM_MC_MCCONTEXT_H
  10. #define LLVM_MC_MCCONTEXT_H
  11. #include "llvm/ADT/DenseMap.h"
  12. #include "llvm/ADT/SmallVector.h"
  13. #include "llvm/ADT/StringMap.h"
  14. #include "llvm/MC/MCDwarf.h"
  15. #include "llvm/MC/SectionKind.h"
  16. #include "llvm/Support/Allocator.h"
  17. #include "llvm/Support/Compiler.h"
  18. #include "llvm/Support/raw_ostream.h"
  19. #include <map>
  20. #include <vector> // FIXME: Shouldn't be needed.
  21. namespace llvm {
  22. class MCAsmInfo;
  23. class MCExpr;
  24. class MCSection;
  25. class MCSymbol;
  26. class MCLabel;
  27. class MCDwarfFile;
  28. class MCDwarfLoc;
  29. class MCObjectFileInfo;
  30. class MCRegisterInfo;
  31. class MCLineSection;
  32. class SMLoc;
  33. class StringRef;
  34. class Twine;
  35. class MCSectionMachO;
  36. class MCSectionELF;
  37. /// MCContext - Context object for machine code objects. This class owns all
  38. /// of the sections that it creates.
  39. ///
  40. class MCContext {
  41. MCContext(const MCContext&) LLVM_DELETED_FUNCTION;
  42. MCContext &operator=(const MCContext&) LLVM_DELETED_FUNCTION;
  43. public:
  44. typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
  45. private:
  46. /// The SourceMgr for this object, if any.
  47. const SourceMgr *SrcMgr;
  48. /// The MCAsmInfo for this target.
  49. const MCAsmInfo &MAI;
  50. /// The MCRegisterInfo for this target.
  51. const MCRegisterInfo &MRI;
  52. /// The MCObjectFileInfo for this target.
  53. const MCObjectFileInfo *MOFI;
  54. /// Allocator - Allocator object used for creating machine code objects.
  55. ///
  56. /// We use a bump pointer allocator to avoid the need to track all allocated
  57. /// objects.
  58. BumpPtrAllocator Allocator;
  59. /// Symbols - Bindings of names to symbols.
  60. SymbolTable Symbols;
  61. /// UsedNames - Keeps tracks of names that were used both for used declared
  62. /// and artificial symbols.
  63. StringMap<bool, BumpPtrAllocator&> UsedNames;
  64. /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
  65. /// symbol.
  66. unsigned NextUniqueID;
  67. /// Instances of directional local labels.
  68. DenseMap<unsigned, MCLabel *> Instances;
  69. /// NextInstance() creates the next instance of the directional local label
  70. /// for the LocalLabelVal and adds it to the map if needed.
  71. unsigned NextInstance(int64_t LocalLabelVal);
  72. /// GetInstance() gets the current instance of the directional local label
  73. /// for the LocalLabelVal and adds it to the map if needed.
  74. unsigned GetInstance(int64_t LocalLabelVal);
  75. /// The file name of the log file from the environment variable
  76. /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique
  77. /// directive is used or it is an error.
  78. char *SecureLogFile;
  79. /// The stream that gets written to for the .secure_log_unique directive.
  80. raw_ostream *SecureLog;
  81. /// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to
  82. /// catch errors if .secure_log_unique appears twice without
  83. /// .secure_log_reset appearing between them.
  84. bool SecureLogUsed;
  85. /// The compilation directory to use for DW_AT_comp_dir.
  86. std::string CompilationDir;
  87. /// The main file name if passed in explicitly.
  88. std::string MainFileName;
  89. /// The dwarf file and directory tables from the dwarf .file directive.
  90. /// We now emit a line table for each compile unit. To reduce the prologue
  91. /// size of each line table, the files and directories used by each compile
  92. /// unit are separated.
  93. typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap;
  94. MCDwarfFilesMap MCDwarfFilesCUMap;
  95. std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap;
  96. /// The current dwarf line information from the last dwarf .loc directive.
  97. MCDwarfLoc CurrentDwarfLoc;
  98. bool DwarfLocSeen;
  99. /// Generate dwarf debugging info for assembly source files.
  100. bool GenDwarfForAssembly;
  101. /// The current dwarf file number when generate dwarf debugging info for
  102. /// assembly source files.
  103. unsigned GenDwarfFileNumber;
  104. /// The default initial text section that we generate dwarf debugging line
  105. /// info for when generating dwarf assembly source files.
  106. const MCSection *GenDwarfSection;
  107. /// Symbols created for the start and end of this section.
  108. MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym;
  109. /// The information gathered from labels that will have dwarf label
  110. /// entries when generating dwarf assembly source files.
  111. std::vector<const MCGenDwarfLabelEntry *> MCGenDwarfLabelEntries;
  112. /// The string to embed in the debug information for the compile unit, if
  113. /// non-empty.
  114. StringRef DwarfDebugFlags;
  115. /// The string to embed in as the dwarf AT_producer for the compile unit, if
  116. /// non-empty.
  117. StringRef DwarfDebugProducer;
  118. /// Honor temporary labels, this is useful for debugging semantic
  119. /// differences between temporary and non-temporary labels (primarily on
  120. /// Darwin).
  121. bool AllowTemporaryLabels;
  122. /// The dwarf line information from the .loc directives for the sections
  123. /// with assembled machine instructions have after seeing .loc directives.
  124. DenseMap<const MCSection *, MCLineSection *> MCLineSections;
  125. /// We need a deterministic iteration order, so we remember the order
  126. /// the elements were added.
  127. std::vector<const MCSection *> MCLineSectionOrder;
  128. /// The Compile Unit ID that we are currently processing.
  129. unsigned DwarfCompileUnitID;
  130. /// The line table start symbol for each Compile Unit.
  131. DenseMap<unsigned, MCSymbol *> MCLineTableSymbols;
  132. void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
  133. /// Do automatic reset in destructor
  134. bool AutoReset;
  135. MCSymbol *CreateSymbol(StringRef Name);
  136. public:
  137. explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
  138. const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0,
  139. bool DoAutoReset = true);
  140. ~MCContext();
  141. const SourceMgr *getSourceManager() const { return SrcMgr; }
  142. const MCAsmInfo &getAsmInfo() const { return MAI; }
  143. const MCRegisterInfo &getRegisterInfo() const { return MRI; }
  144. const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
  145. void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
  146. /// @name Module Lifetime Management
  147. /// @{
  148. /// reset - return object to right after construction state to prepare
  149. /// to process a new module
  150. void reset();
  151. /// @}
  152. /// @name Symbol Management
  153. /// @{
  154. /// CreateTempSymbol - Create and return a new assembler temporary symbol
  155. /// with a unique but unspecified name.
  156. MCSymbol *CreateTempSymbol();
  157. /// getUniqueSymbolID() - Return a unique identifier for use in constructing
  158. /// symbol names.
  159. unsigned getUniqueSymbolID() { return NextUniqueID++; }
  160. /// CreateDirectionalLocalSymbol - Create the definition of a directional
  161. /// local symbol for numbered label (used for "1:" definitions).
  162. MCSymbol *CreateDirectionalLocalSymbol(int64_t LocalLabelVal);
  163. /// GetDirectionalLocalSymbol - Create and return a directional local
  164. /// symbol for numbered label (used for "1b" or 1f" references).
  165. MCSymbol *GetDirectionalLocalSymbol(int64_t LocalLabelVal, int bORf);
  166. /// GetOrCreateSymbol - Lookup the symbol inside with the specified
  167. /// @p Name. If it exists, return it. If not, create a forward
  168. /// reference and return it.
  169. ///
  170. /// @param Name - The symbol name, which must be unique across all symbols.
  171. MCSymbol *GetOrCreateSymbol(StringRef Name);
  172. MCSymbol *GetOrCreateSymbol(const Twine &Name);
  173. /// LookupSymbol - Get the symbol for \p Name, or null.
  174. MCSymbol *LookupSymbol(StringRef Name) const;
  175. MCSymbol *LookupSymbol(const Twine &Name) const;
  176. /// getSymbols - Get a reference for the symbol table for clients that
  177. /// want to, for example, iterate over all symbols. 'const' because we
  178. /// still want any modifications to the table itself to use the MCContext
  179. /// APIs.
  180. const SymbolTable &getSymbols() const {
  181. return Symbols;
  182. }
  183. /// @}
  184. /// @name Section Management
  185. /// @{
  186. /// getMachOSection - Return the MCSection for the specified mach-o section.
  187. /// This requires the operands to be valid.
  188. const MCSectionMachO *getMachOSection(StringRef Segment,
  189. StringRef Section,
  190. unsigned TypeAndAttributes,
  191. unsigned Reserved2,
  192. SectionKind K);
  193. const MCSectionMachO *getMachOSection(StringRef Segment,
  194. StringRef Section,
  195. unsigned TypeAndAttributes,
  196. SectionKind K) {
  197. return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
  198. }
  199. const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
  200. unsigned Flags, SectionKind Kind);
  201. const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
  202. unsigned Flags, SectionKind Kind,
  203. unsigned EntrySize, StringRef Group);
  204. const MCSectionELF *CreateELFGroupSection();
  205. const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
  206. int Selection, SectionKind Kind);
  207. const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics,
  208. SectionKind Kind) {
  209. return getCOFFSection (Section, Characteristics, 0, Kind);
  210. }
  211. /// @}
  212. /// @name Dwarf Management
  213. /// @{
  214. /// \brief Get the compilation directory for DW_AT_comp_dir
  215. /// This can be overridden by clients which want to control the reported
  216. /// compilation directory and have it be something other than the current
  217. /// working directory.
  218. const std::string &getCompilationDir() const { return CompilationDir; }
  219. /// \brief Set the compilation directory for DW_AT_comp_dir
  220. /// Override the default (CWD) compilation directory.
  221. void setCompilationDir(StringRef S) { CompilationDir = S.str(); }
  222. /// \brief Get the main file name for use in error messages and debug
  223. /// info. This can be set to ensure we've got the correct file name
  224. /// after preprocessing or for -save-temps.
  225. const std::string &getMainFileName() const { return MainFileName; }
  226. /// \brief Set the main file name and override the default.
  227. void setMainFileName(StringRef S) { MainFileName = S.str(); }
  228. /// GetDwarfFile - creates an entry in the dwarf file and directory tables.
  229. unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
  230. unsigned FileNumber, unsigned CUID);
  231. bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
  232. bool hasDwarfFiles() const {
  233. // Traverse MCDwarfFilesCUMap and check whether each entry is empty.
  234. MCDwarfFilesMap::const_iterator MapB, MapE;
  235. for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end();
  236. MapB != MapE; MapB++)
  237. if (!MapB->second.empty())
  238. return true;
  239. return false;
  240. }
  241. const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) {
  242. return MCDwarfFilesCUMap[CUID];
  243. }
  244. const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) {
  245. return MCDwarfDirsCUMap[CUID];
  246. }
  247. const DenseMap<const MCSection *, MCLineSection *>
  248. &getMCLineSections() const {
  249. return MCLineSections;
  250. }
  251. const std::vector<const MCSection *> &getMCLineSectionOrder() const {
  252. return MCLineSectionOrder;
  253. }
  254. void addMCLineSection(const MCSection *Sec, MCLineSection *Line) {
  255. MCLineSections[Sec] = Line;
  256. MCLineSectionOrder.push_back(Sec);
  257. }
  258. unsigned getDwarfCompileUnitID() {
  259. return DwarfCompileUnitID;
  260. }
  261. void setDwarfCompileUnitID(unsigned CUIndex) {
  262. DwarfCompileUnitID = CUIndex;
  263. }
  264. const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const {
  265. return MCLineTableSymbols;
  266. }
  267. MCSymbol *getMCLineTableSymbol(unsigned ID) const {
  268. DenseMap<unsigned, MCSymbol *>::const_iterator CIter =
  269. MCLineTableSymbols.find(ID);
  270. if (CIter == MCLineTableSymbols.end())
  271. return NULL;
  272. return CIter->second;
  273. }
  274. void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
  275. MCLineTableSymbols[ID] = Sym;
  276. }
  277. /// setCurrentDwarfLoc - saves the information from the currently parsed
  278. /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction
  279. /// is assembled an entry in the line number table with this information and
  280. /// the address of the instruction will be created.
  281. void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
  282. unsigned Flags, unsigned Isa,
  283. unsigned Discriminator) {
  284. CurrentDwarfLoc.setFileNum(FileNum);
  285. CurrentDwarfLoc.setLine(Line);
  286. CurrentDwarfLoc.setColumn(Column);
  287. CurrentDwarfLoc.setFlags(Flags);
  288. CurrentDwarfLoc.setIsa(Isa);
  289. CurrentDwarfLoc.setDiscriminator(Discriminator);
  290. DwarfLocSeen = true;
  291. }
  292. void ClearDwarfLocSeen() { DwarfLocSeen = false; }
  293. bool getDwarfLocSeen() { return DwarfLocSeen; }
  294. const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
  295. bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
  296. void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
  297. unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
  298. unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; }
  299. const MCSection *getGenDwarfSection() { return GenDwarfSection; }
  300. void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
  301. MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }
  302. void setGenDwarfSectionStartSym(MCSymbol *Sym) {
  303. GenDwarfSectionStartSym = Sym;
  304. }
  305. MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; }
  306. void setGenDwarfSectionEndSym(MCSymbol *Sym) {
  307. GenDwarfSectionEndSym = Sym;
  308. }
  309. const std::vector<const MCGenDwarfLabelEntry *>
  310. &getMCGenDwarfLabelEntries() const {
  311. return MCGenDwarfLabelEntries;
  312. }
  313. void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E) {
  314. MCGenDwarfLabelEntries.push_back(E);
  315. }
  316. void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }
  317. StringRef getDwarfDebugFlags() { return DwarfDebugFlags; }
  318. void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
  319. StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
  320. /// @}
  321. char *getSecureLogFile() { return SecureLogFile; }
  322. raw_ostream *getSecureLog() { return SecureLog; }
  323. bool getSecureLogUsed() { return SecureLogUsed; }
  324. void setSecureLog(raw_ostream *Value) {
  325. SecureLog = Value;
  326. }
  327. void setSecureLogUsed(bool Value) {
  328. SecureLogUsed = Value;
  329. }
  330. void *Allocate(unsigned Size, unsigned Align = 8) {
  331. return Allocator.Allocate(Size, Align);
  332. }
  333. void Deallocate(void *Ptr) {
  334. }
  335. // Unrecoverable error has occured. Display the best diagnostic we can
  336. // and bail via exit(1). For now, most MC backend errors are unrecoverable.
  337. // FIXME: We should really do something about that.
  338. LLVM_ATTRIBUTE_NORETURN void FatalError(SMLoc L, const Twine &Msg);
  339. };
  340. } // end namespace llvm
  341. // operator new and delete aren't allowed inside namespaces.
  342. // The throw specifications are mandated by the standard.
  343. /// @brief Placement new for using the MCContext's allocator.
  344. ///
  345. /// This placement form of operator new uses the MCContext's allocator for
  346. /// obtaining memory. It is a non-throwing new, which means that it returns
  347. /// null on error. (If that is what the allocator does. The current does, so if
  348. /// this ever changes, this operator will have to be changed, too.)
  349. /// Usage looks like this (assuming there's an MCContext 'Context' in scope):
  350. /// @code
  351. /// // Default alignment (16)
  352. /// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments);
  353. /// // Specific alignment
  354. /// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments);
  355. /// @endcode
  356. /// Please note that you cannot use delete on the pointer; it must be
  357. /// deallocated using an explicit destructor call followed by
  358. /// @c Context.Deallocate(Ptr).
  359. ///
  360. /// @param Bytes The number of bytes to allocate. Calculated by the compiler.
  361. /// @param C The MCContext that provides the allocator.
  362. /// @param Alignment The alignment of the allocated memory (if the underlying
  363. /// allocator supports it).
  364. /// @return The allocated memory. Could be NULL.
  365. inline void *operator new(size_t Bytes, llvm::MCContext &C,
  366. size_t Alignment = 16) throw () {
  367. return C.Allocate(Bytes, Alignment);
  368. }
  369. /// @brief Placement delete companion to the new above.
  370. ///
  371. /// This operator is just a companion to the new above. There is no way of
  372. /// invoking it directly; see the new operator for more details. This operator
  373. /// is called implicitly by the compiler if a placement new expression using
  374. /// the MCContext throws in the object constructor.
  375. inline void operator delete(void *Ptr, llvm::MCContext &C, size_t)
  376. throw () {
  377. C.Deallocate(Ptr);
  378. }
  379. /// This placement form of operator new[] uses the MCContext's allocator for
  380. /// obtaining memory. It is a non-throwing new[], which means that it returns
  381. /// null on error.
  382. /// Usage looks like this (assuming there's an MCContext 'Context' in scope):
  383. /// @code
  384. /// // Default alignment (16)
  385. /// char *data = new (Context) char[10];
  386. /// // Specific alignment
  387. /// char *data = new (Context, 8) char[10];
  388. /// @endcode
  389. /// Please note that you cannot use delete on the pointer; it must be
  390. /// deallocated using an explicit destructor call followed by
  391. /// @c Context.Deallocate(Ptr).
  392. ///
  393. /// @param Bytes The number of bytes to allocate. Calculated by the compiler.
  394. /// @param C The MCContext that provides the allocator.
  395. /// @param Alignment The alignment of the allocated memory (if the underlying
  396. /// allocator supports it).
  397. /// @return The allocated memory. Could be NULL.
  398. inline void *operator new[](size_t Bytes, llvm::MCContext& C,
  399. size_t Alignment = 16) throw () {
  400. return C.Allocate(Bytes, Alignment);
  401. }
  402. /// @brief Placement delete[] companion to the new[] above.
  403. ///
  404. /// This operator is just a companion to the new[] above. There is no way of
  405. /// invoking it directly; see the new[] operator for more details. This operator
  406. /// is called implicitly by the compiler if a placement new[] expression using
  407. /// the MCContext throws in the object constructor.
  408. inline void operator delete[](void *Ptr, llvm::MCContext &C) throw () {
  409. C.Deallocate(Ptr);
  410. }
  411. #endif