[llvm] r241869 - [Object][ELF] Support dumping hash-tables from files with no section table.

Kuperstein, Michael M michael.m.kuperstein at intel.com
Tue Jul 14 07:42:47 PDT 2015


Hi Michael,

Looks like this breaks MSVC 32-bit builds (64-bit is fine, as the green buildbots show).
The stack traces look something like this:

>llvm-readobj.EXE -r -expand-relocs ..\..\..\test\tools\llvm-readobj/Inputs/relocs.obj.elf-aarch64
Assertion failed: (uintptr_t(data.buffer) & (alignOf<RootLeaf>() - 1)) == 0 && "Insufficient alignment", file C:\llvm\include\llvm/ADT/IntervalMap.h, line 1045
0x00F66C39 (0x00000016 0x9B3896AF 0x00A8F34C 0x00A8F168), HandleAbort() + 0x9 bytes(s), c:\llvm\lib\support\windows\signals.inc, line 296
0x5CFEF7F9 (0x00000016 0x00F66C30 0x00A8F154 0x5CFE9AC4), raise() + 0x2B9 bytes(s)
0x5CFFB284 (0x00A8F34C 0x00A8F168 0x000000A7 0x00D30150), abort() + 0x34 bytes(s)
0x5CFE9AC4 (0x013D1C70 0x013D1758 0x00000415 0x00000008), _wassert() + 0xD4 bytes(s)
0x00F0F694 (0x00A8F2EC 0x00000000 0x00000008 0xCCCCCCCC), llvm::IntervalMap<unsigned __int64,unsigned int,9,llvm::IntervalMapHalfOpenInfo<unsigned __int64> >::IntervalMap<unsigned __int64,unsigned int,9,llvm::IntervalMapHalfOpenInfo<unsigned __int64> >() + 0x74 bytes(s), c:\llvm\include\llvm\adt\intervalmap.h, line 1044 + 0x2F byte(s)
0x00F22253 (0x00A8F52C 0x00000000 0x00000001 0x00000460), llvm::object::ELFFile<llvm::object::ELFType<1,1> >::scanDynamicTable() + 0x43 bytes(s), c:\llvm\bitset\include\llvm\object\elf.h, line 736
0x00F0D420 (0x00D84FF8 0x00001088 0x00A8F510 0x01CCCCCC), llvm::object::ELFFile<llvm::object::ELFType<1,1> >::ELFFile<llvm::object::ELFType<1,1> >() + 0x810 bytes(s), c:\llvm\include\llvm\object\elf.h, line 723
0x00F0F1A0 (0x00D84FF8 0x00001088 0x00D84FB4 0x0000003E), llvm::object::ELFObjectFile<llvm::object::ELFType<1,1> >::ELFObjectFile<llvm::object::ELFType<1,1> >() + 0x90 bytes(s), c:\llvm\include\llvm\object\elfobjectfile.h, line 744 + 0x90 byte(s)
0x00F070C7 (0x00A8F60C 0x00D84FF8 0x00001088 0x00D84FB4), llvm::object::ObjectFile::createELFObjectFile() + 0x1C7 bytes(s), c:\llvm\lib\object\elfobjectfile.cpp, line 44 + 0x3E byte(s)
0x00EE8EF6 (0x00A8F60C 0x00D84FF8 0x00001088 0x00D84FB4), llvm::object::ObjectFile::createObjectFile() + 0xA6 bytes(s), c:\llvm\lib\object\objectfile.cpp, line 80 + 0x25 byte(s)
0x00F0645D (0x00A8F668 0x00D84FF8 0x00001088 0x00D84FB4), llvm::object::SymbolicFile::createSymbolicFile() + 0x14D bytes(s), c:\llvm\lib\object\symbolicfile.cpp, line 64 + 0x29 byte(s)
0x00EEFABD (0x00A8F700 0x00D84FF8 0x00001088 0x00D84FB4), llvm::object::createBinary() + 0xCD bytes(s), c:\llvm\lib\object\binary.cpp, line 66 + 0x2F byte(s)
0x00EEFC58 (0x00A8F78C 0x00D82808 0x0000003E 0x00A8F850), llvm::object::createBinary() + 0xB8 bytes(s), c:\llvm\lib\object\binary.cpp, line 85 + 0x39 byte(s)
0x00ED193D (0x00D82808 0x0000003E 0xCCCCCCCC 0x00A8F7D8), dumpInput() + 0x8D bytes(s), c:\llvm\tools\llvm-readobj\llvm-readobj.cpp, line 375 + 0x11 byte(s)
0x00ED2C53 (0x00D79F70 0x00D79F8C 0x00A8F7F8 0xCCCCCCCC), std::_For_each<std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,void (__cdecl*)(llvm::StringRef)>() + 0x33 bytes(s), c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm, line 24 + 0x15 byte(s)
0x00ED3B9F (0x00D7FA38 0x00A8F7EC 0x00D79F70 0x00D7FA38), std::for_each<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >,void (__cdecl*)(llvm::StringRef)>() + 0x8F bytes(s), c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm, line 33 + 0x37 byte(s)
0x00ED1B2B (0x00000004 0x00D7F990 0x00D7CF20 0xE91289D2), main() + 0xBB bytes(s), c:\llvm\tools\llvm-readobj\llvm-readobj.cpp, line 408 + 0x26 byte(s)
0x01284C59 (0x00A8F8B4 0x7590336A 0x7EFDE000 0x00A8F8F4), __tmainCRTStartup() + 0x199 bytes(s), f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c, line 626 + 0x19 byte(s)
0x01284D9D (0x7EFDE000 0x00A8F8F4 0x77209F72 0x7EFDE000), mainCRTStartup() + 0xD bytes(s), f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c, line 466
0x7590336A (0x7EFDE000 0x0507E442 0x00000000 0x00000000), BaseThreadInitThunk() + 0x12 bytes(s)
0x77209F72 (0x01284D90 0x7EFDE000 0x00000000 0x00000000), RtlInitializeExceptionChain() + 0x63 bytes(s)
0x77209F45 (0x01284D90 0x7EFDE000 0x00000000 0x00000000), RtlInitializeExceptionChain() + 0x36 bytes(s)

