llvm.org GIT mirror llvm / 3a50eea
Dont emit Mapping symbols for sections that contain only data. Summary: Dont emit mapping symbols for sections that contain only data. Patched by Shankar Easwaran <shankare@codeaurora.org> Reviewers: rengolin, peter.smith, weimingz, kparzysz, t.p.northover Reviewed By: t.p.northover Subscribers: t.p.northover, llvm-commits Differential Revision: https://reviews.llvm.org/D30724 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298901 91177308-0d34-0410-b5e6-96231b3b80d8 Weiming Zhao 3 years ago
18 changed file(s) with 177 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
4141 void InitSections(bool NoExecStack) override;
4242 void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
4343 void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
44 void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) override;
4445 void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
4546 void EmitThumbFunc(MCSymbol *Func) override;
4647 void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
8989 /// @{
9090
9191 void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
92 virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F);
9293 void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
9394 void EmitValueImpl(const MCExpr *Value, unsigned Size,
9495 SMLoc Loc = SMLoc()) override;
9595 void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) {
9696 auto *Symbol = cast(S);
9797 MCObjectStreamer::EmitLabel(Symbol, Loc);
98
99 const MCSectionELF &Section =
100 static_cast(*getCurrentSectionOnly());
101 if (Section.getFlags() & ELF::SHF_TLS)
102 Symbol->setType(ELF::STT_TLS);
103 }
104
105 void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc, MCFragment *F) {
106 auto *Symbol = cast(S);
107 MCObjectStreamer::EmitLabel(Symbol, Loc, F);
98108
99109 const MCSectionELF &Section =
100110 static_cast(*getCurrentSectionOnly());
170170 }
171171 }
172172
173 void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) {
174 MCStreamer::EmitLabel(Symbol, Loc);
175 getAssembler().registerSymbol(*Symbol);
176 auto *DF = dyn_cast_or_null(F);
177 if (DF)
178 Symbol->setFragment(F);
179 else
180 PendingLabels.push_back(Symbol);
181 }
182
173183 void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
174184 int64_t IntValue;
175185 if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
490500 MCDataFragment *DF = getOrCreateDataFragment();
491501 flushPendingLabels(DF, DF->getContents().size());
492502
493 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
494 Value, FK_GPRel_4));
503 DF->getFixups().push_back(
504 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
495505 DF->getContents().resize(DF->getContents().size() + 4, 0);
496506 }
497507
500510 MCDataFragment *DF = getOrCreateDataFragment();
501511 flushPendingLabels(DF, DF->getContents().size());
502512
503 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
504 Value, FK_GPRel_4));
513 DF->getFixups().push_back(
514 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
505515 DF->getContents().resize(DF->getContents().size() + 8, 0);
506516 }
507517
463463 void emitUnwindRaw(int64_t Offset, const SmallVectorImpl &Opcodes);
464464
465465 void ChangeSection(MCSection *Section, const MCExpr *Subsection) override {
466 // We have to keep track of the mapping symbol state of any sections we
467 // use. Each one should start off as EMS_None, which is provided as the
468 // default constructor by DenseMap::lookup.
469 LastMappingSymbols[getPreviousSection().first] = LastEMS;
470 LastEMS = LastMappingSymbols.lookup(Section);
471
466 LastMappingSymbols[getPreviousSection().first] = std::move(LastEMSInfo);
472467 MCELFStreamer::ChangeSection(Section, Subsection);
468 auto LastMappingSymbol = LastMappingSymbols.find(Section);
469 if (LastMappingSymbol != LastMappingSymbols.end()) {
470 LastEMSInfo = std::move(LastMappingSymbol->second);
471 return;
472 }
473 LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
473474 }
474475
475476 /// This function is the one used to emit instruction data into the ELF
529530 void EmitBytes(StringRef Data) override {
530531 EmitDataMappingSymbol();
531532 MCELFStreamer::EmitBytes(Data);
533 }
534
535 void FlushPendingMappingSymbol() {
536 if (!LastEMSInfo->hasInfo())
537 return;
538 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
539 EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset);
540 EMS->resetInfo();
532541 }
533542
534543 /// This is one of the functions used to emit data into an ELF section, so the
572581 EMS_Data
573582 };
574583
584 struct ElfMappingSymbolInfo {
585 explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O)
586 : Loc(Loc), F(F), Offset(O), State(EMS_None) {}
587 void resetInfo() {
588 F = nullptr;
589 Offset = 0;
590 }
591 bool hasInfo() { return F != nullptr; }
592 SMLoc Loc;
593 MCFragment *F;
594 uint64_t Offset;
595 ElfMappingSymbol State;
596 };
597
575598 void EmitDataMappingSymbol() {
576 if (LastEMS == EMS_Data) return;
599 if (LastEMSInfo->State == EMS_Data)
600 return;
601 else if (LastEMSInfo->State == EMS_None) {
602 // This is a tentative symbol, it won't really be emitted until it's
603 // actually needed.
604 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
605 auto *DF = dyn_cast_or_null(getCurrentFragment());
606 if (!DF)
607 return;
608 EMS->Loc = SMLoc();
609 EMS->F = getCurrentFragment();
610 EMS->Offset = DF->getContents().size();
611 LastEMSInfo->State = EMS_Data;
612 return;
613 }
577614 EmitMappingSymbol("$d");
578 LastEMS = EMS_Data;
615 LastEMSInfo->State = EMS_Data;
579616 }
580617
581618 void EmitThumbMappingSymbol() {
582 if (LastEMS == EMS_Thumb) return;
619 if (LastEMSInfo->State == EMS_Thumb)
620 return;
621 FlushPendingMappingSymbol();
583622 EmitMappingSymbol("$t");
584 LastEMS = EMS_Thumb;
623 LastEMSInfo->State = EMS_Thumb;
585624 }
586625
587626 void EmitARMMappingSymbol() {
588 if (LastEMS == EMS_ARM) return;
627 if (LastEMSInfo->State == EMS_ARM)
628 return;
629 FlushPendingMappingSymbol();
589630 EmitMappingSymbol("$a");
590 LastEMS = EMS_ARM;
631 LastEMSInfo->State = EMS_ARM;
591632 }
592633
593634 void EmitMappingSymbol(StringRef Name) {
600641 Symbol->setExternal(false);
601642 }
602643
644 void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F,
645 uint64_t Offset) {
646 auto *Symbol = cast(getContext().getOrCreateSymbol(
647 Name + "." + Twine(MappingSymbolCounter++)));
648 EmitLabel(Symbol, Loc, F);
649 Symbol->setType(ELF::STT_NOTYPE);
650 Symbol->setBinding(ELF::STB_LOCAL);
651 Symbol->setExternal(false);
652 Symbol->setOffset(Offset);
653 }
654
603655 void EmitThumbFunc(MCSymbol *Func) override {
604656 getAssembler().setIsThumbFunc(Func);
605657 EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
625677 bool IsThumb;
626678 int64_t MappingSymbolCounter = 0;
627679
628 DenseMap LastMappingSymbols;
629 ElfMappingSymbol LastEMS = EMS_None;
680 DenseMap>
681 LastMappingSymbols;
682
683 std::unique_ptr LastEMSInfo;
630684
631685 // ARM Exception Handling Frame Information
632686 MCSymbol *ExTab;
0 .section .foobar,"ax",%progbits
1 nop
2 .word 32
0 .section .foobar,"",%progbits
1 nop
2 .word 32
0 .section .foobar,"aw",%progbits
1 nop
2 .word 32
0 .section .foobar,"",%progbits
1 .word 32
0 .section .foobar,"aw",%progbits
1 .word 32
0 .section .foo
1 .word 30
2 .word 31
3 .word 32
4 .word 33
5 nop
6 .word 34
7 .word 35
8 .word 36
9 .word 37
10 .word 38
11 nop
0 .section .foobar,"aw",%progbits
1 .word 32
2 nop
0 .text
1 .syntax unified
2 .eabi_attribute 67, "2.09" @ Tag_conformance
3 .cpu arm7tdmi
4 .eabi_attribute 6, 2 @ Tag_CPU_arch
0 .ident "LLVM ARM Compiler"
5959 ;; ARM-NEXT: Other:
6060 ;; ARM-NEXT: Section: [[MIXED_SECT]]
6161
62 ;; ARM: Symbol {
63 ;; ARM: Name: $d
64 ;; ARM-NEXT: Value: 0x0
65 ;; ARM-NEXT: Size: 0
66 ;; ARM-NEXT: Binding: Local (0x0)
67 ;; ARM-NEXT: Type: None (0x0)
68 ;; ARM-NEXT: Other: 0
69 ;; ARM-NEXT: Section: .ARM.exidx
70 ;; ARM-NEXT: }
71
72 ;; ARM: Symbol {
73 ;; ARM: Name: $d
74 ;; ARM-NEXT: Value: 0
75 ;; ARM-NEXT: Size: 0
76 ;; ARM-NEXT: Binding: Local
77 ;; ARM-NEXT: Type: None
78
7962 ;; ARM-NOT: ${{[atd]}}
8063
8164 ;; TMB: Symbol {
0 # Check section containing code and data with permission executable for the section.
1 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/1.s
2 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s
3
4 # Check section containing code and data with no permissions for the section.
5 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/2.s
6 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s
7
8 # Check section containing code and data with read/write permissions for the section.
9 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/3.s
10 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s
11
12 # Check section containing data with no permissions for the section.
13 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/4.s
14 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MAPPINGSYMBOLS
15
16 # Check section containing only data with read/write permissions for the section.
17 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/5.s
18 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MAPPINGSYMBOLS
19
20 # Check section containing the ident string with no permissions for the section.
21 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/ident.s
22 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MAPPINGSYMBOLS
23
24 # Check section containing the attributes with no permissions for the section.
25 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/attr.s
26 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MAPPINGSYMBOLS
27
28 # Check section containing code and data with no permissions for the section.
29 # data comes before code.
30 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/6.s
31 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s -check-prefix=MIX
32
33 # Check section containing code and data with no permissions for the section.
34 # data comes before code.
35 @ RUN: llvm-mc -triple armv7-none-linux -filetype=obj -o %t.o %p/Inputs/7.s
36 @ RUN: llvm-readobj -elf-output-style=GNU -symbols %t.o | FileCheck %s
37
38 #CHECK: $a
39 #CHECK: $d
40
41 #MIX: $a
42 #MIX: $a
43 #MIX: $d
44 #MIX: $d
45
46 #MAPPINGSYMBOLS-NOT: $a
47 #MAPPINGSYMBOLS-NOT: $d
2828
2929 @ CHECK: 00000000 .text 00000000 $a
3030 @ CHECK-NEXT: 00000000 .wibble 00000000 $a
31 @ CHECK-NEXT: 00000000 .starts_data 00000000 $d
3231 @ CHECK-NEXT: 00000000 .starts_thumb 00000000 $t
3332 @ CHECK-NOT: ${{[adt]}}
3433
88
99 .section .foobar,"",%progbits
1010 .asciz "foo"
11 nop