From 5159718095bd8a18c1661889e93af3aca8eaa5aa Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 10 Jul 2013 20:14:22 +0000 Subject: [PATCH] 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 --- lib/Object/Archive.cpp | 8 +++++++- test/Object/nm-archive.test | 27 +++++++++++++++++---------- tools/llvm-nm/llvm-nm.cpp | 25 ++++++++++++++----------- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp index 292d50a1763..91cc4efde22 100644 --- a/lib/Object/Archive.cpp +++ b/lib/Object/Archive.cpp @@ -210,7 +210,7 @@ error_code Archive::Child::getAsBinary(OwningPtr &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 922983c887f..99efc1bec67 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 c33289bd875..01dd1c33fdc 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(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(), -- 2.11.0