diff options
author | Daniel Sanders <daniel.sanders@imgtec.com> | 2015-11-23 16:08:03 +0000 |
---|---|---|
committer | Daniel Sanders <daniel.sanders@imgtec.com> | 2015-11-23 16:08:03 +0000 |
commit | 2b561336d92ffcdfa37fb31ac2219975a1998a41 (patch) | |
tree | 740dce7e50e431072823dc9678f9981a71f19c3e | |
parent | ba0f7d2b9d1e263febfb392e9dd210679a0b25e8 (diff) | |
download | bcm5719-llvm-2b561336d92ffcdfa37fb31ac2219975a1998a41.tar.gz bcm5719-llvm-2b561336d92ffcdfa37fb31ac2219975a1998a41.zip |
[mips] .ent and .end should also set the type and size of the symbol respectively.
Reviewers: vkalintiris
Subscribers: llvm-commits, seanbruno, emaste, vkalintiris, dsanders
Differential Revision: http://reviews.llvm.org/D14221
llvm-svn: 253875
-rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 18 | ||||
-rw-r--r-- | llvm/test/MC/Mips/directive-ent.s | 50 |
2 files changed, 67 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 994126e83b6..e5fa7556053 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -613,8 +613,9 @@ void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHT_REL); + MCSymbol *Sym = Context.getOrCreateSymbol(Name); const MCSymbolRefExpr *ExprRef = - MCSymbolRefExpr::create(Name, MCSymbolRefExpr::VK_None, Context); + MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Context); MCA.registerSection(*Sec); Sec->setAlignment(4); @@ -640,10 +641,25 @@ void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) { GPRInfoSet = FPRInfoSet = FrameInfoSet = false; OS.PopSection(); + + // .end also implicitly sets the size. + MCSymbol *CurPCSym = Context.createTempSymbol(); + OS.EmitLabel(CurPCSym); + const MCExpr *Size = MCBinaryExpr::createSub( + MCSymbolRefExpr::create(CurPCSym, MCSymbolRefExpr::VK_None, Context), + ExprRef, Context); + int64_t AbsSize; + if (!Size->evaluateAsAbsolute(AbsSize, MCA)) + llvm_unreachable("Function size must be evaluatable as absolute"); + Size = MCConstantExpr::create(AbsSize, Context); + static_cast<MCSymbolELF *>(Sym)->setSize(Size); } void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) { GPRInfoSet = FPRInfoSet = FrameInfoSet = false; + + // .ent also acts like an implicit '.type symbol, STT_FUNC' + static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC); } void MipsTargetELFStreamer::emitDirectiveAbiCalls() { diff --git a/llvm/test/MC/Mips/directive-ent.s b/llvm/test/MC/Mips/directive-ent.s new file mode 100644 index 00000000000..b9b8bf902f6 --- /dev/null +++ b/llvm/test/MC/Mips/directive-ent.s @@ -0,0 +1,50 @@ +# The effects of .ent on the .pdr section are tested in mips-pdr*.s. Test +# everything else here. +# +# RUN: llvm-mc -mcpu=mips32 -triple mips-unknown-unknown %s | \ +# RUN: FileCheck -check-prefix=ASM %s +# RUN: llvm-mc -filetype=obj -mcpu=mips32 -triple mips-unknown-unknown %s | \ +# RUN: llvm-readobj -symbols | \ +# RUN: FileCheck -check-prefix=OBJ -check-prefix=OBJ-32 %s +# +# RUN: llvm-mc -mcpu=mips32 -mattr=micromips -triple mips-unknown-unknown %s | \ +# RUN: FileCheck -check-prefix=ASM %s +# RUN: llvm-mc -filetype=obj -mcpu=mips32 -mattr=micromips \ +# RUN: -triple mips-unknown-unknown %s | \ +# RUN: llvm-readobj -symbols | \ +# RUN: FileCheck -check-prefix=OBJ -check-prefix=OBJ-MM %s +# + .ent a +a: + +# ASM: .ent a +# ASM: a: + +# OBJ: Name: a +# OBJ: Value: 0x0 +# OBJ: Size: 0 +# OBJ: Binding: Local +# OBJ: Type: Function +# OBJ: Other: 0 +# OBJ: Section: .text +# OBJ: } + + .ent b +b: + nop + nop + .end b + +# ASM: .ent b +# ASM: b: + +# OBJ: Name: b +# OBJ: Value: 0x0 +# OBJ-32: Size: 8 +# FIXME: microMIPS uses the 4-byte nop instead of the 2-byte nop. +# OBJ-MM: Size: 8 +# OBJ: Binding: Local +# OBJ: Type: Function +# OBJ: Other: 0 +# OBJ: Section: .text +# OBJ: } |