aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlib/Target/X86/X86ATTAsmPrinter.cpp27
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp18
-rw-r--r--lib/Target/X86/X86COFF.h89
3 files changed, 128 insertions, 6 deletions
diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp
index 096f712eba..02faf7cdb3 100755
--- a/lib/Target/X86/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/X86ATTAsmPrinter.cpp
@@ -16,6 +16,7 @@
#define DEBUG_TYPE "asm-printer"
#include "X86ATTAsmPrinter.h"
#include "X86.h"
+#include "X86COFF.h"
#include "X86MachineFunctionInfo.h"
#include "X86TargetMachine.h"
#include "X86TargetAsmInfo.h"
@@ -128,7 +129,17 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
if (F->hasHiddenVisibility())
if (const char *Directive = TAI->getHiddenDirective())
O << Directive << CurrentFnName << "\n";
-
+
+ if (Subtarget->isTargetELF())
+ O << "\t.type " << CurrentFnName << ",@function\n";
+ else if (Subtarget->isTargetCygMing()) {
+ O << "\t.def\t " << CurrentFnName
+ << ";\t.scl\t" <<
+ (F->getLinkage() == Function::InternalLinkage ? COFF::C_STAT : COFF::C_EXT)
+ << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
+ << ";\t.endef\n";
+ }
+
O << CurrentFnName << ":\n";
// Add some workaround for linkonce linkage on Cygwin\MinGW
if (Subtarget->isTargetCygMing() &&
@@ -289,10 +300,16 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
}
O << Name;
- if (Subtarget->isPICStyleGOT() && isCallOp && isa<Function>(GV)) {
- // Assemble call via PLT for non-local symbols
- if (!isHidden || isExt)
- O << "@PLT";
+ if (isCallOp && isa<Function>(GV)) {
+ if (Subtarget->isPICStyleGOT()) {
+ // Assemble call via PLT for non-local symbols
+ if (!isHidden || GV->isExternal())
+ O << "@PLT";
+ }
+ if (Subtarget->isTargetCygMing() && GV->isExternal()) {
+ // Save function name for later type emission
+ FnStubs.insert(Name);
+ }
}
}
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index 78b1af22e5..767ab23ce3 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -16,6 +16,7 @@
#include "X86AsmPrinter.h"
#include "X86ATTAsmPrinter.h"
+#include "X86COFF.h"
#include "X86IntelAsmPrinter.h"
#include "X86MachineFunctionInfo.h"
#include "X86Subtarget.h"
@@ -249,6 +250,9 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
if (I->hasHiddenVisibility())
if (const char *Directive = TAI->getHiddenDirective())
O << Directive << name << "\n";
+
+ if (Subtarget->isTargetELF())
+ O << "\t.type " << name << ",@object\n";
}
// Output linker support code for dllexported globals
@@ -308,7 +312,19 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
// linker can safely perform dead code stripping. Since LLVM never
// generates code that does this, it is always safe to set.
O << "\t.subsections_via_symbols\n";
- } else if (Subtarget->isTargetELF() || Subtarget->isTargetCygMing()) {
+ } else if (Subtarget->isTargetCygMing()) {
+ // Emit type information for external functions
+ for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
+ i != e; ++i) {
+ O << "\t.def\t " << *i
+ << ";\t.scl\t" << COFF::C_EXT
+ << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
+ << ";\t.endef\n";
+ }
+
+ // Emit final debug information.
+ DW.EndModule();
+ } else if (Subtarget->isTargetELF()) {
// Emit final debug information.
DW.EndModule();
}
diff --git a/lib/Target/X86/X86COFF.h b/lib/Target/X86/X86COFF.h
new file mode 100644
index 0000000000..1d7878b88b
--- /dev/null
+++ b/lib/Target/X86/X86COFF.h
@@ -0,0 +1,89 @@
+//===--- X86COFF.h - Some definitions from COFF documentations ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file just defines some symbols found in COFF documentation. They are
+// used to emit function type information for COFF targets (Cygwin/Mingw32).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86COFF_H
+#define X86COFF_H
+
+namespace COFF
+{
+enum StorageClass {
+ C_EFCN = -1, // physical end of function
+ C_NULL = 0,
+ C_AUTO = 1, // external definition
+ C_EXT = 2, // external symbol
+ C_STAT = 3, // static
+ C_REG = 4, // register variable
+ C_EXTDEF = 5, // external definition
+ C_LABEL = 6, // label
+ C_ULABEL = 7, // undefined label
+ C_MOS = 8, // member of structure
+ C_ARG = 9, // function argument
+ C_STRTAG = 10, // structure tag
+ C_MOU = 11, // member of union
+ C_UNTAG = 12, // union tag
+ C_TPDEF = 13, // type definition
+ C_USTATIC = 14, // undefined static
+ C_ENTAG = 15, // enumeration tag
+ C_MOE = 16, // member of enumeration
+ C_REGPARM = 17, // register parameter
+ C_FIELD = 18, // bit field
+
+ C_BLOCK = 100, // ".bb" or ".eb"
+ C_FCN = 101, // ".bf" or ".ef"
+ C_EOS = 102, // end of structure
+ C_FILE = 103, // file name
+ C_LINE = 104, // dummy class for line number entry
+ C_ALIAS = 105, // duplicate tag
+ C_HIDDEN = 106
+};
+
+enum SymbolType {
+ T_NULL = 0, // no type info
+ T_ARG = 1, // function argument (only used by compiler)
+ T_VOID = 1,
+ T_CHAR = 2, // character
+ T_SHORT = 3, // short integer
+ T_INT = 4, // integer
+ T_LONG = 5, // long integer
+ T_FLOAT = 6, // floating point
+ T_DOUBLE = 7, // double word
+ T_STRUCT = 8, // structure
+ T_UNION = 9, // union
+ T_ENUM = 10, // enumeration
+ T_MOE = 11, // member of enumeration
+ T_UCHAR = 12, // unsigned character
+ T_USHORT = 13, // unsigned short
+ T_UINT = 14, // unsigned integer
+ T_ULONG = 15 // unsigned long
+};
+
+enum SymbolDerivedType {
+ DT_NON = 0, // no derived type
+ DT_PTR = 1, // pointer
+ DT_FCN = 2, // function
+ DT_ARY = 3 // array
+};
+
+enum TypePacking {
+ N_BTMASK = 017,
+ N_TMASK = 060,
+ N_TMASK1 = 0300,
+ N_TMASK2 = 0360,
+ N_BTSHFT = 4,
+ N_TSHIFT = 2
+};
+
+}
+
+#endif // X86COFF_H