xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCSectionGOFF.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- MCSectionGOFF.cpp - GOFF Code Section Representation ---------------===//
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/MC/MCSectionGOFF.h"
10 #include "llvm/BinaryFormat/GOFF.h"
11 #include "llvm/Support/raw_ostream.h"
12 
13 using namespace llvm;
14 
emitCATTR(raw_ostream & OS,StringRef Name,GOFF::ESDRmode Rmode,GOFF::ESDAlignment Alignment,GOFF::ESDLoadingBehavior LoadBehavior,GOFF::ESDExecutable Executable,bool IsReadOnly,uint32_t SortKey,uint8_t FillByteValue,StringRef PartName)15 static void emitCATTR(raw_ostream &OS, StringRef Name, GOFF::ESDRmode Rmode,
16                       GOFF::ESDAlignment Alignment,
17                       GOFF::ESDLoadingBehavior LoadBehavior,
18                       GOFF::ESDExecutable Executable, bool IsReadOnly,
19                       uint32_t SortKey, uint8_t FillByteValue,
20                       StringRef PartName) {
21   OS << Name << " CATTR ";
22   OS << "ALIGN(" << static_cast<unsigned>(Alignment) << "),"
23      << "FILL(" << static_cast<unsigned>(FillByteValue) << ")";
24   switch (LoadBehavior) {
25   case GOFF::ESD_LB_Deferred:
26     OS << ",DEFLOAD";
27     break;
28   case GOFF::ESD_LB_NoLoad:
29     OS << ",NOLOAD";
30     break;
31   default:
32     break;
33   }
34   switch (Executable) {
35   case GOFF::ESD_EXE_CODE:
36     OS << ",EXECUTABLE";
37     break;
38   case GOFF::ESD_EXE_DATA:
39     OS << ",NOTEXECUTABLE";
40     break;
41   default:
42     break;
43   }
44   if (IsReadOnly)
45     OS << ",READONLY";
46   if (Rmode != GOFF::ESD_RMODE_None) {
47     OS << ',';
48     OS << "RMODE(";
49     switch (Rmode) {
50     case GOFF::ESD_RMODE_24:
51       OS << "24";
52       break;
53     case GOFF::ESD_RMODE_31:
54       OS << "31";
55       break;
56     case GOFF::ESD_RMODE_64:
57       OS << "64";
58       break;
59     case GOFF::ESD_RMODE_None:
60       break;
61     }
62     OS << ')';
63   }
64   if (SortKey)
65     OS << ",PRIORITY(" << SortKey << ")";
66   if (!PartName.empty())
67     OS << ",PART(" << PartName << ")";
68   OS << '\n';
69 }
70 
emitXATTR(raw_ostream & OS,StringRef Name,GOFF::ESDLinkageType Linkage,GOFF::ESDExecutable Executable,GOFF::ESDBindingScope BindingScope)71 static void emitXATTR(raw_ostream &OS, StringRef Name,
72                       GOFF::ESDLinkageType Linkage,
73                       GOFF::ESDExecutable Executable,
74                       GOFF::ESDBindingScope BindingScope) {
75   OS << Name << " XATTR ";
76   OS << "LINKAGE(" << (Linkage == GOFF::ESD_LT_OS ? "OS" : "XPLINK") << "),";
77   if (Executable != GOFF::ESD_EXE_Unspecified)
78     OS << "REFERENCE(" << (Executable == GOFF::ESD_EXE_CODE ? "CODE" : "DATA")
79        << "),";
80   if (BindingScope != GOFF::ESD_BSC_Unspecified) {
81     OS << "SCOPE(";
82     switch (BindingScope) {
83     case GOFF::ESD_BSC_Section:
84       OS << "SECTION";
85       break;
86     case GOFF::ESD_BSC_Module:
87       OS << "MODULE";
88       break;
89     case GOFF::ESD_BSC_Library:
90       OS << "LIBRARY";
91       break;
92     case GOFF::ESD_BSC_ImportExport:
93       OS << "EXPORT";
94       break;
95     default:
96       break;
97     }
98     OS << ')';
99   }
100   OS << '\n';
101 }
102 
printSwitchToSection(const MCAsmInfo & MAI,const Triple & T,raw_ostream & OS,uint32_t Subsection) const103 void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
104                                          raw_ostream &OS,
105                                          uint32_t Subsection) const {
106   switch (SymbolType) {
107   case GOFF::ESD_ST_SectionDefinition: {
108     OS << Name << " CSECT\n";
109     Emitted = true;
110     break;
111   }
112   case GOFF::ESD_ST_ElementDefinition: {
113     getParent()->printSwitchToSection(MAI, T, OS, Subsection);
114     if (!Emitted) {
115       emitCATTR(OS, Name, EDAttributes.Rmode, EDAttributes.Alignment,
116                 EDAttributes.LoadBehavior, GOFF::ESD_EXE_Unspecified,
117                 EDAttributes.IsReadOnly, 0, EDAttributes.FillByteValue,
118                 StringRef());
119       Emitted = true;
120     } else
121       OS << Name << " CATTR\n";
122     break;
123   }
124   case GOFF::ESD_ST_PartReference: {
125     MCSectionGOFF *ED = getParent();
126     ED->getParent()->printSwitchToSection(MAI, T, OS, Subsection);
127     if (!Emitted) {
128       emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode,
129                 ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior,
130                 PRAttributes.Executable, ED->EDAttributes.IsReadOnly,
131                 PRAttributes.SortKey, ED->EDAttributes.FillByteValue, Name);
132       emitXATTR(OS, Name, PRAttributes.Linkage, PRAttributes.Executable,
133                 PRAttributes.BindingScope);
134       ED->Emitted = true;
135       Emitted = true;
136     } else
137       OS << ED->getName() << " CATTR PART(" << Name << ")\n";
138     break;
139   }
140   default:
141     llvm_unreachable("Wrong section type");
142   }
143 }