MCSymbolELF.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //===- lib/MC/MCSymbolELF.cpp ---------------------------------------------===//
  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. #include "llvm/MC/MCSymbolELF.h"
  9. #include "llvm/BinaryFormat/ELF.h"
  10. #include "llvm/MC/MCFixupKindInfo.h"
  11. namespace llvm {
  12. namespace {
  13. enum {
  14. // Shift value for STT_* flags. 7 possible values. 3 bits.
  15. ELF_STT_Shift = 0,
  16. // Shift value for STB_* flags. 4 possible values, 2 bits.
  17. ELF_STB_Shift = 3,
  18. // Shift value for STV_* flags. 4 possible values, 2 bits.
  19. ELF_STV_Shift = 5,
  20. // Shift value for STO_* flags. 3 bits. All the values are between 0x20 and
  21. // 0xe0, so we shift right by 5 before storing.
  22. ELF_STO_Shift = 7,
  23. // One bit.
  24. ELF_IsSignature_Shift = 10,
  25. // One bit.
  26. ELF_WeakrefUsedInReloc_Shift = 11,
  27. // One bit.
  28. ELF_BindingSet_Shift = 12
  29. };
  30. }
  31. void MCSymbolELF::setBinding(unsigned Binding) const {
  32. setIsBindingSet();
  33. unsigned Val;
  34. switch (Binding) {
  35. default:
  36. llvm_unreachable("Unsupported Binding");
  37. case ELF::STB_LOCAL:
  38. Val = 0;
  39. break;
  40. case ELF::STB_GLOBAL:
  41. Val = 1;
  42. break;
  43. case ELF::STB_WEAK:
  44. Val = 2;
  45. break;
  46. case ELF::STB_GNU_UNIQUE:
  47. Val = 3;
  48. break;
  49. }
  50. uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STB_Shift);
  51. setFlags(OtherFlags | (Val << ELF_STB_Shift));
  52. }
  53. unsigned MCSymbolELF::getBinding() const {
  54. if (isBindingSet()) {
  55. uint32_t Val = (Flags >> ELF_STB_Shift) & 3;
  56. switch (Val) {
  57. default:
  58. llvm_unreachable("Invalid value");
  59. case 0:
  60. return ELF::STB_LOCAL;
  61. case 1:
  62. return ELF::STB_GLOBAL;
  63. case 2:
  64. return ELF::STB_WEAK;
  65. case 3:
  66. return ELF::STB_GNU_UNIQUE;
  67. }
  68. }
  69. if (isDefined())
  70. return ELF::STB_LOCAL;
  71. if (isUsedInReloc())
  72. return ELF::STB_GLOBAL;
  73. if (isWeakrefUsedInReloc())
  74. return ELF::STB_WEAK;
  75. if (isSignature())
  76. return ELF::STB_LOCAL;
  77. return ELF::STB_GLOBAL;
  78. }
  79. void MCSymbolELF::setType(unsigned Type) const {
  80. unsigned Val;
  81. switch (Type) {
  82. default:
  83. llvm_unreachable("Unsupported Binding");
  84. case ELF::STT_NOTYPE:
  85. Val = 0;
  86. break;
  87. case ELF::STT_OBJECT:
  88. Val = 1;
  89. break;
  90. case ELF::STT_FUNC:
  91. Val = 2;
  92. break;
  93. case ELF::STT_SECTION:
  94. Val = 3;
  95. break;
  96. case ELF::STT_COMMON:
  97. Val = 4;
  98. break;
  99. case ELF::STT_TLS:
  100. Val = 5;
  101. break;
  102. case ELF::STT_GNU_IFUNC:
  103. Val = 6;
  104. break;
  105. }
  106. uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STT_Shift);
  107. setFlags(OtherFlags | (Val << ELF_STT_Shift));
  108. }
  109. unsigned MCSymbolELF::getType() const {
  110. uint32_t Val = (Flags >> ELF_STT_Shift) & 7;
  111. switch (Val) {
  112. default:
  113. llvm_unreachable("Invalid value");
  114. case 0:
  115. return ELF::STT_NOTYPE;
  116. case 1:
  117. return ELF::STT_OBJECT;
  118. case 2:
  119. return ELF::STT_FUNC;
  120. case 3:
  121. return ELF::STT_SECTION;
  122. case 4:
  123. return ELF::STT_COMMON;
  124. case 5:
  125. return ELF::STT_TLS;
  126. case 6:
  127. return ELF::STT_GNU_IFUNC;
  128. }
  129. }
  130. void MCSymbolELF::setVisibility(unsigned Visibility) {
  131. assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
  132. Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
  133. uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STV_Shift);
  134. setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
  135. }
  136. unsigned MCSymbolELF::getVisibility() const {
  137. unsigned Visibility = (Flags >> ELF_STV_Shift) & 3;
  138. return Visibility;
  139. }
  140. void MCSymbolELF::setOther(unsigned Other) {
  141. assert((Other & 0x1f) == 0);
  142. Other >>= 5;
  143. assert(Other <= 0x7);
  144. uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STO_Shift);
  145. setFlags(OtherFlags | (Other << ELF_STO_Shift));
  146. }
  147. unsigned MCSymbolELF::getOther() const {
  148. unsigned Other = (Flags >> ELF_STO_Shift) & 7;
  149. return Other << 5;
  150. }
  151. void MCSymbolELF::setIsWeakrefUsedInReloc() const {
  152. uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_WeakrefUsedInReloc_Shift);
  153. setFlags(OtherFlags | (1 << ELF_WeakrefUsedInReloc_Shift));
  154. }
  155. bool MCSymbolELF::isWeakrefUsedInReloc() const {
  156. return getFlags() & (0x1 << ELF_WeakrefUsedInReloc_Shift);
  157. }
  158. void MCSymbolELF::setIsSignature() const {
  159. uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_IsSignature_Shift);
  160. setFlags(OtherFlags | (1 << ELF_IsSignature_Shift));
  161. }
  162. bool MCSymbolELF::isSignature() const {
  163. return getFlags() & (0x1 << ELF_IsSignature_Shift);
  164. }
  165. void MCSymbolELF::setIsBindingSet() const {
  166. uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_BindingSet_Shift);
  167. setFlags(OtherFlags | (1 << ELF_BindingSet_Shift));
  168. }
  169. bool MCSymbolELF::isBindingSet() const {
  170. return getFlags() & (0x1 << ELF_BindingSet_Shift);
  171. }
  172. }