llvm.org GIT mirror llvm / 16d8031
MC, COFF: Use relocations for function references inside the section Referencing one symbol from another in the same section does not generally require a relocation. However, the MS linker has a feature called /INCREMENTAL which enables incremental links. It achieves this by creating thunks to the actual function and redirecting all relocations to point to the thunk. This breaks down with the old scheme if you have a function which references, say, itself. On x86_64, we would use %rip relative addressing to reference the start of the function from out current position. This would lead to miscompiles because other references might reference the thunk instead, breaking function pointer equality. This fixes PR21520. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221678 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 6 years ago
4 changed file(s) with 26 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
298298
299299 uint8_t getBaseType() const { return getType() & 0x0F; }
300300
301 uint8_t getComplexType() const { return (getType() & 0xF0) >> 4; }
301 uint8_t getComplexType() const {
302 return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
303 }
302304
303305 bool isExternal() const {
304306 return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
168168
169169 void ExecutePostLayoutBinding(MCAssembler &Asm,
170170 const MCAsmLayout &Layout) override;
171
172 bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
173 const MCSymbolData &DataA,
174 const MCFragment &FB, bool InSet,
175 bool IsPCRel) const override;
171176
172177 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
173178 const MCFragment *Fragment, const MCFixup &Fixup,
642647 DefineSymbol(SD, Asm, Layout);
643648 }
644649
650 bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
651 const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB,
652 bool InSet, bool IsPCRel) const {
653 // MS LINK expects to be able to replace all references to a function with a
654 // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize
655 // away any relocations to functions.
656 if ((((DataA.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift) >>
657 COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
658 return false;
659 return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB,
660 InSet, IsPCRel);
661 }
662
645663 void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
646664 const MCAsmLayout &Layout,
647665 const MCFragment *Fragment,
132132 if (!CurSymbol)
133133 FatalError("storage class specified outside of symbol definition");
134134
135 if (StorageClass & ~0xff)
135 if (StorageClass & ~COFF::SSC_Invalid)
136136 FatalError(Twine("storage class value '") + itostr(StorageClass) +
137137 "' out of range");
138138
None // The purpose of this test is to verify that we do not produce unneeded
1 // relocations when symbols are in the same section and we know their offset.
0 // The purpose of this test is to verify that we produce relocations for
1 // references to functions. Failing to do so might cause pointer-to-function
2 // equality to fail if /INCREMENTAL links are used.
23
34 // RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s | llvm-readobj -s | FileCheck %s
45 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj -s | FileCheck %s
4546 ret
4647
4748 // CHECK: Sections [
48 // CHECK-NOT: RelocationCount: {{[^0]}}
49 // CHECK: RelocationCount: 1