LLVM 24.0.0git
CSKYELFStreamer.cpp
Go to the documentation of this file.
1//===-- CSKYELFStreamer.cpp - CSKY ELF Target Streamer Methods ------------===//
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// This file provides CSKY specific target streamer methods.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CSKYELFStreamer.h"
14#include "CSKYMCTargetDesc.h"
18#include "llvm/MC/MCAssembler.h"
19#include "llvm/MC/MCContext.h"
23#include "llvm/MC/MCSymbolELF.h"
25#include "llvm/Support/LEB128.h"
26
27using namespace llvm;
28
29// This part is for ELF object output.
31 const MCSubtargetInfo &STI)
32 : CSKYTargetStreamer(S), CurrentVendor("csky") {
34 const FeatureBitset &Features = STI.getFeatureBits();
35
36 unsigned EFlags = W.getELFHeaderEFlags();
37
38 EFlags |= ELF::EF_CSKY_ABIV2;
39
40 if (Features[CSKY::ProcCK801])
41 EFlags |= ELF::EF_CSKY_801;
42 else if (Features[CSKY::ProcCK802])
43 EFlags |= ELF::EF_CSKY_802;
44 else if (Features[CSKY::ProcCK803])
45 EFlags |= ELF::EF_CSKY_803;
46 else if (Features[CSKY::ProcCK804])
47 EFlags |= ELF::EF_CSKY_803;
48 else if (Features[CSKY::ProcCK805])
49 EFlags |= ELF::EF_CSKY_805;
50 else if (Features[CSKY::ProcCK807])
51 EFlags |= ELF::EF_CSKY_807;
52 else if (Features[CSKY::ProcCK810])
53 EFlags |= ELF::EF_CSKY_810;
54 else if (Features[CSKY::ProcCK860])
55 EFlags |= ELF::EF_CSKY_860;
56 else
57 EFlags |= ELF::EF_CSKY_810;
58
59 if (Features[CSKY::FeatureFPUV2_SF] || Features[CSKY::FeatureFPUV3_SF])
60 EFlags |= ELF::EF_CSKY_FLOAT;
61
62 EFlags |= ELF::EF_CSKY_EFV1;
63
64 W.setELFHeaderEFlags(EFlags);
65}
66
70
71void CSKYTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
72 setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
73}
74
75void CSKYTargetELFStreamer::emitTextAttribute(unsigned Attribute,
77 setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
78}
79
81 if (Contents.empty())
82 return;
83
84 if (AttributeSection) {
85 Streamer.switchSection(AttributeSection);
86 } else {
87 MCAssembler &MCA = getStreamer().getAssembler();
88 AttributeSection = MCA.getContext().getELFSection(
89 ".csky.attributes", ELF::SHT_CSKY_ATTRIBUTES, 0);
90 Streamer.switchSection(AttributeSection);
92 }
93
94 // Vendor size + Vendor name + '\0'
95 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
96
97 // Tag + Tag Size
98 const size_t TagHeaderSize = 1 + 4;
99
100 const size_t ContentsSize = calculateContentSize();
101
102 Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
103 Streamer.emitBytes(CurrentVendor);
104 Streamer.emitInt8(0); // '\0'
105
106 Streamer.emitInt8(ELFAttrs::File);
107 Streamer.emitInt32(TagHeaderSize + ContentsSize);
108
109 // Size should have been accounted for already, now
110 // emit each field as its type (ULEB or String).
111 for (AttributeItem item : Contents) {
112 Streamer.emitULEB128IntValue(item.Tag);
113 switch (item.Type) {
114 default:
115 llvm_unreachable("Invalid attribute type");
116 case AttributeType::Numeric:
117 Streamer.emitULEB128IntValue(item.IntValue);
118 break;
119 case AttributeType::Text:
120 Streamer.emitBytes(item.StringValue);
121 Streamer.emitInt8(0); // '\0'
122 break;
123 case AttributeType::NumericAndText:
124 Streamer.emitULEB128IntValue(item.IntValue);
125 Streamer.emitBytes(item.StringValue);
126 Streamer.emitInt8(0); // '\0'
127 break;
128 }
129 }
130
131 Contents.clear();
132}
133
134size_t CSKYTargetELFStreamer::calculateContentSize() const {
135 size_t Result = 0;
136 for (AttributeItem item : Contents) {
137 switch (item.Type) {
138 case AttributeType::Hidden:
139 break;
140 case AttributeType::Numeric:
141 Result += getULEB128Size(item.Tag);
142 Result += getULEB128Size(item.IntValue);
143 break;
144 case AttributeType::Text:
145 Result += getULEB128Size(item.Tag);
146 Result += item.StringValue.size() + 1; // string + '\0'
147 break;
148 case AttributeType::NumericAndText:
149 Result += getULEB128Size(item.Tag);
150 Result += getULEB128Size(item.IntValue);
151 Result += item.StringValue.size() + 1; // string + '\0';
152 break;
153 }
154 }
155 return Result;
156}
157
158void CSKYELFStreamer::EmitMappingSymbol(StringRef Name) {
159 if (Name == "$d" && State == EMS_Data)
160 return;
161 if (Name == "$t" && State == EMS_Text)
162 return;
163 if (Name == "$t" && State == EMS_None) {
164 State = EMS_Text;
165 return;
166 }
167
168 State = (Name == "$t" ? EMS_Text : EMS_Data);
169
170 auto *Symbol =
171 static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));
172 emitLabel(Symbol);
173
174 Symbol->setType(ELF::STT_NOTYPE);
175 Symbol->setBinding(ELF::STB_LOCAL);
176}
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
ElfMappingSymbol State
CSKYTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI)
Container class for subtarget features.
MCContext & getContext() const
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition MCContext.h:550
LLVM_ABI MCSymbol * createLocalSymbol(StringRef Name)
Create a local, non-temporary symbol like an ELF mapping symbol.
ELFObjectWriter & getWriter()
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
MCAssembler & getAssembler()
Streaming machine code generation interface.
Definition MCStreamer.h:222
MCContext & getContext() const
Definition MCStreamer.h:326
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
MCStreamer & Streamer
Definition MCStreamer.h:97
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ SHT_CSKY_ATTRIBUTES
Definition ELF.h:1243
@ STB_LOCAL
Definition ELF.h:1414
@ EF_CSKY_ABIV2
Definition ELF.h:1058
@ EF_CSKY_807
Definition ELF.h:1052
@ EF_CSKY_802
Definition ELF.h:1049
@ EF_CSKY_FLOAT
Definition ELF.h:1056
@ EF_CSKY_801
Definition ELF.h:1048
@ EF_CSKY_EFV1
Definition ELF.h:1059
@ EF_CSKY_805
Definition ELF.h:1051
@ EF_CSKY_860
Definition ELF.h:1054
@ EF_CSKY_803
Definition ELF.h:1050
@ EF_CSKY_810
Definition ELF.h:1053
@ STT_NOTYPE
Definition ELF.h:1426
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition LEB128.cpp:19