[llvm-commits] [llvm] r167853 - in /llvm/trunk: include/llvm/Object/Archive.h lib/Object/Archive.cpp test/Object/Inputs/coff_archive.lib test/Object/Inputs/liblong_filenames.a test/Object/Inputs/libsimple_archive.a test/Object/archive-long-index.test test/Object/coff-archive.test test/Object/simple-archive.test tools/llvm-nm/llvm-nm.cpp

Shankar Easwaran shankare at codeaurora.org
Tue Nov 13 10:38:42 PST 2012


Author: shankare
Date: Tue Nov 13 12:38:42 2012
New Revision: 167853

URL: http://llvm.org/viewvc/llvm-project?rev=167853&view=rev
Log:
Adding changes to support GNU style archive library reading

Added:
    llvm/trunk/test/Object/Inputs/coff_archive.lib   (with props)
    llvm/trunk/test/Object/Inputs/liblong_filenames.a   (with props)
    llvm/trunk/test/Object/Inputs/libsimple_archive.a   (with props)
    llvm/trunk/test/Object/archive-long-index.test
    llvm/trunk/test/Object/coff-archive.test
    llvm/trunk/test/Object/simple-archive.test
Modified:
    llvm/trunk/include/llvm/Object/Archive.h
    llvm/trunk/lib/Object/Archive.cpp
    llvm/trunk/tools/llvm-nm/llvm-nm.cpp

Modified: llvm/trunk/include/llvm/Object/Archive.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Archive.h?rev=167853&r1=167852&r2=167853&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Archive.h (original)
+++ llvm/trunk/include/llvm/Object/Archive.h Tue Nov 13 12:38:42 2012
@@ -122,6 +122,16 @@
 
   Archive(MemoryBuffer *source, error_code &ec);
 
+  enum Kind {
+    K_GNU,
+    K_BSD,
+    K_COFF
+  };
+
+  Kind kind() const { 
+    return Format;
+  }
+
   child_iterator begin_children(bool skip_internal = true) const;
   child_iterator end_children() const;
 
@@ -133,9 +143,13 @@
     return v->isArchive();
   }
 
+  // check if a symbol is in the archive
+  child_iterator findSym(StringRef name) const;
+
 private:
   child_iterator SymbolTable;
   child_iterator StringTable;
+  Kind Format;
 };
 
 }

Modified: llvm/trunk/lib/Object/Archive.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Archive.cpp?rev=167853&r1=167852&r2=167853&view=diff
==============================================================================
--- llvm/trunk/lib/Object/Archive.cpp (original)
+++ llvm/trunk/lib/Object/Archive.cpp Tue Nov 13 12:38:42 2012
@@ -122,7 +122,14 @@
                    + sizeof(ArchiveMemberHeader)
                    + Parent->StringTable->getSize()))
       return object_error::parse_failed;
-    Result = addr;
+
+    // GNU long file names end with a /.
+    if (Parent->kind() == K_GNU) {
+      StringRef::size_type End = StringRef(addr).find('/');
+      Result = StringRef(addr, End);
+    } else {
+      Result = addr;
+    }
     return object_error::success;
   } else if (name.startswith("#1/")) {
     APInt name_size;
@@ -187,15 +194,52 @@
   child_iterator i = begin_children(false);
   child_iterator e = end_children();
 
-  if (i != e) ++i; // Nobody cares about the first member.
-  if (i != e) {
-    SymbolTable = i;
-    ++i;
-  }
-  if (i != e) {
-    StringTable = i;
-  }
+  StringRef name;
+  if ((ec = i->getName(name)))
+    return;
 
+  // Below is the pattern that is used to figure out the archive format
+  // GNU archive format
+  //  First member : / (points to the symbol table )
+  //  Second member : // (may exist, if it exists, points to the string table)
+  //  Note : The string table is used if the filename exceeds 15 characters
+  // BSD archive format
+  //  First member : __.SYMDEF (points to the symbol table)
+  //  There is no string table, if the filename exceeds 15 characters or has a 
+  //  embedded space, the filename has #1/<size>, The size represents the size 
+  //  of the filename that needs to be read after the archive header
+  // COFF archive format
+  //  First member : /
+  //  Second member : / (provides a directory of symbols)
+  //  Third member : // contains the string table, this is present even if the
+  //                    string table is empty
+  if (name == "/") {
+    SymbolTable = i;
+    StringTable = e;
+    if (i != e) ++i;
+    if ((ec = i->getName(name)))
+      return;
+    if (name[0] != '/') {
+      Format = K_GNU;
+    } else if ((name.size() > 1) && (name == "//")) { 
+      Format = K_GNU;
+      StringTable = i;
+      ++i;
+    } else  { 
+      Format = K_COFF;
+      if (i != e) {
+        SymbolTable = i;
+        ++i;
+      }
+      if (i != e) {
+        StringTable = i;
+      }
+    }
+  } else if (name == "__.SYMDEF") {
+    Format = K_BSD;
+    SymbolTable = i;
+    StringTable = e;
+  } 
   ec = object_error::success;
 }
 
