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 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 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 103 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 }