[lld] r246405 - Keep the largest common symbol.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 30 18:16:20 PDT 2015
Author: rafael
Date: Sun Aug 30 20:16:19 2015
New Revision: 246405
URL: http://llvm.org/viewvc/llvm-project?rev=246405&view=rev
Log:
Keep the largest common symbol.
This requires templating some functions over ELFT, but that opens other cleanup
opportunities for future patches.
Added:
lld/trunk/test/elf2/Inputs/common.s
lld/trunk/test/elf2/common.s
Modified:
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/ELF/SymbolTable.h
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=246405&r1=246404&r2=246405&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Sun Aug 30 20:16:19 2015
@@ -12,12 +12,12 @@
#include "Symbols.h"
using namespace llvm;
+using namespace llvm::object;
using namespace lld;
using namespace lld::elf2;
SymbolTable::SymbolTable() {
- resolve(new (Alloc) SyntheticUndefined("_start"));
}
void SymbolTable::addFile(std::unique_ptr<InputFile> File) {
@@ -32,11 +32,41 @@ void SymbolTable::addObject(ObjectFileBa
ObjectFileBase &Old = *ObjectFiles[0];
if (!Old.isCompatibleWith(*File))
error(Twine(Old.getName() + " is incompatible with " + File->getName()));
+ } else {
+ auto *Start = new (Alloc) SyntheticUndefined("_start");
+ switch (File->kind()) {
+ case InputFile::Object32LEKind:
+ resolve<ELF32LE>(Start);
+ break;
+ case InputFile::Object32BEKind:
+ resolve<ELF32BE>(Start);
+ break;
+ case InputFile::Object64LEKind:
+ resolve<ELF64LE>(Start);
+ break;
+ case InputFile::Object64BEKind:
+ resolve<ELF64BE>(Start);
+ break;
+ }
}
ObjectFiles.emplace_back(File);
- for (SymbolBody *Body : File->getSymbols())
- resolve(Body);
+ for (SymbolBody *Body : File->getSymbols()) {
+ switch (File->kind()) {
+ case InputFile::Object32LEKind:
+ resolve<ELF32LE>(Body);
+ break;
+ case InputFile::Object32BEKind:
+ resolve<ELF32BE>(Body);
+ break;
+ case InputFile::Object64LEKind:
+ resolve<ELF64LE>(Body);
+ break;
+ case InputFile::Object64BEKind:
+ resolve<ELF64BE>(Body);
+ break;
+ }
+ }
}
void SymbolTable::reportRemainingUndefines() {
@@ -49,7 +79,7 @@ void SymbolTable::reportRemainingUndefin
// This function resolves conflicts if there's an existing symbol with
// the same name. Decisions are made based on symbol type.
-void SymbolTable::resolve(SymbolBody *New) {
+template <class ELFT> void SymbolTable::resolve(SymbolBody *New) {
// Find an existing Symbol or create and insert a new one.
StringRef Name = New->getName();
Builder.add(Name);
@@ -64,7 +94,7 @@ void SymbolTable::resolve(SymbolBody *Ne
// compare() returns -1, 0, or 1 if the lhs symbol is less preferable,
// equivalent (conflicting), or more preferable, respectively.
SymbolBody *Existing = Sym->Body;
- int comp = Existing->compare(New);
+ int comp = Existing->compare<ELFT>(New);
if (comp < 0)
Sym->Body = New;
if (comp == 0)
Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=246405&r1=246404&r2=246405&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Sun Aug 30 20:16:19 2015
@@ -51,7 +51,7 @@ public:
private:
void addObject(ObjectFileBase *File);
- void resolve(SymbolBody *Body);
+ template <class ELFT> void resolve(SymbolBody *Body);
llvm::DenseMap<StringRef, Symbol *> Symtab;
llvm::BumpPtrAllocator Alloc;
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=246405&r1=246404&r2=246405&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Sun Aug 30 20:16:19 2015
@@ -19,25 +19,36 @@ using namespace lld::elf2;
// Returns 1, 0 or -1 if this symbol should take precedence
// over the Other, tie or lose, respectively.
-int SymbolBody::compare(SymbolBody *Other) {
+template <class ELFT> int SymbolBody::compare(SymbolBody *Other) {
std::pair<bool, bool> L(isDefined(), !isWeak());
std::pair<bool, bool> R(Other->isDefined(), !Other->isWeak());
// Normalize
if (L > R)
- return -Other->compare(this);
+ return -Other->compare<ELFT>(this);
if (L != R)
return -1;
if (L.first && L.second) {
- // FIXME: In the case where both are common we need to pick the largest
- // and remember the alignment restriction.
- if (isCommon())
+ if (isCommon()) {
+ if (Other->isCommon()) {
+ // FIXME: We also need to remember the alignment restriction.
+ if (cast<DefinedCommon<ELFT>>(this)->Sym.st_size >=
+ cast<DefinedCommon<ELFT>>(Other)->Sym.st_size)
+ return 1;
+ return -1;
+ }
return -1;
+ }
if (Other->isCommon())
return 1;
return 0;
}
return 1;
}
+
+template int SymbolBody::compare<ELF32LE>(SymbolBody *Other);
+template int SymbolBody::compare<ELF32BE>(SymbolBody *Other);
+template int SymbolBody::compare<ELF64LE>(SymbolBody *Other);
+template int SymbolBody::compare<ELF64BE>(SymbolBody *Other);
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=246405&r1=246404&r2=246405&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Sun Aug 30 20:16:19 2015
@@ -71,7 +71,7 @@ public:
// Decides which symbol should "win" in the symbol table, this or
// the Other. Returns 1 if this wins, -1 if the Other wins, or 0 if
// they are duplicate (conflicting) symbols.
- int compare(SymbolBody *Other);
+ template <class ELFT> int compare(SymbolBody *Other);
protected:
SymbolBody(Kind K, StringRef Name, bool IsWeak)
Added: lld/trunk/test/elf2/Inputs/common.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/common.s?rev=246405&view=auto
==============================================================================
--- lld/trunk/test/elf2/Inputs/common.s (added)
+++ lld/trunk/test/elf2/Inputs/common.s Sun Aug 30 20:16:19 2015
@@ -0,0 +1,2 @@
+.comm sym1,8,4
+.comm sym2,4,4
Added: lld/trunk/test/elf2/common.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/common.s?rev=246405&view=auto
==============================================================================
--- lld/trunk/test/elf2/common.s (added)
+++ lld/trunk/test/elf2/common.s Sun Aug 30 20:16:19 2015
@@ -0,0 +1,28 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2
+// RUN: lld -flavor gnu2 %t %t2 -o %t3
+// RUN: llvm-readobj -t %t3 | FileCheck %s
+// REQUIRES: x86
+
+// CHECK: Name: sym2
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+
+// CHECK: Name: sym1
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+
+
+.globl _start
+_start:
+
+.comm sym1,4,4
+.comm sym2,8,4
More information about the llvm-commits
mailing list