diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-08-11 17:33:02 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-08-11 17:33:02 +0000 |
| commit | b13df6582a6a7802d4e0675a4ae7545c09a766a9 (patch) | |
| tree | 62e3c91b29baaab8c14ec0153598acadf183170e | |
| parent | b5093187f9a38ac329b8da95284e311d92f21031 (diff) | |
| download | bcm5719-llvm-b13df6582a6a7802d4e0675a4ae7545c09a766a9.tar.gz bcm5719-llvm-b13df6582a6a7802d4e0675a4ae7545c09a766a9.zip | |
Add support for weak symbols.
llvm-svn: 244636
| -rw-r--r-- | lld/ELF/InputFiles.cpp | 14 | ||||
| -rw-r--r-- | lld/ELF/Symbols.cpp | 15 | ||||
| -rw-r--r-- | lld/ELF/Symbols.h | 14 | ||||
| -rw-r--r-- | lld/test/elf2/Inputs/invalid-binding.elf | bin | 0 -> 536 bytes | |||
| -rw-r--r-- | lld/test/elf2/Inputs/local.s | 1 | ||||
| -rw-r--r-- | lld/test/elf2/Inputs/resolution.s | 10 | ||||
| -rw-r--r-- | lld/test/elf2/invalid-elf.test | 4 | ||||
| -rw-r--r-- | lld/test/elf2/resolution.s (renamed from lld/test/elf2/local.s) | 7 |
8 files changed, 54 insertions, 11 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 9dcd2faede8..3a1196761cf 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -75,9 +75,17 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable); error(NameOrErr.getError()); StringRef Name = *NameOrErr; - if (Sym->isUndefined()) - return new (Alloc) Undefined(Name); - return new (Alloc) DefinedRegular<ELFT>(Name); + switch (Sym->getBinding()) { + default: + error("unexpected binding"); + case STB_GLOBAL: + if (Sym->isUndefined()) + return new (Alloc) Undefined(Name); + return new (Alloc) DefinedRegular<ELFT>(Name); + case STB_WEAK: + // FIXME: add support for weak undefined + return new (Alloc) DefinedWeak<ELFT>(Name); + } } namespace lld { diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 32bcf8e8793..09644374066 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -21,6 +21,10 @@ template <class ELFT> DefinedRegular<ELFT>::DefinedRegular(StringRef Name) : Defined(DefinedRegularKind, Name) {} +template <class ELFT> +DefinedWeak<ELFT>::DefinedWeak(StringRef Name) + : Defined(DefinedWeakKind, Name) {} + // Returns 1, 0 or -1 if this symbol should take precedence // over the Other, tie or lose, respectively. int SymbolBody::compare(SymbolBody *Other) { @@ -32,16 +36,14 @@ int SymbolBody::compare(SymbolBody *Other) { return -Other->compare(this); // First handle comparisons between two different kinds. - if (LK != RK) { - assert(LK == DefinedRegularKind); - assert(RK == UndefinedKind); + if (LK != RK) return 1; - } // Now handle the case where the kinds are the same. switch (LK) { case DefinedRegularKind: return 0; + case DefinedWeakKind: case UndefinedKind: return 1; } @@ -54,5 +56,10 @@ template class DefinedRegular<llvm::object::ELF32LE>; template class DefinedRegular<llvm::object::ELF32BE>; template class DefinedRegular<llvm::object::ELF64LE>; template class DefinedRegular<llvm::object::ELF64BE>; + +template class DefinedWeak<llvm::object::ELF32LE>; +template class DefinedWeak<llvm::object::ELF32BE>; +template class DefinedWeak<llvm::object::ELF64LE>; +template class DefinedWeak<llvm::object::ELF64BE>; } } diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 197a30ce359..18e31dacc2f 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -37,8 +37,9 @@ public: enum Kind { DefinedFirst = 0, DefinedRegularKind = 0, - DefinedLast = 0, - UndefinedKind = 1, + DefinedWeakKind = 1, + DefinedLast = 1, + UndefinedKind = 2 }; Kind kind() const { return static_cast<Kind>(SymbolKind); } @@ -92,6 +93,15 @@ public: } }; +template <class ELFT> class DefinedWeak : public Defined { +public: + DefinedWeak(StringRef Name); + + static bool classof(const SymbolBody *S) { + return S->kind() == DefinedWeakKind; + } +}; + // Undefined symbols. class Undefined : public SymbolBody { public: diff --git a/lld/test/elf2/Inputs/invalid-binding.elf b/lld/test/elf2/Inputs/invalid-binding.elf Binary files differnew file mode 100644 index 00000000000..61b5af9b456 --- /dev/null +++ b/lld/test/elf2/Inputs/invalid-binding.elf diff --git a/lld/test/elf2/Inputs/local.s b/lld/test/elf2/Inputs/local.s deleted file mode 100644 index a5c4ffc9952..00000000000 --- a/lld/test/elf2/Inputs/local.s +++ /dev/null @@ -1 +0,0 @@ -local: diff --git a/lld/test/elf2/Inputs/resolution.s b/lld/test/elf2/Inputs/resolution.s new file mode 100644 index 00000000000..e3ab0482c67 --- /dev/null +++ b/lld/test/elf2/Inputs/resolution.s @@ -0,0 +1,10 @@ +local: + +.weak foo +foo: + +.weak _start +_start: + +.weak bar +bar: diff --git a/lld/test/elf2/invalid-elf.test b/lld/test/elf2/invalid-elf.test index 95fd67164d5..5b2bea3994f 100644 --- a/lld/test/elf2/invalid-elf.test +++ b/lld/test/elf2/invalid-elf.test @@ -9,3 +9,7 @@ INVALID-FILE-CLASS: Invalid file class RUN: not lld -flavor gnu2 %p/Inputs/invalid-symtab-sh_info.elf -o %t2 2>&1 | \ RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s INVALID-SYMTAB-SHINFO: Invalid sh_info in symbol table + +RUN: not lld -flavor gnu2 %p/Inputs/invalid-binding.elf -o %t2 2>&1 | \ +RUN: FileCheck --check-prefix=INVALID-BINDING %s +INVALID-BINDING: unexpected binding diff --git a/lld/test/elf2/local.s b/lld/test/elf2/resolution.s index 295ff614547..a49c7d5a1a5 100644 --- a/lld/test/elf2/local.s +++ b/lld/test/elf2/resolution.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t -// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/local.s -o %t2 +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/resolution.s -o %t2 // RUN: lld -flavor gnu2 %t %t2 -o %t3 // REQUIRES: x86 @@ -8,3 +8,8 @@ _start: nop local: + +.weak foo +foo: + +.long bar |

