Skip to content

Commit

Permalink
Reland r298901 with modifications (reverted in r298932)
Browse files Browse the repository at this point in the history
Dont emit Mapping symbols for sections that contain only data.

Summary:
Dont emit mapping symbols for sections that contain only data.

Reviewers: rengolin, weimingz, kparzysz, t.p.northover, peter.smith

Reviewed By: t.p.northover

Patched by Shankar Easwaran <shankare@codeaurora.org>

Subscribers: alekseyshl, t.p.northover, llvm-commits

Differential Revision: https://reviews.llvm.org/D30724

llvm-svn: 299392
  • Loading branch information
Weiming Zhao committed Apr 3, 2017
1 parent b600e13 commit 74a7fa0
Show file tree
Hide file tree
Showing 18 changed files with 180 additions and 37 deletions.
1 change: 1 addition & 0 deletions llvm/include/llvm/MC/MCELFStreamer.h
Expand Up @@ -42,6 +42,7 @@ class MCELFStreamer : public MCObjectStreamer {
void InitSections(bool NoExecStack) override;
void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitThumbFunc(MCSymbol *Func) override;
void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/MC/MCObjectStreamer.h
Expand Up @@ -90,6 +90,7 @@ class MCObjectStreamer : public MCStreamer {
/// @{

void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F);
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override;
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/MC/MCELFStreamer.cpp
Expand Up @@ -103,6 +103,16 @@ void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) {
Symbol->setType(ELF::STT_TLS);
}

void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc, MCFragment *F) {
auto *Symbol = cast<MCSymbolELF>(S);
MCObjectStreamer::EmitLabel(Symbol, Loc, F);

const MCSectionELF &Section =
static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
if (Section.getFlags() & ELF::SHF_TLS)
Symbol->setType(ELF::STT_TLS);
}

void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
// Let the target do whatever target specific stuff it needs to do.
getAssembler().getBackend().handleAssemblerFlag(Flag);
Expand Down
18 changes: 14 additions & 4 deletions llvm/lib/MC/MCObjectStreamer.cpp
Expand Up @@ -171,6 +171,16 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
}
}

void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
MCStreamer::EmitLabel(Symbol, Loc);
getAssembler().registerSymbol(*Symbol);
auto *DF = dyn_cast_or_null<MCDataFragment>(F);
if (DF)
Symbol->setFragment(F);
else
PendingLabels.push_back(Symbol);
}

void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
int64_t IntValue;
if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
Expand Down Expand Up @@ -491,8 +501,8 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
flushPendingLabels(DF, DF->getContents().size());

DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
Value, FK_GPRel_4));
DF->getFixups().push_back(
MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
DF->getContents().resize(DF->getContents().size() + 4, 0);
}

Expand All @@ -501,8 +511,8 @@ void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
MCDataFragment *DF = getOrCreateDataFragment();
flushPendingLabels(DF, DF->getContents().size());

DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
Value, FK_GPRel_4));
DF->getFixups().push_back(
MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
DF->getContents().resize(DF->getContents().size() + 8, 0);
}

Expand Down
86 changes: 71 additions & 15 deletions llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
Expand Up @@ -464,13 +464,14 @@ class ARMELFStreamer : public MCELFStreamer {
void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);

void ChangeSection(MCSection *Section, const MCExpr *Subsection) override {
// We have to keep track of the mapping symbol state of any sections we
// use. Each one should start off as EMS_None, which is provided as the
// default constructor by DenseMap::lookup.
LastMappingSymbols[getPreviousSection().first] = LastEMS;
LastEMS = LastMappingSymbols.lookup(Section);

LastMappingSymbols[getPreviousSection().first] = std::move(LastEMSInfo);
MCELFStreamer::ChangeSection(Section, Subsection);
auto LastMappingSymbol = LastMappingSymbols.find(Section);
if (LastMappingSymbol != LastMappingSymbols.end()) {
LastEMSInfo = std::move(LastMappingSymbol->second);
return;
}
LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
}

/// This function is the one used to emit instruction data into the ELF
Expand Down Expand Up @@ -532,15 +533,25 @@ class ARMELFStreamer : public MCELFStreamer {
MCELFStreamer::EmitBytes(Data);
}

