diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/MC/MCELFStreamer.h | 1 | ||||
| -rw-r--r-- | llvm/include/llvm/MC/MCObjectStreamer.h | 1 | ||||
| -rw-r--r-- | llvm/lib/MC/MCELFStreamer.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 82 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/1.s | 3 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/2.s | 3 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/3.s | 3 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/4.s | 2 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/5.s | 2 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/6.s | 12 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/7.s | 3 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/attr.s | 5 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/Inputs/ident.s | 1 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/data-in-code.ll | 17 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/mappingsymbols.s | 48 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/multi-section-mapping.s | 1 | ||||
| -rw-r--r-- | llvm/test/Object/ARM/nm-mapping-symbol.s | 1 | 
18 files changed, 177 insertions, 36 deletions
diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index ea9ade459e0..90434f34da5 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -42,6 +42,7 @@ public:    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; diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 978a2409526..11f8dfa2448 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -90,6 +90,7 @@ public:    /// @{    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; diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index de0791281d2..c8e0223c057 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -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); diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 8f502fc3e2f..726326be2ee 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -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())) { @@ -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);  } @@ -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);  } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index f7bdda491cb..2959f982c43 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -464,13 +464,14 @@ public:    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 @@ -532,6 +533,14 @@ public:      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. @@ -573,22 +582,54 @@ private:      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) { @@ -601,6 +642,17 @@ private:      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); @@ -626,8 +678,10 @@ private:    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; diff --git a/llvm/test/MC/ARM/Inputs/1.s b/llvm/test/MC/ARM/Inputs/1.s new file mode 100644 index 00000000000..0afcc633f64 --- /dev/null +++ b/llvm/test/MC/ARM/Inputs/1.s @@ -0,0 +1,3 @@ +        .section        .foobar,"ax",%progbits +         nop +        .word 32 diff --git a/llvm/test/MC/ARM/Inputs/2.s b/llvm/test/MC/ARM/Inputs/2.s new file mode 100644 index 00000000000..0ecdb294ab8 --- /dev/null +++ b/llvm/test/MC/ARM/Inputs/2.s @@ -0,0 +1,3 @@ +        .section        .foobar,"",%progbits +         nop +        .word 32 diff --git a/llvm/test/MC/ARM/Inputs/3.s b/llvm/test/MC/ARM/Inputs/3.s new file mode 100644 index 00000000000..09392623fc1 --- /dev/null +++ b/llvm/test/MC/ARM/Inputs/3.s @@ -0,0 +1,3 @@ +        .section        .foobar,"aw",%progbits +         nop +        .word 32 diff --git a/llvm/test/MC/ARM/Inputs/4.s b/llvm/test/MC/ARM/Inputs/4.s new file mode 100644 index 00000000000..28d8244bb41 --- /dev/null +++ b/llvm/test/MC/ARM/Inputs/4.s @@ -0,0 +1,2 @@ +        .section        .foobar,"",%progbits +        .word 32 diff --git a/llvm/test/MC/ARM/Inputs/5.s b/llvm/test/MC/ARM/Inputs/5.s new file mode 100644 index 00000000000..1faef539b13 --- /dev/null +++ b/llvm/test/MC/ARM/Inputs/5.s @@ -0,0 +1,2 @@ +        .section        .foobar,"aw",%progbits +        .word 32 diff --git a/llvm/test/MC/ARM/Inputs/6.s b/llvm/test/MC/ARM/Inputs/6.s new file mode 100644 index 00000000000..0fdb9daaf29 --- /dev/null +++ b/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 diff --git a/llvm/test/MC/ARM/Inputs/7.s b/llvm/test/MC/ARM/Inputs/7.s new file mode 100644 index 00000000000..b92a61ec971 --- /dev/null +++ b/llvm/test/MC/ARM/Inputs/7.s @@ -0,0 +1,3 @@ +        .section        .foobar,"aw",%progbits +        .word 32 +        nop diff --git a/llvm/test/MC/ARM/Inputs/attr.s b/llvm/test/MC/ARM/Inputs/attr.s new file mode 100644 index 00000000000..412cad76842 --- /dev/null +++ b/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 diff --git a/llvm/test/MC/ARM/Inputs/ident.s b/llvm/test/MC/ARM/Inputs/ident.s new file mode 100644 index 00000000000..19d65fcc7e0 --- /dev/null +++ b/llvm/test/MC/ARM/Inputs/ident.s @@ -0,0 +1 @@ +	.ident	"LLVM ARM Compiler" diff --git a/llvm/test/MC/ARM/data-in-code.ll b/llvm/test/MC/ARM/data-in-code.ll index c2194e9179c..e579146acfb 100644 --- a/llvm/test/MC/ARM/data-in-code.ll +++ b/llvm/test/MC/ARM/data-in-code.ll @@ -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 { diff --git a/llvm/test/MC/ARM/mappingsymbols.s b/llvm/test/MC/ARM/mappingsymbols.s new file mode 100644 index 00000000000..fff8e104781 --- /dev/null +++ b/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 diff --git a/llvm/test/MC/ARM/multi-section-mapping.s b/llvm/test/MC/ARM/multi-section-mapping.s index 2b1b0efab53..e4b7146e4b0 100644 --- a/llvm/test/MC/ARM/multi-section-mapping.s +++ b/llvm/test/MC/ARM/multi-section-mapping.s @@ -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]}} diff --git a/llvm/test/Object/ARM/nm-mapping-symbol.s b/llvm/test/Object/ARM/nm-mapping-symbol.s index 485c1cc39d7..9b7b5b583ea 100644 --- a/llvm/test/Object/ARM/nm-mapping-symbol.s +++ b/llvm/test/Object/ARM/nm-mapping-symbol.s @@ -9,3 +9,4 @@          .section        .foobar,"",%progbits          .asciz  "foo" +        nop  | 

