From 8452e84d36329276ab755269896bd61bb994461e Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Mon, 23 Nov 2015 16:08:03 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253875 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 18 ++++++- test/MC/Mips/directive-ent.s | 50 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/MC/Mips/directive-ent.s diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 994126e83b6..e5fa7556053 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/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(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(Symbol).setType(ELF::STT_FUNC); } void MipsTargetELFStreamer::emitDirectiveAbiCalls() { diff --git a/test/MC/Mips/directive-ent.s b/test/MC/Mips/directive-ent.s new file mode 100644 index 00000000000..b9b8bf902f6 --- /dev/null +++ b/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: } -- 2.34.1