1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCELFSTREAMER_H
#define LLVM_MC_MCELFSTREAMER_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectStreamer.h"
namespace llvm {
class MCContext;
class MCDataFragment;
class MCFragment;
class MCObjectWriter;
class MCSection;
class MCSubtargetInfo;
class MCSymbol;
class MCSymbolRefExpr;
class MCAsmBackend;
class MCCodeEmitter;
class MCExpr;
class MCInst;
class MCELFStreamer : public MCObjectStreamer {
public:
MCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
std::unique_ptr<MCObjectWriter> OW,
std::unique_ptr<MCCodeEmitter> Emitter);
~MCELFStreamer() override = default;
/// state management
void reset() override {
SeenIdent = false;
BundleGroups.clear();
MCObjectStreamer::reset();
}
/// \name MCStreamer Interface
/// @{
void initSections(bool NoExecStack, const MCSubtargetInfo &STI) override;
void changeSection(MCSection *Section, const MCExpr *Subsection) override;
void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
uint64_t Offset) override;
void emitAssemblerFlag(MCAssemblerFlag Flag) override;
void emitThumbFunc(MCSymbol *Func) override;
void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,
bool KeepOriginalSym) override;
void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, unsigned ByteAlignment = 0,
SMLoc L = SMLoc()) override;
void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment = 0) override;
void emitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override;
void emitIdent(StringRef IdentString) override;
void emitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
void emitCGProfileEntry(const MCSymbolRefExpr *From,
const MCSymbolRefExpr *To, uint64_t Count) override;
void finishImpl() override;
void emitBundleAlignMode(unsigned AlignPow2) override;
void emitBundleLock(bool AlignToEnd) override;
void emitBundleUnlock() override;
/// ELF object attributes section emission support
struct AttributeItem {
// This structure holds all attributes, accounting for their string /
// numeric value, so we can later emit them in declaration order, keeping
// all in the same vector.
enum {
HiddenAttribute = 0,
NumericAttribute,
TextAttribute,
NumericAndTextAttributes
} Type;
unsigned Tag;
unsigned IntValue;
std::string StringValue;
};
// Attributes that are added and managed entirely by target.
SmallVector<AttributeItem, 64> Contents;
void setAttributeItem(unsigned Attribute, unsigned Value,
bool OverwriteExisting);
void setAttributeItem(unsigned Attribute, StringRef Value,
bool OverwriteExisting);
void setAttributeItems(unsigned Attribute, unsigned IntValue,
StringRef StringValue, bool OverwriteExisting);
void emitAttributesSection(StringRef Vendor, const Twine &Section,
unsigned Type, MCSection *&AttributeSection) {
createAttributesSection(Vendor, Section, Type, AttributeSection, Contents);
}
private:
AttributeItem *getAttributeItem(unsigned Attribute);
size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec);
void createAttributesSection(StringRef Vendor, const Twine &Section,
unsigned Type, MCSection *&AttributeSection,
SmallVector<AttributeItem, 64> &AttrsVec);
// GNU attributes that will get emitted at the end of the asm file.
SmallVector<AttributeItem, 64> GNUAttributes;
public:
void emitGNUAttribute(unsigned Tag, unsigned Value) override {
AttributeItem Item = {AttributeItem::NumericAttribute, Tag, Value,
std::string(StringRef(""))};
GNUAttributes.push_back(Item);
}
private:
bool isBundleLocked() const;
void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
void fixSymbolsInTLSFixups(const MCExpr *expr);
void finalizeCGProfileEntry(const MCSymbolRefExpr *&S, uint64_t Offset);
void finalizeCGProfile();
/// Merge the content of the fragment \p EF into the fragment \p DF.
void mergeFragment(MCDataFragment *, MCDataFragment *);
bool SeenIdent = false;
/// BundleGroups - The stack of fragments holding the bundle-locked
/// instructions.
SmallVector<MCDataFragment *, 4> BundleGroups;
};
MCELFStreamer *createARMELFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> TAB,
std::unique_ptr<MCObjectWriter> OW,
std::unique_ptr<MCCodeEmitter> Emitter,
bool RelaxAll, bool IsThumb, bool IsAndroid);
} // end namespace llvm
#endif // LLVM_MC_MCELFSTREAMER_H
|