void FlushPendingMappingSymbol() {
if (!LastEMSInfo->hasInfo())
return;
ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset);
EMS->resetInfo();
}

/// This is one of the functions used to emit data into an ELF section, so the
/// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
/// necessary.
void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value))
if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {
if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) {
getContext().reportError(Loc, "relocated expression must be 32-bit");
return;
}
getOrCreateDataFragment();
}

EmitDataMappingSymbol();
MCELFStreamer::EmitValueImpl(Value, Size, Loc);
Expand Down Expand Up @@ -573,22 +584,54 @@ class ARMELFStreamer : public MCELFStreamer {
EMS_Data
};

struct ElfMappingSymbolInfo {
explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O)
: Loc(Loc), F(F), Offset(O), State(EMS_None) {}
void resetInfo() {
F = nullptr;
Offset = 0;
}
bool hasInfo() { return F != nullptr; }
SMLoc Loc;
MCFragment *F;
uint64_t Offset;
ElfMappingSymbol State;
};

void EmitDataMappingSymbol() {
if (LastEMS == EMS_Data) return;
if (LastEMSInfo->State == EMS_Data)
return;
else if (LastEMSInfo->State == EMS_None) {
// This is a tentative symbol, it won't really be emitted until it's
// actually needed.
ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
if (!DF)
return;
EMS->Loc = SMLoc();
EMS->F = getCurrentFragment();
EMS->Offset = DF->getContents().size();
LastEMSInfo->State = EMS_Data;
return;
}
EmitMappingSymbol("$d");
LastEMS = EMS_Data;
LastEMSInfo->State = EMS_Data;
}

void EmitThumbMappingSymbol() {
if (LastEMS == EMS_Thumb) return;
if (LastEMSInfo->State == EMS_Thumb)
return;
FlushPendingMappingSymbol();
EmitMappingSymbol("$t");
LastEMS = EMS_Thumb;
LastEMSInfo->State = EMS_Thumb;
}

void EmitARMMappingSymbol() {
if (LastEMS == EMS_ARM) return;
if (LastEMSInfo->State == EMS_ARM)
return;
FlushPendingMappingSymbol();
EmitMappingSymbol("$a");
LastEMS = EMS_ARM;
LastEMSInfo->State = EMS_ARM;
}

void EmitMappingSymbol(StringRef Name) {
Expand All @@ -601,6 +644,17 @@ class ARMELFStreamer : public MCELFStreamer {
Symbol->setExternal(false);
}

void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F,
uint64_t Offset) {
auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
Name + "." + Twine(MappingSymbolCounter++)));
EmitLabel(Symbol, Loc, F);
Symbol->setType(ELF::STT_NOTYPE);
Symbol->setBinding(ELF::STB_LOCAL);
Symbol->setExternal(false);
Symbol->setOffset(Offset);
}

