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 
9 #include "llvm/BinaryFormat/XCOFF.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/StringRef.h"
12 
13 using namespace llvm;
14 
15 #define SMC_CASE(A)                                                            \
16   case XCOFF::XMC_##A:                                                         \
17     return #A;
18 StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) {
19   switch (SMC) {
20     SMC_CASE(PR)
21     SMC_CASE(RO)
22     SMC_CASE(DB)
23     SMC_CASE(GL)
24     SMC_CASE(XO)
25     SMC_CASE(SV)
26     SMC_CASE(SV64)
27     SMC_CASE(SV3264)
28     SMC_CASE(TI)
29     SMC_CASE(TB)
30     SMC_CASE(RW)
31     SMC_CASE(TC0)
32     SMC_CASE(TC)
33     SMC_CASE(TD)
34     SMC_CASE(DS)
35     SMC_CASE(UA)
36     SMC_CASE(BS)
37     SMC_CASE(UC)
38     SMC_CASE(TL)
39     SMC_CASE(UL)
40     SMC_CASE(TE)
41 #undef SMC_CASE
42   }
43 
44   // TODO: need to add a test case for "Unknown" and other SMC.
45   return "Unknown";
46 }
47 
48 #define RELOC_CASE(A)                                                          \
49   case XCOFF::A:                                                               \
50     return #A;
51 StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
52   switch (Type) {
53     RELOC_CASE(R_POS)
54     RELOC_CASE(R_RL)
55     RELOC_CASE(R_RLA)
56     RELOC_CASE(R_NEG)
57     RELOC_CASE(R_REL)
58     RELOC_CASE(R_TOC)
59     RELOC_CASE(R_TRL)
60     RELOC_CASE(R_TRLA)
61     RELOC_CASE(R_GL)
62     RELOC_CASE(R_TCL)
63     RELOC_CASE(R_REF)
64     RELOC_CASE(R_BA)
65     RELOC_CASE(R_BR)
66     RELOC_CASE(R_RBA)
67     RELOC_CASE(R_RBR)
68     RELOC_CASE(R_TLS)
69     RELOC_CASE(R_TLS_IE)
70     RELOC_CASE(R_TLS_LD)
71     RELOC_CASE(R_TLS_LE)
72     RELOC_CASE(R_TLSM)
73     RELOC_CASE(R_TLSML)
74     RELOC_CASE(R_TOCU)
75     RELOC_CASE(R_TOCL)
76   }
77   return "Unknown";
78 }
79 
80 #define LANG_CASE(A)                                                           \
81   case XCOFF::TracebackTable::A:                                               \
82     return #A;
83 
84 StringRef XCOFF::getNameForTracebackTableLanguageId(
85     XCOFF::TracebackTable::LanguageID LangId) {
86   switch (LangId) {
87     LANG_CASE(C)
88     LANG_CASE(Fortran)
89     LANG_CASE(Pascal)
90     LANG_CASE(Ada)
91     LANG_CASE(PL1)
92     LANG_CASE(Basic)
93     LANG_CASE(Lisp)
94     LANG_CASE(Cobol)
95     LANG_CASE(Modula2)
96     LANG_CASE(Rpg)
97     LANG_CASE(PL8)
98     LANG_CASE(Assembly)
99     LANG_CASE(Java)
100     LANG_CASE(ObjectiveC)
101     LANG_CASE(CPlusPlus)
102   }
103   return "Unknown";
104 }
105 #undef LANG_CASE
106 
107 SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
108   SmallString<32> ParmsType;
109   for (unsigned I = 0; I < ParmsNum; ++I) {
110     if (I != 0)
111       ParmsType += ", ";
112     if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
113       // Fixed parameter type.
114       ParmsType += "i";
115       Value <<= 1;
116     } else {
117       if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
118         // Float parameter type.
119         ParmsType += "f";
120       else
121         // Double parameter type.
122         ParmsType += "d";
123 
124       Value <<= 2;
125     }
126   }
127   assert(Value == 0u && "ParmsType encodes more than ParmsNum parameters.");
128   return ParmsType;
129 }
130 
131 SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
132   SmallString<32> Res;
133 
134   if (Flag & ExtendedTBTableFlag::TB_OS1)
135     Res += "TB_OS1 ";
136   if (Flag & ExtendedTBTableFlag::TB_RESERVED)
137     Res += "TB_RESERVED ";
138   if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY)
139     Res += "TB_SSP_CANARY ";
140   if (Flag & ExtendedTBTableFlag::TB_OS2)
141     Res += "TB_OS2 ";
142   if (Flag & ExtendedTBTableFlag::TB_EH_INFO)
143     Res += "TB_EH_INFO ";
144   if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2)
145     Res += "TB_LONGTBTABLE2 ";
146 
147   // Two of the bits that haven't got used in the mask.
148   if (Flag & 0x06)
149     Res += "Unknown ";
150 
151   // Pop the last space.
152   Res.pop_back();
153   return Res;
154 }
155 
156 #undef RELOC_CASE
157