Skip to content

Commit c3988b4

Browse files
committed
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. llvm-svn: 205081
1 parent 9086f06 commit c3988b4

File tree

6 files changed

+62
-5
lines changed

6 files changed

+62
-5
lines changed

llvm/include/llvm/MC/MCAsmInfo.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ namespace llvm {
116116
/// file.
117117
const char *PrivateGlobalPrefix; // Defaults to "L"
118118

119+
/// This prefix is used for symbols that should be passed through the
120+
/// assembler but be removed by the linker. This is 'l' on Darwin,
121+
/// currently used for some ObjC metadata.
122+
/// The default of "" meast that for this system a plain private symbol
123+
/// should be used.
124+
const char *LinkerPrivateGlobalPrefix; // Defaults to "".
125+
119126
/// InlineAsmStart/End - If these are nonempty, they contain a directive to
120127
/// emit before and after an inline assembly statement.
121128
const char *InlineAsmStart; // Defaults to "#APP\n"
@@ -425,6 +432,14 @@ namespace llvm {
425432
const char *getPrivateGlobalPrefix() const {
426433
return PrivateGlobalPrefix;
427434
}
435+
bool hasLinkerPrivateGlobalPrefix() const {
436+
return LinkerPrivateGlobalPrefix[0] != '\0';
437+
}
438+
const char *getLinkerPrivateGlobalPrefix() const {
439+
if (hasLinkerPrivateGlobalPrefix())
440+
return LinkerPrivateGlobalPrefix;
441+
return getPrivateGlobalPrefix();
442+
}
428443
const char *getInlineAsmStart() const {
429444
return InlineAsmStart;
430445
}

llvm/include/llvm/MC/MCContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ namespace llvm {
193193
/// @name Symbol Management
194194
/// @{
195195

196+
/// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary
197+
/// symbol with a unique but unspecified name.
198+
MCSymbol *CreateLinkerPrivateTempSymbol();
199+
196200
/// CreateTempSymbol - Create and return a new assembler temporary symbol
197201
/// with a unique but unspecified name.
198202
MCSymbol *CreateTempSymbol();

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,8 @@ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
758758
/// Takes ownership of \p TAB and \p CE.
759759
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
760760
raw_ostream &OS, MCCodeEmitter *CE,
761-
bool RelaxAll = false);
761+
bool RelaxAll = false,
762+
bool LabelSections = false);
762763

763764
/// createWinCOFFStreamer - Create a machine code streamer which will
764765
/// generate Microsoft COFF format object files.

llvm/lib/MC/MCAsmInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ MCAsmInfo::MCAsmInfo() {
4141
LabelSuffix = ":";
4242
DebugLabelSuffix = ":";
4343
PrivateGlobalPrefix = "L";
44+
LinkerPrivateGlobalPrefix = "";
4445
InlineAsmStart = "APP";
4546
InlineAsmEnd = "NO_APP";
4647
Code16Directive = ".code16";

llvm/lib/MC/MCContext.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
153153
return GetOrCreateSymbol(Name.toStringRef(NameSV));
154154
}
155155

156+
MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() {
157+
SmallString<128> NameSV;
158+
raw_svector_ostream(NameSV)
159+
<< MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++;
160+
return CreateSymbol(NameSV);
161+
}
162+
156163
MCSymbol *MCContext::CreateTempSymbol() {
157164
SmallString<128> NameSV;
158165
raw_svector_ostream(NameSV)

llvm/lib/MC/MCMachOStreamer.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
//===----------------------------------------------------------------------===//
99

1010
#include "llvm/MC/MCStreamer.h"
11+
#include "llvm/ADT/DenseMap.h"
12+
#include "llvm/ADT/SmallVector.h"
1113
#include "llvm/MC/MCAsmBackend.h"
1214
#include "llvm/MC/MCAssembler.h"
1315
#include "llvm/MC/MCCodeEmitter.h"
@@ -31,18 +33,31 @@ namespace {
3133

3234
class MCMachOStreamer : public MCObjectStreamer {
3335
private:
36+
/// LabelSections - true if each section change should emit a linker local
37+
/// label for use in relocations for assembler local references. Obviates the
38+
/// need for local relocations. False by default.
39+
bool LabelSections;
40+
41+
/// HasSectionLabel - map of which sections have already had a non-local
42+
/// label emitted to them. Used so we don't emit extraneous linker local
43+
/// labels in the middle of the section.
44+
DenseMap<const MCSection*, bool> HasSectionLabel;
45+
3446
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
3547

3648
void EmitDataRegion(DataRegionData::KindTy Kind);
3749
void EmitDataRegionEnd();
50+
3851
public:
3952
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
40-
MCCodeEmitter *Emitter)
41-
: MCObjectStreamer(Context, MAB, OS, Emitter) {}
53+
MCCodeEmitter *Emitter, bool label)
54+
: MCObjectStreamer(Context, MAB, OS, Emitter),
55+
LabelSections(label) {}
4256

4357
/// @name MCStreamer Interface
4458
/// @{
4559

60+
void ChangeSection(const MCSection *Sect, const MCExpr *Subsect) override;
4661
void EmitLabel(MCSymbol *Symbol) override;
4762
void EmitDebugLabel(MCSymbol *Symbol) override;
4863
void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
@@ -94,6 +109,19 @@ class MCMachOStreamer : public MCObjectStreamer {
94109

95110
} // end anonymous namespace.
96111

112+
void MCMachOStreamer::ChangeSection(const MCSection *Section,
113+
const MCExpr *Subsection) {
114+
// Change the section normally.
115+
MCObjectStreamer::ChangeSection(Section, Subsection);
116+
// Output a linker-local symbol so we don't need section-relative local
117+
// relocations. The linker hates us when we do that.
118+
if (LabelSections && !HasSectionLabel[Section]) {
119+
MCSymbol *Label = getContext().CreateLinkerPrivateTempSymbol();
120+
EmitLabel(Label);
121+
HasSectionLabel[Section] = true;
122+
}
123+
}
124+
97125
void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
98126
MCSymbol *EHSymbol) {
99127
MCSymbolData &SD =
@@ -425,8 +453,9 @@ void MCMachOStreamer::FinishImpl() {
425453

426454
MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
427455
raw_ostream &OS, MCCodeEmitter *CE,
428-
bool RelaxAll) {
429-
MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE);
456+
bool RelaxAll,
457+
bool LabelSections) {
458+
MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections);
430459
if (RelaxAll)
431460
S->getAssembler().setRelaxAll(true);
432461
return S;

0 commit comments

Comments
 (0)