The failure is intermittent (I guess it depends on alignment :-) ) - happens once in every 3 or 4 runs, but on average it makes >100 tests to fail when running check-llvm.

Thanks,
  Michael

-----Original Message-----
From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Michael J. Spencer
Sent: Friday, July 10, 2015 01:32
To: llvm-commits at cs.uiuc.edu
Subject: [llvm] r241869 - [Object][ELF] Support dumping hash-tables from files with no section table.

Author: mspencer
Date: Thu Jul  9 17:32:24 2015
New Revision: 241869

URL: http://llvm.org/viewvc/llvm-project?rev=241869&view=rev
Log:
[Object][ELF] Support dumping hash-tables from files with no section table.

This time without breaking the bots.

Added:
    llvm/trunk/test/Object/Inputs/no-section-table.so
    llvm/trunk/test/Object/no-section-table.test
Modified:
    llvm/trunk/include/llvm/Object/ELF.h
    llvm/trunk/include/llvm/Object/ELFTypes.h
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
    llvm/trunk/tools/llvm-readobj/ObjDumper.h
    llvm/trunk/tools/llvm-readobj/StreamWriter.h
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp

Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=241869&r1=241868&r2=241869&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Thu Jul  9 17:32:24 2015
@@ -16,6 +16,7 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -139,6 +140,7 @@ public:
   typedef Elf_Verneed_Impl<ELFT> Elf_Verneed;
   typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
   typedef Elf_Versym_Impl<ELFT> Elf_Versym;
+  typedef Elf_Hash<ELFT> Elf_Hash;
   typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter;
   typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range;
   typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter; @@ -176,6 +178,7 @@ private:
   const Elf_Shdr *dot_symtab_sec = nullptr; // Symbol table section.
   StringRef DynSymStrTab;                   // Dynnamic symbol string table.
   const Elf_Shdr *DotDynSymSec = nullptr;   // Dynamic symbol table section.
+  const Elf_Hash *HashTable = nullptr;
 
   const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr;
   DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable; @@ -229,6 +232,8 @@ private:
   void LoadVersionNeeds(const Elf_Shdr *ec) const;
   void LoadVersionMap() const;
 
+  void scanDynamicTable();
+
 public:
   template<typename T>
   const T        *getEntry(uint32_t Section, uint32_t Entry) const;
@@ -237,6 +242,7 @@ public:
 
   const Elf_Shdr *getDotSymtabSec() const { return dot_symtab_sec; }
   const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; }
