[mips] .ent and .end should also set the type and size of the symbol respectively.
authorDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 23 Nov 2015 16:08:03 +0000 (16:08 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 23 Nov 2015 16:08:03 +0000 (16:08 +0000)
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

lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
test/MC/Mips/directive-ent.s [new file with mode: 0644]

index 994126e83b6e425ff518ea03e5771657189efc54..e5fa7556053f96944c8e4eb5a55eac925feac477 100644 (file)
@@ -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/test/MC/Mips/directive-ent.s b/test/MC/Mips/directive-ent.s
new file mode 100644 (file)
index 0000000..b9b8bf9
--- /dev/null
@@ -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: }