From ccde19d77ec8e990bedeea2a7190beb3f42cce06 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 26 Jun 2015 03:09:23 +0000 Subject: [PATCH] COFF: Fix local absolute symbols. Absolute symbols were always handled as external symbols, so if two or more object files define the same absolute symbol, they would conflict even if the symbol is private to each file. This patch fixes that bug. llvm-svn: 240756 --- lld/COFF/InputFiles.cpp | 2 +- lld/COFF/Symbols.h | 14 ++++++++++---- lld/test/COFF/internal.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 lld/test/COFF/internal.test diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index f616d4c..c54ccdd 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -198,7 +198,7 @@ SymbolBody *ObjectFile::createSymbolBody(COFFSymbolRef Sym, const void *AuxP, // Skip special symbols. if (Name == "@comp.id" || Name == "@feat.00") return nullptr; - return new (Alloc) DefinedAbsolute(Name, Sym.getValue()); + return new (Alloc) DefinedAbsolute(Name, Sym); } if (Sym.getSectionNumber() == llvm::COFF::IMAGE_SYM_DEBUG) return nullptr; diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index 7262f9a..8afbdc6 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -173,20 +173,26 @@ private: // Absolute symbols. class DefinedAbsolute : public Defined { public: - DefinedAbsolute(StringRef N, uint64_t VA) - : Defined(DefinedAbsoluteKind), Name(N), RVA(VA - Config->ImageBase) {} + DefinedAbsolute(StringRef N, COFFSymbolRef S) + : Defined(DefinedAbsoluteKind), Name(N), VA(S.getValue()), + External(S.isExternal()) {} + + DefinedAbsolute(StringRef N, uint64_t V) + : Defined(DefinedAbsoluteKind), Name(N), VA(V) {} static bool classof(const SymbolBody *S) { return S->kind() == DefinedAbsoluteKind; } StringRef getName() override { return Name; } - uint64_t getRVA() override { return RVA; } + uint64_t getRVA() override { return VA - Config->ImageBase; } uint64_t getFileOff() override { llvm_unreachable("internal error"); } + bool isExternal() override { return External; } private: StringRef Name; - uint64_t RVA; + uint64_t VA; + bool External = true; }; // This class represents a symbol defined in an archive file. It is diff --git a/lld/test/COFF/internal.test b/lld/test/COFF/internal.test new file mode 100644 index 0000000..e88d5de --- /dev/null +++ b/lld/test/COFF/internal.test @@ -0,0 +1,42 @@ +# Test that non-external symbols don't conflict + +# RUN: yaml2obj < %s > %t1.obj +# RUN: yaml2obj < %s > %t2.obj +# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t3.obj +# RUN: lld -flavor link2 /out:%t.exe %t1.obj %t2.obj %t3.obj + +--- +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 000000000000 +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 6 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: defined + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: absolute + Value: 0xdeadbeef + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... -- 2.7.4