MCSymbolMachO.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //===- MCSymbolMachO.h - ---------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_MC_MCSYMBOLMACHO_H
  9. #define LLVM_MC_MCSYMBOLMACHO_H
  10. #include "llvm/ADT/Twine.h"
  11. #include "llvm/MC/MCSymbol.h"
  12. namespace llvm {
  13. class MCSymbolMachO : public MCSymbol {
  14. /// We store the value for the 'desc' symbol field in the
  15. /// lowest 16 bits of the implementation defined flags.
  16. enum MachOSymbolFlags : uint16_t { // See <mach-o/nlist.h>.
  17. SF_DescFlagsMask = 0xFFFF,
  18. // Reference type flags.
  19. SF_ReferenceTypeMask = 0x0007,
  20. SF_ReferenceTypeUndefinedNonLazy = 0x0000,
  21. SF_ReferenceTypeUndefinedLazy = 0x0001,
  22. SF_ReferenceTypeDefined = 0x0002,
  23. SF_ReferenceTypePrivateDefined = 0x0003,
  24. SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
  25. SF_ReferenceTypePrivateUndefinedLazy = 0x0005,
  26. // Other 'desc' flags.
  27. SF_ThumbFunc = 0x0008,
  28. SF_NoDeadStrip = 0x0020,
  29. SF_WeakReference = 0x0040,
  30. SF_WeakDefinition = 0x0080,
  31. SF_SymbolResolver = 0x0100,
  32. SF_AltEntry = 0x0200,
  33. SF_Cold = 0x0400,
  34. // Common alignment
  35. SF_CommonAlignmentMask = 0xF0FF,
  36. SF_CommonAlignmentShift = 8
  37. };
  38. public:
  39. MCSymbolMachO(const StringMapEntry<bool> *Name, bool isTemporary)
  40. : MCSymbol(SymbolKindMachO, Name, isTemporary) {}
  41. // Reference type methods.
  42. void clearReferenceType() const {
  43. modifyFlags(0, SF_ReferenceTypeMask);
  44. }
  45. void setReferenceTypeUndefinedLazy(bool Value) const {
  46. modifyFlags(Value ? SF_ReferenceTypeUndefinedLazy : 0,
  47. SF_ReferenceTypeUndefinedLazy);
  48. }
  49. // Other 'desc' methods.
  50. void setThumbFunc() const {
  51. modifyFlags(SF_ThumbFunc, SF_ThumbFunc);
  52. }
  53. bool isNoDeadStrip() const {
  54. return getFlags() & SF_NoDeadStrip;
  55. }
  56. void setNoDeadStrip() const {
  57. modifyFlags(SF_NoDeadStrip, SF_NoDeadStrip);
  58. }
  59. bool isWeakReference() const {
  60. return getFlags() & SF_WeakReference;
  61. }
  62. void setWeakReference() const {
  63. modifyFlags(SF_WeakReference, SF_WeakReference);
  64. }
  65. bool isWeakDefinition() const {
  66. return getFlags() & SF_WeakDefinition;
  67. }
  68. void setWeakDefinition() const {
  69. modifyFlags(SF_WeakDefinition, SF_WeakDefinition);
  70. }
  71. bool isSymbolResolver() const {
  72. return getFlags() & SF_SymbolResolver;
  73. }
  74. void setSymbolResolver() const {
  75. modifyFlags(SF_SymbolResolver, SF_SymbolResolver);
  76. }
  77. void setAltEntry() const {
  78. modifyFlags(SF_AltEntry, SF_AltEntry);
  79. }
  80. bool isAltEntry() const {
  81. return getFlags() & SF_AltEntry;
  82. }
  83. void setCold() const { modifyFlags(SF_Cold, SF_Cold); }
  84. bool isCold() const { return getFlags() & SF_Cold; }
  85. void setDesc(unsigned Value) const {
  86. assert(Value == (Value & SF_DescFlagsMask) &&
  87. "Invalid .desc value!");
  88. setFlags(Value & SF_DescFlagsMask);
  89. }
  90. /// Get the encoded value of the flags as they will be emitted in to
  91. /// the MachO binary
  92. uint16_t getEncodedFlags(bool EncodeAsAltEntry) const {
  93. uint16_t Flags = getFlags();
  94. // Common alignment is packed into the 'desc' bits.
  95. if (isCommon()) {
  96. if (unsigned Align = getCommonAlignment()) {
  97. unsigned Log2Size = Log2_32(Align);
  98. assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
  99. if (Log2Size > 15)
  100. report_fatal_error("invalid 'common' alignment '" +
  101. Twine(Align) + "' for '" + getName() + "'",
  102. false);
  103. Flags = (Flags & SF_CommonAlignmentMask) |
  104. (Log2Size << SF_CommonAlignmentShift);
  105. }
  106. }
  107. if (EncodeAsAltEntry)
  108. Flags |= SF_AltEntry;
  109. return Flags;
  110. }
  111. static bool classof(const MCSymbol *S) { return S->isMachO(); }
  112. };
  113. }
  114. #endif