void EmitThumbFunc(MCSymbol *Func) override {
getAssembler().setIsThumbFunc(Func);
EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
Expand All @@ -626,8 +680,10 @@ class ARMELFStreamer : public MCELFStreamer {
bool IsThumb;
int64_t MappingSymbolCounter = 0;

DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
ElfMappingSymbol LastEMS = EMS_None;
DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
LastMappingSymbols;

std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;

// ARM Exception Handling Frame Information
MCSymbol *ExTab;
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/ARM/Inputs/1.s
@@ -0,0 +1,3 @@
.section .foobar,"ax",%progbits
nop
.word 32
3 changes: 3 additions & 0 deletions llvm/test/MC/ARM/Inputs/2.s
@@ -0,0 +1,3 @@
.section .foobar,"",%progbits
nop
.word 32
3 changes: 3 additions & 0 deletions llvm/test/MC/ARM/Inputs/3.s
@@ -0,0 +1,3 @@
.section .foobar,"aw",%progbits
nop
.word 32
2 changes: 2 additions & 0 deletions llvm/test/MC/ARM/Inputs/4.s
@@ -0,0 +1,2 @@
.section .foobar,"",%progbits
.word 32
2 changes: 2 additions & 0 deletions llvm/test/MC/ARM/Inputs/5.s
@@ -0,0 +1,2 @@
.section .foobar,"aw",%progbits
.word 32
12 changes: 12 additions & 0 deletions llvm/test/MC/ARM/Inputs/6.s
@@ -0,0 +1,12 @@
.section .foo
.word 30
.word 31
.word 32
.word 33
nop
.word 34
.word 35
.word 36
.word 37
.word 38
nop
3 changes: 3 additions & 0 deletions llvm/test/MC/ARM/Inputs/7.s
@@ -0,0 +1,3 @@
.section .foobar,"aw",%progbits
.word 32
nop
5 changes: 5 additions & 0 deletions llvm/test/MC/ARM/Inputs/attr.s
@@ -0,0 +1,5 @@
.text
.syntax unified
.eabi_attribute 67, "2.09" @ Tag_conformance
.cpu arm7tdmi
.eabi_attribute 6, 2 @ Tag_CPU_arch
1 change: 1 addition & 0 deletions llvm/test/MC/ARM/Inputs/ident.s
@@ -0,0 +1 @@
.ident "LLVM ARM Compiler"
17 changes: 0 additions & 17 deletions llvm/test/MC/ARM/data-in-code.ll
Expand Up @@ -60,23 +60,6 @@ exit:
;; ARM-NEXT: Other:
;; ARM-NEXT: Section: [[MIXED_SECT]]

;; ARM: Symbol {
;; ARM: Name: $d
;; ARM-NEXT: Value: 0x0
;; ARM-NEXT: Size: 0
;; ARM-NEXT: Binding: Local (0x0)
;; ARM-NEXT: Type: None (0x0)
;; ARM-NEXT: Other: 0
;; ARM-NEXT: Section: .ARM.exidx
;; ARM-NEXT: }

;; ARM: Symbol {
;; ARM: Name: $d
;; ARM-NEXT: Value: 0
;; ARM-NEXT: Size: 0
;; ARM-NEXT: Binding: Local
;; ARM-NEXT: Type: None

;; ARM-NOT: ${{[atd]}}

;; TMB: Symbol {
Expand Down
48 changes: 48 additions & 0 deletions llvm/test/MC/ARM/mappingsymbols.s
@@ -0,0 +1,48 @@
# Check section containing code and data with permission executable for the section.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/1.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s

# Check section containing code and data with no permissions for the section.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/2.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s

# Check section containing code and data with read/write permissions for the section.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/3.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s

# Check section containing data with no permissions for the section.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/4.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MAPPINGSYMBOLS

# Check section containing only data with read/write permissions for the section.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/5.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MAPPINGSYMBOLS

# Check section containing the ident string with no permissions for the section.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/ident.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MAPPINGSYMBOLS

# Check section containing the attributes with no permissions for the section.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/attr.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MAPPINGSYMBOLS

# Check section containing code and data with no permissions for the section.
# data comes before code.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/6.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MIX

# Check section containing code and data with no permissions for the section.
# data comes before code.
@ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/7.s
@ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s

#CHECK: $a
#CHECK: $d

#MIX: $a
#MIX: $a
#MIX: $d
#MIX: $d

#MAPPINGSYMBOLS-NOT: $a
#MAPPINGSYMBOLS-NOT: $d
1 change: 0 additions & 1 deletion llvm/test/MC/ARM/multi-section-mapping.s
Expand Up @@ -29,7 +29,6 @@

@ CHECK: 00000000 .text 00000000 $a
@ CHECK-NEXT: 00000000 .wibble 00000000 $a
@ CHECK-NEXT: 00000000 .starts_data 00000000 $d
@ CHECK-NEXT: 00000000 .starts_thumb 00000000 $t
@ CHECK-NOT: ${{[adt]}}

1 change: 1 addition & 0 deletions llvm/test/Object/ARM/nm-mapping-symbol.s
Expand Up @@ -9,3 +9,4 @@

.section .foobar,"",%progbits
.asciz "foo"
nop

0 comments on commit 74a7fa0

Please sign in to comment.