XCOFF.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. //===-- llvm/BinaryFormat/XCOFF.cpp - The XCOFF file format -----*- 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. #include "llvm/BinaryFormat/XCOFF.h"
  9. #include "llvm/ADT/SmallString.h"
  10. #include "llvm/ADT/StringRef.h"
  11. #include "llvm/Support/Errc.h"
  12. #include "llvm/Support/Error.h"
  13. using namespace llvm;
  14. #define SMC_CASE(A) \
  15. case XCOFF::XMC_##A: \
  16. return #A;
  17. StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) {
  18. switch (SMC) {
  19. SMC_CASE(PR)
  20. SMC_CASE(RO)
  21. SMC_CASE(DB)
  22. SMC_CASE(GL)
  23. SMC_CASE(XO)
  24. SMC_CASE(SV)
  25. SMC_CASE(SV64)
  26. SMC_CASE(SV3264)
  27. SMC_CASE(TI)
  28. SMC_CASE(TB)
  29. SMC_CASE(RW)
  30. SMC_CASE(TC0)
  31. SMC_CASE(TC)
  32. SMC_CASE(TD)
  33. SMC_CASE(DS)
  34. SMC_CASE(UA)
  35. SMC_CASE(BS)
  36. SMC_CASE(UC)
  37. SMC_CASE(TL)
  38. SMC_CASE(UL)
  39. SMC_CASE(TE)
  40. #undef SMC_CASE
  41. }
  42. // TODO: need to add a test case for "Unknown" and other SMC.
  43. return "Unknown";
  44. }
  45. #define RELOC_CASE(A) \
  46. case XCOFF::A: \
  47. return #A;
  48. StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
  49. switch (Type) {
  50. RELOC_CASE(R_POS)
  51. RELOC_CASE(R_RL)
  52. RELOC_CASE(R_RLA)
  53. RELOC_CASE(R_NEG)
  54. RELOC_CASE(R_REL)
  55. RELOC_CASE(R_TOC)
  56. RELOC_CASE(R_TRL)
  57. RELOC_CASE(R_TRLA)
  58. RELOC_CASE(R_GL)
  59. RELOC_CASE(R_TCL)
  60. RELOC_CASE(R_REF)
  61. RELOC_CASE(R_BA)
  62. RELOC_CASE(R_BR)
  63. RELOC_CASE(R_RBA)
  64. RELOC_CASE(R_RBR)
  65. RELOC_CASE(R_TLS)
  66. RELOC_CASE(R_TLS_IE)
  67. RELOC_CASE(R_TLS_LD)
  68. RELOC_CASE(R_TLS_LE)
  69. RELOC_CASE(R_TLSM)
  70. RELOC_CASE(R_TLSML)
  71. RELOC_CASE(R_TOCU)
  72. RELOC_CASE(R_TOCL)
  73. }
  74. return "Unknown";
  75. }
  76. #undef RELOC_CASE
  77. #define LANG_CASE(A) \
  78. case XCOFF::TracebackTable::A: \
  79. return #A;
  80. StringRef XCOFF::getNameForTracebackTableLanguageId(
  81. XCOFF::TracebackTable::LanguageID LangId) {
  82. switch (LangId) {
  83. LANG_CASE(C)
  84. LANG_CASE(Fortran)
  85. LANG_CASE(Pascal)
  86. LANG_CASE(Ada)
  87. LANG_CASE(PL1)
  88. LANG_CASE(Basic)
  89. LANG_CASE(Lisp)
  90. LANG_CASE(Cobol)
  91. LANG_CASE(Modula2)
  92. LANG_CASE(Rpg)
  93. LANG_CASE(PL8)
  94. LANG_CASE(Assembly)
  95. LANG_CASE(Java)
  96. LANG_CASE(ObjectiveC)
  97. LANG_CASE(CPlusPlus)
  98. }
  99. return "Unknown";
  100. }
  101. #undef LANG_CASE
  102. Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,
  103. unsigned FixedParmsNum,
  104. unsigned FloatingParmsNum) {
  105. SmallString<32> ParmsType;
  106. int Bits = 0;
  107. unsigned ParsedFixedNum = 0;
  108. unsigned ParsedFloatingNum = 0;
  109. unsigned ParsedNum = 0;
  110. unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;
  111. // In the function PPCFunctionInfo::getParmsType(), when there are no vector
  112. // parameters, the 31st bit of ParmsType is always zero even if it indicates a
  113. // floating point parameter. The parameter type information is lost. There
  114. // are only 8 GPRs used for parameters passing, the floating parameters
  115. // also occupy GPRs if there are available, so the 31st bit can never be a
  116. // fixed parameter. At the same time, we also do not know whether the zero of
  117. // the 31st bit indicates a float or double parameter type here. Therefore, we
  118. // ignore the 31st bit.
  119. while (Bits < 31 && ParsedNum < ParmsNum) {
  120. if (++ParsedNum > 1)
  121. ParmsType += ", ";
  122. if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
  123. // Fixed parameter type.
  124. ParmsType += "i";
  125. ++ParsedFixedNum;
  126. Value <<= 1;
  127. ++Bits;
  128. } else {
  129. if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
  130. // Float parameter type.
  131. ParmsType += "f";
  132. else
  133. // Double parameter type.
  134. ParmsType += "d";
  135. ++ParsedFloatingNum;
  136. Value <<= 2;
  137. Bits += 2;
  138. }
  139. }
  140. // We have more parameters than the 32 Bits could encode.
  141. if (ParsedNum < ParmsNum)
  142. ParmsType += ", ...";
  143. if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
  144. ParsedFloatingNum > FloatingParmsNum)
  145. return createStringError(errc::invalid_argument,
  146. "ParmsType encodes can not map to ParmsNum "
  147. "parameters in parseParmsType.");
  148. return ParmsType;
  149. }
  150. SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
  151. SmallString<32> Res;
  152. if (Flag & ExtendedTBTableFlag::TB_OS1)
  153. Res += "TB_OS1 ";
  154. if (Flag & ExtendedTBTableFlag::TB_RESERVED)
  155. Res += "TB_RESERVED ";
  156. if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)
  157. Res += "TB_SSP_CANARY ";
  158. if (Flag & ExtendedTBTableFlag::TB_OS2)
  159. Res += "TB_OS2 ";
  160. if (Flag & ExtendedTBTableFlag::TB_EH_INFO)
  161. Res += "TB_EH_INFO ";
  162. if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)
  163. Res += "TB_LONGTBTABLE2 ";
  164. // Two of the bits that haven't got used in the mask.
  165. if (Flag & 0x06)
  166. Res += "Unknown ";
  167. // Pop the last space.
  168. Res.pop_back();
  169. return Res;
  170. }
  171. Expected<SmallString<32>>
  172. XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,
  173. unsigned FloatingParmsNum,
  174. unsigned VectorParmsNum) {
  175. SmallString<32> ParmsType;
  176. unsigned ParsedFixedNum = 0;
  177. unsigned ParsedFloatingNum = 0;
  178. unsigned ParsedVectorNum = 0;
  179. unsigned ParsedNum = 0;
  180. unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;
  181. for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {
  182. if (++ParsedNum > 1)
  183. ParmsType += ", ";
  184. switch (Value & TracebackTable::ParmTypeMask) {
  185. case TracebackTable::ParmTypeIsFixedBits:
  186. ParmsType += "i";
  187. ++ParsedFixedNum;
  188. break;
  189. case TracebackTable::ParmTypeIsVectorBits:
  190. ParmsType += "v";
  191. ++ParsedVectorNum;
  192. break;
  193. case TracebackTable::ParmTypeIsFloatingBits:
  194. ParmsType += "f";
  195. ++ParsedFloatingNum;
  196. break;
  197. case TracebackTable::ParmTypeIsDoubleBits:
  198. ParmsType += "d";
  199. ++ParsedFloatingNum;
  200. break;
  201. default:
  202. assert(false && "Unrecognized bits in ParmsType.");
  203. }
  204. Value <<= 2;
  205. }
  206. // We have more parameters than the 32 Bits could encode.
  207. if (ParsedNum < ParmsNum)
  208. ParmsType += ", ...";
  209. if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
  210. ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)
  211. return createStringError(
  212. errc::invalid_argument,
  213. "ParmsType encodes can not map to ParmsNum parameters "
  214. "in parseParmsTypeWithVecInfo.");
  215. return ParmsType;
  216. }
  217. Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,
  218. unsigned ParmsNum) {
  219. SmallString<32> ParmsType;
  220. unsigned ParsedNum = 0;
  221. for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {
  222. if (++ParsedNum > 1)
  223. ParmsType += ", ";
  224. switch (Value & TracebackTable::ParmTypeMask) {
  225. case TracebackTable::ParmTypeIsVectorCharBit:
  226. ParmsType += "vc";
  227. break;
  228. case TracebackTable::ParmTypeIsVectorShortBit:
  229. ParmsType += "vs";
  230. break;
  231. case TracebackTable::ParmTypeIsVectorIntBit:
  232. ParmsType += "vi";
  233. break;
  234. case TracebackTable::ParmTypeIsVectorFloatBit:
  235. ParmsType += "vf";
  236. break;
  237. }
  238. Value <<= 2;
  239. }
  240. // We have more parameters than the 32 Bits could encode.
  241. if (ParsedNum < ParmsNum)
  242. ParmsType += ", ...";
  243. if (Value != 0u)
  244. return createStringError(errc::invalid_argument,
  245. "ParmsType encodes more than ParmsNum parameters "
  246. "in parseVectorParmsType.");
  247. return ParmsType;
  248. }