mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-20 14:29:27 +00:00
MachO: allow each section to have a linker-private symbol
The upcoming ARM64 backend doesn't have section-relative relocations, so we give each section its own symbol to provide this functionality. Of course, it doesn't need to appear in the final executable, so linker-private is the best kind for this purpose. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205081 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
42529ad33a
commit
c5d592d5d2
@ -116,6 +116,13 @@ namespace llvm {
|
|||||||
/// file.
|
/// file.
|
||||||
const char *PrivateGlobalPrefix; // Defaults to "L"
|
const char *PrivateGlobalPrefix; // Defaults to "L"
|
||||||
|
|
||||||
|
/// This prefix is used for symbols that should be passed through the
|
||||||
|
/// assembler but be removed by the linker. This is 'l' on Darwin,
|
||||||
|
/// currently used for some ObjC metadata.
|
||||||
|
/// The default of "" meast that for this system a plain private symbol
|
||||||
|
/// should be used.
|
||||||
|
const char *LinkerPrivateGlobalPrefix; // Defaults to "".
|
||||||
|
|
||||||
/// InlineAsmStart/End - If these are nonempty, they contain a directive to
|
/// InlineAsmStart/End - If these are nonempty, they contain a directive to
|
||||||
/// emit before and after an inline assembly statement.
|
/// emit before and after an inline assembly statement.
|
||||||
const char *InlineAsmStart; // Defaults to "#APP\n"
|
const char *InlineAsmStart; // Defaults to "#APP\n"
|
||||||
@ -425,6 +432,14 @@ namespace llvm {
|
|||||||
const char *getPrivateGlobalPrefix() const {
|
const char *getPrivateGlobalPrefix() const {
|
||||||
return PrivateGlobalPrefix;
|
return PrivateGlobalPrefix;
|
||||||
}
|
}
|
||||||
|
bool hasLinkerPrivateGlobalPrefix() const {
|
||||||
|
return LinkerPrivateGlobalPrefix[0] != '\0';
|
||||||
|
}
|
||||||
|
const char *getLinkerPrivateGlobalPrefix() const {
|
||||||
|
if (hasLinkerPrivateGlobalPrefix())
|
||||||
|
return LinkerPrivateGlobalPrefix;
|
||||||
|
return getPrivateGlobalPrefix();
|
||||||
|
}
|
||||||
const char *getInlineAsmStart() const {
|
const char *getInlineAsmStart() const {
|
||||||
return InlineAsmStart;
|
return InlineAsmStart;
|
||||||
}
|
}
|
||||||
|
@ -193,6 +193,10 @@ namespace llvm {
|
|||||||
/// @name Symbol Management
|
/// @name Symbol Management
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
/// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary
|
||||||
|
/// symbol with a unique but unspecified name.
|
||||||
|
MCSymbol *CreateLinkerPrivateTempSymbol();
|
||||||
|
|
||||||
/// CreateTempSymbol - Create and return a new assembler temporary symbol
|
/// CreateTempSymbol - Create and return a new assembler temporary symbol
|
||||||
/// with a unique but unspecified name.
|
/// with a unique but unspecified name.
|
||||||
MCSymbol *CreateTempSymbol();
|
MCSymbol *CreateTempSymbol();
|
||||||
|
@ -758,7 +758,8 @@ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
|
|||||||
/// Takes ownership of \p TAB and \p CE.
|
/// Takes ownership of \p TAB and \p CE.
|
||||||
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
|
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
|
||||||
raw_ostream &OS, MCCodeEmitter *CE,
|
raw_ostream &OS, MCCodeEmitter *CE,
|
||||||
bool RelaxAll = false);
|
bool RelaxAll = false,
|
||||||
|
bool LabelSections = false);
|
||||||
|
|
||||||
/// createWinCOFFStreamer - Create a machine code streamer which will
|
/// createWinCOFFStreamer - Create a machine code streamer which will
|
||||||
/// generate Microsoft COFF format object files.
|
/// generate Microsoft COFF format object files.
|
||||||
|
@ -41,6 +41,7 @@ MCAsmInfo::MCAsmInfo() {
|
|||||||
LabelSuffix = ":";
|
LabelSuffix = ":";
|
||||||
DebugLabelSuffix = ":";
|
DebugLabelSuffix = ":";
|
||||||
PrivateGlobalPrefix = "L";
|
PrivateGlobalPrefix = "L";
|
||||||
|
LinkerPrivateGlobalPrefix = "";
|
||||||
InlineAsmStart = "APP";
|
InlineAsmStart = "APP";
|
||||||
InlineAsmEnd = "NO_APP";
|
InlineAsmEnd = "NO_APP";
|
||||||
Code16Directive = ".code16";
|
Code16Directive = ".code16";
|
||||||
|
@ -153,6 +153,13 @@ MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
|
|||||||
return GetOrCreateSymbol(Name.toStringRef(NameSV));
|
return GetOrCreateSymbol(Name.toStringRef(NameSV));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() {
|
||||||
|
SmallString<128> NameSV;
|
||||||
|
raw_svector_ostream(NameSV)
|
||||||
|
<< MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
|
||||||
|
return CreateSymbol(NameSV);
|
||||||
|
}
|
||||||
|
|
||||||
MCSymbol *MCContext::CreateTempSymbol() {
|
MCSymbol *MCContext::CreateTempSymbol() {
|
||||||
SmallString<128> NameSV;
|
SmallString<128> NameSV;
|
||||||
raw_svector_ostream(NameSV)
|
raw_svector_ostream(NameSV)
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/MC/MCStreamer.h"
|
#include "llvm/MC/MCStreamer.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/MC/MCAsmBackend.h"
|
#include "llvm/MC/MCAsmBackend.h"
|
||||||
#include "llvm/MC/MCAssembler.h"
|
#include "llvm/MC/MCAssembler.h"
|
||||||
#include "llvm/MC/MCCodeEmitter.h"
|
#include "llvm/MC/MCCodeEmitter.h"
|
||||||
@ -31,18 +33,31 @@ namespace {
|
|||||||
|
|
||||||
class MCMachOStreamer : public MCObjectStreamer {
|
class MCMachOStreamer : public MCObjectStreamer {
|
||||||
private:
|
private:
|
||||||
|
/// LabelSections - true if each section change should emit a linker local
|
||||||
|
/// label for use in relocations for assembler local references. Obviates the
|
||||||
|
/// need for local relocations. False by default.
|
||||||
|
bool LabelSections;
|
||||||
|
|
||||||
|
/// HasSectionLabel - map of which sections have already had a non-local
|
||||||
|
/// label emitted to them. Used so we don't emit extraneous linker local
|
||||||
|
/// labels in the middle of the section.
|
||||||
|
DenseMap<const MCSection*, bool> HasSectionLabel;
|
||||||
|
|
||||||
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
|
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
|
||||||
|
|
||||||
void EmitDataRegion(DataRegionData::KindTy Kind);
|
void EmitDataRegion(DataRegionData::KindTy Kind);
|
||||||
void EmitDataRegionEnd();
|
void EmitDataRegionEnd();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
|
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
|
||||||
MCCodeEmitter *Emitter)
|
MCCodeEmitter *Emitter, bool label)
|
||||||
: MCObjectStreamer(Context, MAB, OS, Emitter) {}
|
: MCObjectStreamer(Context, MAB, OS, Emitter),
|
||||||
|
LabelSections(label) {}
|
||||||
|
|
||||||
/// @name MCStreamer Interface
|
/// @name MCStreamer Interface
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
void ChangeSection(const MCSection *Sect, const MCExpr *Subsect) override;
|
||||||
void EmitLabel(MCSymbol *Symbol) override;
|
void EmitLabel(MCSymbol *Symbol) override;
|
||||||
void EmitDebugLabel(MCSymbol *Symbol) override;
|
void EmitDebugLabel(MCSymbol *Symbol) override;
|
||||||
void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
|
void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
|
||||||
@ -94,6 +109,19 @@ public:
|
|||||||
|
|
||||||
} // end anonymous namespace.
|
} // end anonymous namespace.
|
||||||
|
|
||||||
|
void MCMachOStreamer::ChangeSection(const MCSection *Section,
|
||||||
|
const MCExpr *Subsection) {
|
||||||
|
// Change the section normally.
|
||||||
|
MCObjectStreamer::ChangeSection(Section, Subsection);
|
||||||
|
// Output a linker-local symbol so we don't need section-relative local
|
||||||
|
// relocations. The linker hates us when we do that.
|
||||||
|
if (LabelSections && !HasSectionLabel[Section]) {
|
||||||
|
MCSymbol *Label = getContext().CreateLinkerPrivateTempSymbol();
|
||||||
|
EmitLabel(Label);
|
||||||
|
HasSectionLabel[Section] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
|
void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
|
||||||
MCSymbol *EHSymbol) {
|
MCSymbol *EHSymbol) {
|
||||||
MCSymbolData &SD =
|
MCSymbolData &SD =
|
||||||
@ -425,8 +453,9 @@ void MCMachOStreamer::FinishImpl() {
|
|||||||
|
|
||||||
MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
|
MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
|
||||||
raw_ostream &OS, MCCodeEmitter *CE,
|
raw_ostream &OS, MCCodeEmitter *CE,
|
||||||
bool RelaxAll) {
|
bool RelaxAll,
|
||||||
MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE);
|
bool LabelSections) {
|
||||||
|
MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
|
||||||
if (RelaxAll)
|
if (RelaxAll)
|
||||||
S->getAssembler().setRelaxAll(true);
|
S->getAssembler().setRelaxAll(true);
|
||||||
return S;
|
return S;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user