summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Object/COFF.h4
-rw-r--r--llvm/lib/MC/WinCOFFObjectWriter.cpp18
-rw-r--r--llvm/lib/MC/WinCOFFStreamer.cpp2
-rw-r--r--llvm/test/MC/COFF/simple-fixups.s7
4 files changed, 26 insertions, 5 deletions
diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h
index d9c0cd3870d..579cbadbc94 100644
--- a/llvm/include/llvm/Object/COFF.h
+++ b/llvm/include/llvm/Object/COFF.h
@@ -299,7 +299,9 @@ public:
uint8_t getBaseType() const { return getType() & 0x0F; }
- uint8_t getComplexType() const { return (getType() & 0xF0) >> 4; }
+ uint8_t getComplexType() const {
+ return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
+ }
bool isExternal() const {
return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index e5f4565dafc..1046e047161 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -170,6 +170,11 @@ public:
void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
+ bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB, bool InSet,
+ bool IsPCRel) const override;
+
void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, bool &IsPCRel,
@@ -643,6 +648,19 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
DefineSymbol(SD, Asm, Layout);
}
+bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
+ const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB,
+ bool InSet, bool IsPCRel) const {
+ // MS LINK expects to be able to replace all references to a function with a
+ // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize
+ // away any relocations to functions.
+ if ((((DataA.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift) >>
+ COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
+ return false;
+ return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB,
+ InSet, IsPCRel);
+}
+
void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp
index 32813a1d263..6a8054d7486 100644
--- a/llvm/lib/MC/WinCOFFStreamer.cpp
+++ b/llvm/lib/MC/WinCOFFStreamer.cpp
@@ -133,7 +133,7 @@ void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
if (!CurSymbol)
FatalError("storage class specified outside of symbol definition");
- if (StorageClass & ~0xff)
+ if (StorageClass & ~COFF::SSC_Invalid)
FatalError(Twine("storage class value '") + itostr(StorageClass) +
"' out of range");
diff --git a/llvm/test/MC/COFF/simple-fixups.s b/llvm/test/MC/COFF/simple-fixups.s
index 2a74f21f12d..cb5d7642ee6 100644
--- a/llvm/test/MC/COFF/simple-fixups.s
+++ b/llvm/test/MC/COFF/simple-fixups.s
@@ -1,5 +1,6 @@
-// The purpose of this test is to verify that we do not produce unneeded
-// relocations when symbols are in the same section and we know their offset.
+// The purpose of this test is to verify that we produce relocations for
+// references to functions. Failing to do so might cause pointer-to-function
+// equality to fail if /INCREMENTAL links are used.
// RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s | llvm-readobj -s | FileCheck %s
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj -s | FileCheck %s
@@ -46,4 +47,4 @@ Ltmp0:
ret
// CHECK: Sections [
-// CHECK-NOT: RelocationCount: {{[^0]}}
+// CHECK: RelocationCount: 1
OpenPOWER on IntegriCloud