1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00
llvm-mirror/include/llvm/MC/MCELFStreamer.h
Jonas Paulsson 38b768656f [MCStreamer] Move emission of attributes section into MCELFStreamer
Enable the emission of a GNU attributes section by reusing the code for
emitting the ARM build attributes section.

The GNU attributes follow the exact same section format as the ARM
BuildAttributes section, so this can be factored out and reused for GNU
attributes generally.

The immediate motivation for this is to emit a GNU attributes section for the
vector ABI on SystemZ (https://reviews.llvm.org/D105067).

Review: Logan Chien, Ulrich Weigand

Differential Revision: https://reviews.llvm.org/D102894
2021-06-30 16:00:27 -05:00

157 lines
5.9 KiB
C++

//===- 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/BinaryFormat/ELF.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectStreamer.h"
namespace llvm {
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) 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