summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-07-10 20:14:22 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-07-10 20:14:22 +0000
commit5159718095bd8a18c1661889e93af3aca8eaa5aa (patch)
tree0404298ed72edcfe60e8fb18c6d9a14bb3962909
parented094c32ff2683c07d8eec558ee9defa4f0c00f6 (diff)
downloadllvm-5159718095bd8a18c1661889e93af3aca8eaa5aa.tar.gz
llvm-5159718095bd8a18c1661889e93af3aca8eaa5aa.tar.bz2
llvm-5159718095bd8a18c1661889e93af3aca8eaa5aa.tar.xz
Don't crash in 'llvm -s' when an archive has no symtab.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186029 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Object/Archive.cpp8
-rw-r--r--test/Object/nm-archive.test27
-rw-r--r--tools/llvm-nm/llvm-nm.cpp25
3 files changed, 38 insertions, 22 deletions
diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp
index 292d50a176..91cc4efde2 100644
--- a/lib/Object/Archive.cpp
+++ b/lib/Object/Archive.cpp
@@ -210,7 +210,7 @@ error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const {
}
Archive::Archive(MemoryBuffer *source, error_code &ec)
- : Binary(Binary::ID_Archive, source) {
+ : Binary(Binary::ID_Archive, source), SymbolTable(end_children()) {
// Check for sufficient magic.
if (!source || source->getBufferSize()
< (8 + sizeof(ArchiveMemberHeader)) // Smallest archive.
@@ -375,6 +375,9 @@ Archive::Symbol Archive::Symbol::getNext() const {
}
Archive::symbol_iterator Archive::begin_symbols() const {
+ if (SymbolTable == end_children())
+ return symbol_iterator(Symbol(this, 0, 0));
+
const char *buf = SymbolTable->getBuffer().begin();
if (kind() == K_GNU) {
uint32_t symbol_count = 0;
@@ -395,6 +398,9 @@ Archive::symbol_iterator Archive::begin_symbols() const {
}
Archive::symbol_iterator Archive::end_symbols() const {
+ if (SymbolTable == end_children())
+ return symbol_iterator(Symbol(this, 0, 0));
+
const char *buf = SymbolTable->getBuffer().begin();
uint32_t symbol_count = 0;
if (kind() == K_GNU) {
diff --git a/test/Object/nm-archive.test b/test/Object/nm-archive.test
index 922983c887..99efc1bec6 100644
--- a/test/Object/nm-archive.test
+++ b/test/Object/nm-archive.test
@@ -1,25 +1,32 @@
RUN: llvm-nm %p/Inputs/archive-test.a-coff-i386 \
RUN: | FileCheck %s -check-prefix COFF
+COFF: trivial-object-test.coff-i386:
+COFF-NEXT: 00000000 d .data
+COFF-NEXT: 00000000 t .text
+COFF-NEXT: 00000000 d L_.str
+COFF-NEXT: U _SomeOtherFunction
+COFF-NEXT: 00000000 T _main
+COFF-NEXT: U _puts
+
+
RUN: llvm-as %p/Inputs/trivial.ll -o=%t1
RUN: rm -f %t2
RUN: llvm-ar rcs %t2 %t1
RUN: llvm-nm %t2 | FileCheck %s -check-prefix BITCODE
+BITCODE: U SomeOtherFunction
+BITCODE-NEXT: T main
+BITCODE-NEXT: U puts
+
+
Test we don't error with an archive with no symtab.
RUN: llvm-nm %p/Inputs/archive-test.a-gnu-no-symtab
+
Or in an archive with no symtab or string table.
RUN: llvm-nm %p/Inputs/archive-test.a-gnu-minimal
-COFF: trivial-object-test.coff-i386:
-COFF-NEXT: 00000000 d .data
-COFF-NEXT: 00000000 t .text
-COFF-NEXT: 00000000 d L_.str
-COFF-NEXT: U _SomeOtherFunction
-COFF-NEXT: 00000000 T _main
-COFF-NEXT: U _puts
-BITCODE: U SomeOtherFunction
-BITCODE-NEXT: T main
-BITCODE-NEXT: U puts
+And don't crash when asked to print a non existing symtab.
+RUN: llvm-nm -s %p/Inputs/archive-test.a-gnu-minimal
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
index c33289bd87..01dd1c33fd 100644
--- a/tools/llvm-nm/llvm-nm.cpp
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -365,21 +365,24 @@ static void DumpSymbolNamesFromFile(std::string &Filename) {
if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) {
if (ArchiveMap) {
- outs() << "Archive map" << "\n";
- for (object::Archive::symbol_iterator i = a->begin_symbols(),
- e = a->end_symbols(); i != e; ++i) {
- object::Archive::child_iterator c;
- StringRef symname;
- StringRef filename;
- if (error(i->getMember(c)))
+ object::Archive::symbol_iterator I = a->begin_symbols();
+ object::Archive::symbol_iterator E = a->end_symbols();
+ if (I !=E) {
+ outs() << "Archive map" << "\n";
+ for (; I != E; ++I) {
+ object::Archive::child_iterator c;
+ StringRef symname;
+ StringRef filename;
+ if (error(I->getMember(c)))
return;
- if (error(i->getName(symname)))
+ if (error(I->getName(symname)))
return;
- if (error(c->getName(filename)))
+ if (error(c->getName(filename)))
return;
- outs() << symname << " in " << filename << "\n";
+ outs() << symname << " in " << filename << "\n";
+ }
+ outs() << "\n";
}
- outs() << "\n";
}
for (object::Archive::child_iterator i = a->begin_children(),