@@ -222,17 +266,28 @@
 
 error_code Archive::Symbol::getMember(child_iterator &Result) const {
   const char *buf = Parent->SymbolTable->getBuffer()->getBufferStart();
-  uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
   const char *offsets = buf + 4;
-  buf += 4 + (member_count * 4); // Skip offsets.
-  const char *indicies = buf + 4;
-
-  uint16_t offsetindex =
-    *(reinterpret_cast<const support::ulittle16_t*>(indicies)
-      + SymbolIndex);
-
-  uint32_t offset = *(reinterpret_cast<const support::ulittle32_t*>(offsets)
-                      + (offsetindex - 1));
+  uint32_t offset = 0;
+  if (Parent->kind() == K_GNU) {
+    offset = *(reinterpret_cast<const support::ubig32_t*>(offsets) 
+                          + SymbolIndex);
+  } else if (Parent->kind() == K_BSD) {
+    assert("BSD format is not supported");
+  } else {
+    uint32_t member_count = 0;
+    member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+    buf += 4 + (member_count * 4); // Skip offsets.
+    const char *indicies = buf + 4;
+    uint16_t offsetindex =
+      *(reinterpret_cast<const support::ulittle16_t*>(indicies)
+        + SymbolIndex);
+    uint32_t *offsetaddr = 
+             (uint32_t *)(reinterpret_cast<const support::ulittle32_t*>(offsets)
+                          + (offsetindex - 1));
+    assert((const char *)offsetaddr < 
+           Parent->SymbolTable->getBuffer()->getBufferEnd());
+    offset = *(offsetaddr);
+  }
 
   const char *Loc = Parent->getData().begin() + offset;
   size_t Size = sizeof(ArchiveMemberHeader) +
@@ -253,10 +308,20 @@
 
 Archive::symbol_iterator Archive::begin_symbols() const {
   const char *buf = SymbolTable->getBuffer()->getBufferStart();
-  uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
-  buf += 4 + (member_count * 4); // Skip offsets.
-  uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
-  buf += 4 + (symbol_count * 2); // Skip indices.
+  if (kind() == K_GNU) {
+    uint32_t symbol_count = 0;
+    symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
+    buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
+  } else if (kind() == K_BSD) {
+    assert("BSD archive format is not supported");
+  } else {
+    uint32_t member_count = 0;
+    uint32_t symbol_count = 0;
+    member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+    buf += 4 + (member_count * 4); // Skip offsets.
+    symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+    buf += 4 + (symbol_count * 2); // Skip indices.
+  }
   uint32_t string_start_offset =
     buf - SymbolTable->getBuffer()->getBufferStart();
   return symbol_iterator(Symbol(this, 0, string_start_offset));
@@ -264,9 +329,36 @@
 
 Archive::symbol_iterator Archive::end_symbols() const {
   const char *buf = SymbolTable->getBuffer()->getBufferStart();
-  uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
-  buf += 4 + (member_count * 4); // Skip offsets.
-  uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+  uint32_t symbol_count = 0;
+  if (kind() == K_GNU) {
+    symbol_count = *reinterpret_cast<const support::ubig32_t*>(buf);
+    buf += sizeof(uint32_t) + (symbol_count * (sizeof(uint32_t)));
+  } else if (kind() == K_BSD) {
+    assert("BSD archive format is not supported");
+  } else {
+    uint32_t member_count = 0;
+    member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+    buf += 4 + (member_count * 4); // Skip offsets.
+    symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+  }
   return symbol_iterator(
     Symbol(this, symbol_count, 0));
 }
+
+Archive::child_iterator Archive::findSym(StringRef name) const {
+  Archive::symbol_iterator bs = begin_symbols();
+  Archive::symbol_iterator es = end_symbols();
+  Archive::child_iterator result;
+  
+  StringRef symname;
+  for (; bs != es; ++bs) {
+    if (bs->getName(symname))
+        return end_children();
+    if (symname == name) {
+      if (bs->getMember(result))
+        return end_children();
+      return result;
+    }
+  }
+  return end_children();
+}

Added: llvm/trunk/test/Object/Inputs/coff_archive.lib
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/coff_archive.lib?rev=167853&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/coff_archive.lib
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/Object/Inputs/coff_archive.lib
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/Object/Inputs/liblong_filenames.a
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/liblong_filenames.a?rev=167853&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/liblong_filenames.a
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/Object/Inputs/libsimple_archive.a
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/libsimple_archive.a?rev=167853&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/libsimple_archive.a
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/Object/archive-long-index.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/archive-long-index.test?rev=167853&view=auto
==============================================================================
--- llvm/trunk/test/Object/archive-long-index.test (added)
+++ llvm/trunk/test/Object/archive-long-index.test Tue Nov 13 12:38:42 2012
@@ -0,0 +1,40 @@
+#
+# Check if the index is appearing properly in the output file 
+#
+RUN: llvm-nm -s %p/Inputs/liblong_filenames.a | FileCheck -check-prefix=CHECKIDX %s
+
+CHECKIDX: Archive map
+CHECKIDX: abcdefghijklmnopqrstuvwxyz12345678 in 1.o
+CHECKIDX: main in 1.o
+CHECKIDX: fn1 in 2.o
+CHECKIDX: fn3 in 3.o
+CHECKIDX: fn1 in 3.o
+CHECKIDX: shankar in 4.o
+CHECKIDX: a in 5.o
+CHECKIDX: b in 6.o
+CHECKIDX: a in abcdefghijklmnopqrstuvwxyz1.o
+CHECKIDX: b in abcdefghijklmnopqrstuvwxyz2.o
+CHECKIDX: bda in abcdefghijklmnopqrstuvwxyz2.o
+CHECKIDX: b in abcdefghijklmnopq.o
+CHECKIDX: 1.o:
+CHECKIDX: 00000000 D abcdefghijklmnopqrstuvwxyz12345678
+CHECKIDX:          U bda
+CHECKIDX: 00000000 T main
+CHECKIDX: 2.o:
+CHECKIDX: 00000000 T fn1
+CHECKIDX: 3.o:
+CHECKIDX: 0000000b T fn1
+CHECKIDX: 00000000 T fn3
+CHECKIDX: 4.o:
+CHECKIDX:          C shankar
+CHECKIDX: 5.o:
+CHECKIDX:          C a
+CHECKIDX: 6.o:
+CHECKIDX:          C b
+CHECKIDX: abcdefghijklmnopqrstuvwxyz1.o:
+CHECKIDX:          C a
+CHECKIDX: abcdefghijklmnopqrstuvwxyz2.o:
+CHECKIDX:          C b
+CHECKIDX: 00000000 T bda
+CHECKIDX: abcdefghijklmnopq.o:
+CHECKIDX:          C b

Added: llvm/trunk/test/Object/coff-archive.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/coff-archive.test?rev=167853&view=auto
==============================================================================
--- llvm/trunk/test/Object/coff-archive.test (added)
+++ llvm/trunk/test/Object/coff-archive.test Tue Nov 13 12:38:42 2012
@@ -0,0 +1,225 @@
+#
+# Check if the index is appearing properly in the output file 
+#
+RUN: llvm-nm -s %p/Inputs/coff_archive.lib | FileCheck -check-prefix=CHECKIDX %s
+
+CHECKIDX: Archive map
+CHECKIDX: ??0invalid_argument at std@@QAE at PBD@Z in Debug\mymath.obj
+CHECKIDX: ??0logic_error at std@@QAE at PBD@Z in Debug\mymath.obj
+CHECKIDX: ??1invalid_argument at std@@UAE at XZ in Debug\mymath.obj
+CHECKIDX: ??1logic_error at std@@UAE at XZ in Debug\mymath.obj
+CHECKIDX: ??_7invalid_argument at std@@6B@ in Debug\mymath.obj
+CHECKIDX: ??_7logic_error at std@@6B@ in Debug\mymath.obj
+CHECKIDX: ??_C at _0BC@IHENMCGI at b?5cannot?5be?5zero?$CB?$AA@ in Debug\mymath.obj
+CHECKIDX: ??_Ginvalid_argument at std@@UAEPAXI at Z in Debug\mymath.obj
+CHECKIDX: ??_Glogic_error at std@@UAEPAXI at Z in Debug\mymath.obj
+CHECKIDX: ??_R0?AVexception at std@@@8 in Debug\mymath.obj
+CHECKIDX: ??_R0?AVinvalid_argument at std@@@8 in Debug\mymath.obj
+CHECKIDX: ??_R0?AVlogic_error at std@@@8 in Debug\mymath.obj
+CHECKIDX: ??_R0PAVexception at std@@@8 in Debug\mymath.obj
+CHECKIDX: ??_R0PAVinvalid_argument at std@@@8 in Debug\mymath.obj
+CHECKIDX: ??_R0PAVlogic_error at std@@@8 in Debug\mymath.obj
+CHECKIDX: ??_R0PAX at 8 in Debug\mymath.obj
+CHECKIDX: ??_R1A@?0A at EA@exception at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R1A@?0A at EA@invalid_argument at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R1A@?0A at EA@logic_error at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R2exception at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R2invalid_argument at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R2logic_error at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R3exception at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R3invalid_argument at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R3logic_error at std@@8 in Debug\mymath.obj
+CHECKIDX: ??_R4invalid_argument at std@@6B@ in Debug\mymath.obj
+CHECKIDX: ??_R4logic_error at std@@6B@ in Debug\mymath.obj
+CHECKIDX: ?Add at MyMathFuncs@MathFuncs@@SANNN at Z in Debug\mymath.obj
+CHECKIDX: ?Divide at MyMathFuncs@MathFuncs@@SANNN at Z in Debug\mymath.obj
+CHECKIDX: ?Multiply at MyMathFuncs@MathFuncs@@SANNN at Z in Debug\mymath.obj
+CHECKIDX: ?Subtract at MyMathFuncs@MathFuncs@@SANNN at Z in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at C@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at D@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at E@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at F@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at G@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at H@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at I@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at J@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at K@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at M@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at N@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at O@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at _J@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at _K@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?_Rank@?$_Arithmetic_traits at _N@std@@2HB in Debug\mymath.obj
+CHECKIDX: ?value@?$integral_constant at I$0A@@tr1 at std@@2IB in Debug\mymath.obj
+CHECKIDX: ?value@?$integral_constant at _N$00 at tr1@std@@2_NB in Debug\mymath.obj
+CHECKIDX: ?value@?$integral_constant at _N$0A@@tr1 at std@@2_NB in Debug\mymath.obj
+CHECKIDX: __CT??_R0PAVexception at std@@@84 in Debug\mymath.obj
+CHECKIDX: __CT??_R0PAVinvalid_argument at std@@@84 in Debug\mymath.obj
+CHECKIDX: __CT??_R0PAVlogic_error at std@@@84 in Debug\mymath.obj
+CHECKIDX: __CT??_R0PAX at 84 in Debug\mymath.obj
+CHECKIDX: __CTA4PAVinvalid_argument at std@@ in Debug\mymath.obj
+CHECKIDX: __TI4PAVinvalid_argument at std@@ in Debug\mymath.obj
+CHECKIDX: __real at 0000000000000000 in Debug\mymath.obj
+CHECKIDX: Debug\stdafx.obj:
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$T
+CHECKIDX: 00000000 i .drectve
+CHECKIDX: 00ab9d1b a @comp.id
+CHECKIDX: 00000001 a @feat.00
+CHECKIDX: Debug\mymath.obj:
+CHECKIDX: 00000000 d .data
+CHECKIDX: 00000000 d .data
+CHECKIDX: 00000000 d .data
+CHECKIDX: 00000000 d .data
+CHECKIDX: 00000000 d .data
+CHECKIDX: 00000000 d .data
+CHECKIDX: 00000000 d .data
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$S
+CHECKIDX: 00000000 N .debug$T
+CHECKIDX: 00000000 i .drectve
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rdata$r
+CHECKIDX: 00000000 r .rtc$IMZ
+CHECKIDX: 00000000 r .rtc$TMZ
+CHECKIDX: 00000000 N .sxdata
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text
+CHECKIDX: 00000000 t .text$x
+CHECKIDX: 00000000 r .xdata$x
+CHECKIDX: 00000000 r .xdata$x
+CHECKIDX: 00000000 r .xdata$x
+CHECKIDX: 00000000 r .xdata$x
+CHECKIDX: 00000000 r .xdata$x
+CHECKIDX: 00000000 r .xdata$x
+CHECKIDX: 00000000 r .xdata$x
+CHECKIDX: 00000000 T ??0invalid_argument at std@@QAE at PBD@Z
+CHECKIDX: 00000000 T ??0logic_error at std@@QAE at PBD@Z
+CHECKIDX: 00000000 T ??1invalid_argument at std@@UAE at XZ
+CHECKIDX: 00000000 T ??1logic_error at std@@UAE at XZ
+CHECKIDX:          U ??2 at YAPAXI@Z
+CHECKIDX:          U ??3 at YAXPAX@Z
+CHECKIDX: 00000004 R ??_7invalid_argument at std@@6B@
+CHECKIDX: 00000004 R ??_7logic_error at std@@6B@
+CHECKIDX:          U ??_7type_info@@6B@
+CHECKIDX: 00000000 R ??_C at _0BC@IHENMCGI at b?5cannot?5be?5zero?$CB?$AA@
+CHECKIDX:          w ??_Einvalid_argument at std@@UAEPAXI at Z
+CHECKIDX:          w ??_Elogic_error at std@@UAEPAXI at Z
+CHECKIDX:          U ??_Ginvalid_argument at std@@UAEPAXI at Z
+CHECKIDX: 00000000 T ??_Ginvalid_argument at std@@UAEPAXI at Z
+CHECKIDX: 00000000 T ??_Glogic_error at std@@UAEPAXI at Z
+CHECKIDX:          U ??_Glogic_error at std@@UAEPAXI at Z
+CHECKIDX: 00000000 D ??_R0?AVexception at std@@@8
+CHECKIDX: 00000000 D ??_R0?AVinvalid_argument at std@@@8
+CHECKIDX: 00000000 D ??_R0?AVlogic_error at std@@@8
+CHECKIDX: 00000000 D ??_R0PAVexception at std@@@8
+CHECKIDX: 00000000 D ??_R0PAVinvalid_argument at std@@@8
+CHECKIDX: 00000000 D ??_R0PAVlogic_error at std@@@8
+CHECKIDX: 00000000 D ??_R0PAX at 8
+CHECKIDX: 00000000 R ??_R1A@?0A at EA@exception at std@@8
+CHECKIDX: 00000000 R ??_R1A@?0A at EA@invalid_argument at std@@8
+CHECKIDX: 00000000 R ??_R1A@?0A at EA@logic_error at std@@8
+CHECKIDX: 00000000 R ??_R2exception at std@@8
+CHECKIDX: 00000000 R ??_R2invalid_argument at std@@8
+CHECKIDX: 00000000 R ??_R2logic_error at std@@8
+CHECKIDX: 00000000 R ??_R3exception at std@@8
+CHECKIDX: 00000000 R ??_R3invalid_argument at std@@8
+CHECKIDX: 00000000 R ??_R3logic_error at std@@8
+CHECKIDX: 00000000 R ??_R4invalid_argument at std@@6B@
+CHECKIDX: 00000000 R ??_R4logic_error at std@@6B@
+CHECKIDX: 00000000 T ?Add at MyMathFuncs@MathFuncs@@SANNN at Z
+CHECKIDX: 00000000 T ?Divide at MyMathFuncs@MathFuncs@@SANNN at Z
+CHECKIDX: 00000000 T ?Multiply at MyMathFuncs@MathFuncs@@SANNN at Z
+CHECKIDX: 00000000 T ?Subtract at MyMathFuncs@MathFuncs@@SANNN at Z
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at C@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at D@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at E@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at F@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at G@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at H@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at I@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at J@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at K@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at M@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at N@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at O@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at _J@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at _K@std@@2HB
+CHECKIDX: 00000000 R ?_Rank@?$_Arithmetic_traits at _N@std@@2HB
+CHECKIDX: 00000000 R ?value@?$integral_constant at I$0A@@tr1 at std@@2IB
+CHECKIDX: 00000000 R ?value@?$integral_constant at _N$00 at tr1@std@@2_NB
+CHECKIDX: 00000000 R ?value@?$integral_constant at _N$0A@@tr1 at std@@2_NB
+CHECKIDX:          U ?what at exception@std@@UBEPBDXZ
+CHECKIDX:          U @__security_check_cookie at 4
+CHECKIDX: 00ab9d1b a @comp.id
+CHECKIDX: 00000001 a @feat.00
+CHECKIDX: 00000000 R __CT??_R0PAVexception at std@@@84
+CHECKIDX: 00000000 R __CT??_R0PAVinvalid_argument at std@@@84
+CHECKIDX: 00000000 R __CT??_R0PAVlogic_error at std@@@84
+CHECKIDX: 00000000 R __CT??_R0PAX at 84
+CHECKIDX: 00000000 R __CTA4PAVinvalid_argument at std@@
+CHECKIDX:          U __CxxThrowException at 8
+CHECKIDX:          U __RTC_CheckEsp
+CHECKIDX:          U __RTC_InitBase
+CHECKIDX: 00000000 r __RTC_InitBase.rtc$IMZ
+CHECKIDX:          U __RTC_Shutdown
+CHECKIDX: 00000000 r __RTC_Shutdown.rtc$TMZ
+CHECKIDX: 00000000 R __TI4PAVinvalid_argument at std@@
+CHECKIDX:          U ___CxxFrameHandler3
+CHECKIDX:          U ___security_cookie
+CHECKIDX: 00000008 r __ehfuncinfo$?Divide at MyMathFuncs@MathFuncs@@SANNN at Z
+CHECKIDX: 0000000e t __ehhandler$?Divide at MyMathFuncs@MathFuncs@@SANNN at Z
+CHECKIDX:          U __fltused
+CHECKIDX:          U __imp_??0exception at std@@QAE at ABQBD@Z
+CHECKIDX:          U __imp_??1exception at std@@UAE at XZ
+CHECKIDX: 00000000 R __real at 0000000000000000
+CHECKIDX: 00000000 t __unwindfunclet$?Divide at MyMathFuncs@MathFuncs@@SANNN at Z$0
+CHECKIDX: 00000000 r __unwindtable$?Divide at MyMathFuncs@MathFuncs@@SANNN at Z

Added: llvm/trunk/test/Object/simple-archive.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/simple-archive.test?rev=167853&view=auto
==============================================================================
--- llvm/trunk/test/Object/simple-archive.test (added)
+++ llvm/trunk/test/Object/simple-archive.test Tue Nov 13 12:38:42 2012
@@ -0,0 +1,12 @@
+#
+# Check if the index is appearing properly in the output file 
+#
+RUN: llvm-nm -s %p/Inputs/libsimple_archive.a | FileCheck -check-prefix=CHECKIDX %s
+
+CHECKIDX: Archive map
+CHECKIDX: abcdefghijklmnopqrstuvwxyz12345678 in 1.o
+CHECKIDX: main in 1.o
+CHECKIDX: 1.o:
+CHECKIDX: 00000000 D abcdefghijklmnopqrstuvwxyz12345678
+CHECKIDX:          U fn1
+CHECKIDX: 00000000 T main

Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=167853&r1=167852&r2=167853&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original)
+++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Tue Nov 13 12:38:42 2012
@@ -113,6 +113,10 @@
   cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden,
                                cl::desc("Exclude aliases from output"));
 
+  cl::opt<bool> ArchiveMap("print-armap",
+    cl::desc("Print the archive map"));
+  cl::alias ArchiveMaps("s", cl::desc("Alias for --print-armap"),
+                                 cl::aliasopt(ArchiveMap));
   bool PrintAddress = true;
 
   bool MultipleFiles = false;
@@ -346,6 +350,24 @@
       return;
 
     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))) 
+              return;
+          if (error(i->getName(symname)))
+              return;
+          if (error(c->getName(filename)))
+              return;
+          outs() << symname << " in " << filename << "\n";
+        }
+        outs() << "\n";
+      }
+
       for (object::Archive::child_iterator i = a->begin_children(),
                                            e = a->end_children(); i != e; ++i) {
         OwningPtr<Binary> child;





More information about the llvm-commits mailing list