+  const Elf_Hash *getHashTable() const { return HashTable; }
 
   ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const;
   const char *getDynamicString(uintX_t Offset) const; @@ -578,8 +584,10 @@ ELFFile<ELFT>::ELFFile(StringRef Object,
 
   Header = reinterpret_cast<const Elf_Ehdr *>(base());
 
-  if (Header->e_shoff == 0)
+  if (Header->e_shoff == 0) {
+    scanDynamicTable();
     return;
+  }
 
   const uint64_t SectionTableOffset = Header->e_shoff;
 
@@ -604,6 +612,13 @@ ELFFile<ELFT>::ELFFile(StringRef Object,
 
   for (const Elf_Shdr &Sec : sections()) {
     switch (Sec.sh_type) {
+    case ELF::SHT_HASH:
+      if (HashTable) {
+        EC = object_error::parse_failed;
+        return;
+      }
+      HashTable = reinterpret_cast<const Elf_Hash *>(base() + Sec.sh_offset);
+      break;
     case ELF::SHT_SYMTAB_SHNDX:
       if (SymbolTableSectionHeaderIndex) {
         // More than one .symtab_shndx!
@@ -701,7 +716,21 @@ ELFFile<ELFT>::ELFFile(StringRef Object,
     }
   }
 
-  // Scan program headers.
+  scanDynamicTable();
+
+  EC = std::error_code();
+}
+
+template <class ELFT>
+void ELFFile<ELFT>::scanDynamicTable() {
+  // Build load-address to file-offset map.
+  typedef IntervalMap<
+      uintX_t, uintptr_t,
+      IntervalMapImpl::NodeSizer<uintX_t, uintptr_t>::LeafSize,
+      IntervalMapHalfOpenInfo<uintX_t>> LoadMapT;
+  typename LoadMapT::Allocator Alloc;
+  LoadMapT LoadMap(Alloc);
+
   for (Elf_Phdr_Iter PhdrI = program_header_begin(),
                      PhdrE = program_header_end();
        PhdrI != PhdrE; ++PhdrI) {
@@ -709,34 +738,36 @@ ELFFile<ELFT>::ELFFile(StringRef Object,
       DynamicRegion.Addr = base() + PhdrI->p_offset;
       DynamicRegion.Size = PhdrI->p_filesz;
       DynamicRegion.EntSize = sizeof(Elf_Dyn);
-      break;
+      continue;
     }
+    if (PhdrI->p_type != ELF::PT_LOAD)
+      continue;
+    if (PhdrI->p_filesz == 0)
+      continue;
+    LoadMap.insert(PhdrI->p_vaddr, PhdrI->p_vaddr + PhdrI->p_filesz,
+                   PhdrI->p_offset);
   }
 
-  // Scan dynamic table.
+  auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {
+    auto I = LoadMap.find(VAddr);
+    if (I == LoadMap.end())
+      return nullptr;
+    return base() + I.value() + (VAddr - I.start());  };
+
   for (Elf_Dyn_Iter DynI = dynamic_table_begin(), DynE = dynamic_table_end();
        DynI != DynE; ++DynI) {
     switch (DynI->d_tag) {
-    case ELF::DT_RELA: {
-      uint64_t VBase = 0;
-      const uint8_t *FBase = nullptr;
-      for (Elf_Phdr_Iter PhdrI = program_header_begin(),
-                         PhdrE = program_header_end();
-           PhdrI != PhdrE; ++PhdrI) {
-        if (PhdrI->p_type != ELF::PT_LOAD)
-          continue;
-        if (DynI->getPtr() >= PhdrI->p_vaddr &&
-            DynI->getPtr() < PhdrI->p_vaddr + PhdrI->p_memsz) {
-          VBase = PhdrI->p_vaddr;
-          FBase = base() + PhdrI->p_offset;
-          break;
-        }
-      }
-      if (!VBase)
-        return;
-      DynRelaRegion.Addr = FBase + DynI->getPtr() - VBase;
+    case ELF::DT_HASH:
+      if (HashTable)
+        continue;
+      HashTable =
+          reinterpret_cast<const Elf_Hash *>(toMappedAddr(DynI->getPtr()));
+      break;
+    case ELF::DT_RELA:
+      if (!DynRelaRegion.Addr)
+        DynRelaRegion.Addr = toMappedAddr(DynI->getPtr());
       break;
-    }
     case ELF::DT_RELASZ:
       DynRelaRegion.Size = DynI->getVal();
       break;
@@ -744,8 +775,6 @@ ELFFile<ELFT>::ELFFile(StringRef Object,
       DynRelaRegion.EntSize = DynI->getVal();
     }
   }
-
-  EC = std::error_code();
 }
 
 template <class ELFT>

Modified: llvm/trunk/include/llvm/Object/ELFTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFTypes.h?rev=241869&r1=241868&r2=241869&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFTypes.h (original)
+++ llvm/trunk/include/llvm/Object/ELFTypes.h Thu Jul  9 17:32:24 2015
@@ -10,6 +10,7 @@
 #ifndef LLVM_OBJECT_ELFTYPES_H
 #define LLVM_OBJECT_ELFTYPES_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/ELF.h"
@@ -463,6 +464,23 @@ struct Elf_Phdr_Impl<ELFType<TargetEndia
   Elf_Xword p_align;  // Segment alignment constraint  };
 
+// ELFT needed for endianess.
+template <class ELFT>
+struct Elf_Hash {
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+  Elf_Word nbucket;
+  Elf_Word nchain;
+
+  ArrayRef<Elf_Word> buckets() const {
+    return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);  }
+
+  ArrayRef<Elf_Word> chains() const {
+    return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
+                              &nbucket + 2 + nbucket + nchain);
+  }
+};
+
 // MIPS .reginfo section
 template <class ELFT>
 struct Elf_Mips_RegInfo;

Added: llvm/trunk/test/Object/Inputs/no-section-table.so
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/no-section-table.so?rev=241869&view=auto
==============================================================================
Binary files llvm/trunk/test/Object/Inputs/no-section-table.so (added) and llvm/trunk/test/Object/Inputs/no-section-table.so Thu Jul  9 17:32:24 2015 differ

Added: llvm/trunk/test/Object/no-section-table.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/no-section-table.test?rev=241869&view=auto
==============================================================================
--- llvm/trunk/test/Object/no-section-table.test (added)
+++ llvm/trunk/test/Object/no-section-table.test Thu Jul  9 17:32:24 
+++ 2015
@@ -0,0 +1,8 @@
+RUN: llvm-readobj %p/Inputs/no-section-table.so -hash-table | FileCheck 
+%s
+
+CHECK: HashTable {
+CHECK:   Num Buckets: 3
+CHECK:   Num Chains: 13
+CHECK:   Buckets: [12, 10, 11]
+CHECK:   Chains: [0, 0, 0, 0, 2, 3, 4, 0, 7, 5, 6, 8, 9]
+CHECK: }

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=241869&r1=241868&r2=241869&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Thu Jul  9 17:32:24 2015
@@ -56,6 +56,7 @@ public:
   void printDynamicTable() override;
   void printNeededLibraries() override;
   void printProgramHeaders() override;
+  void printHashTable() override;
 
   void printAttributes() override;
   void printMipsPLTGOT() override;
@@ -1119,6 +1120,18 @@ void ELFDumper<ELFT>::printProgramHeader
   }
 }
 
+template <typename ELFT>
+void ELFDumper<ELFT>::printHashTable() {
+  DictScope D(W, "HashTable");
+  auto HT = Obj->getHashTable();
+  if (!HT)
+    return;
+  W.printNumber("Num Buckets", HT->nbucket);
+  W.printNumber("Num Chains", HT->nchain);
+  W.printList("Buckets", HT->buckets());
+  W.printList("Chains", HT->chains());
+}
+
 template <class ELFT>
 void ELFDumper<ELFT>::printAttributes() {
   W.startLine() << "Attributes not implemented.\n";

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.h?rev=241869&r1=241868&r2=241869&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.h (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.h Thu Jul  9 17:32:24 2015
@@ -37,6 +37,7 @@ public:
   virtual void printDynamicTable() { }
   virtual void printNeededLibraries() { }
   virtual void printProgramHeaders() { }
+  virtual void printHashTable() { }
 
   // Only implemented for ARM ELF at this time.
   virtual void printAttributes() { }

Modified: llvm/trunk/tools/llvm-readobj/StreamWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/StreamWriter.h?rev=241869&r1=241868&r2=241869&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/StreamWriter.h (original)
+++ llvm/trunk/tools/llvm-readobj/StreamWriter.h Thu Jul  9 17:32:24 
+++ 2015
@@ -181,8 +181,8 @@ public:
     startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
   }
 
-  template <typename T_>
-  void printList(StringRef Label, const SmallVectorImpl<T_> &List) {
+  template <typename T>
+  void printList(StringRef Label, const T &List) {
     startLine() << Label << ": [";
     bool Comma = false;
     for (const auto &Item : List) {

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=241869&r1=241868&r2=241869&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Thu Jul  9 17:32:24 
+++ 2015
@@ -127,6 +127,10 @@ namespace opts {
   cl::opt<bool> ProgramHeaders("program-headers",
     cl::desc("Display ELF program headers"));
 
+  // -hash-table
+  cl::opt<bool> HashTable("hash-table",
+    cl::desc("Display ELF hash table"));
+
   // -expand-relocs
   cl::opt<bool> ExpandRelocs("expand-relocs",
     cl::desc("Expand each shown relocation to multiple lines")); @@ -300,6 +304,8 @@ static void dumpObject(const ObjectFile
     Dumper->printNeededLibraries();
   if (opts::ProgramHeaders)
     Dumper->printProgramHeaders();
+  if (opts::HashTable)
+    Dumper->printHashTable();
   if (Obj->getArch() == llvm::Triple::arm && Obj->isELF())
     if (opts::ARMAttributes)
       Dumper->printAttributes();


_______________________________________________
llvm-commits mailing list
llvm-commits at cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.





More information about the llvm-commits mailing list