|  | @@ -65,6 +65,7 @@ void cmELFByteSwap(T& x)
 | 
	
		
			
				|  |  |  class cmELFInternal
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  public:
 | 
	
		
			
				|  |  | +  typedef cmELF::StringEntry StringEntry;
 | 
	
		
			
				|  |  |    enum ByteOrderType { ByteOrderMSB, ByteOrderLSB };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Construct and take ownership of the file stream object.
 | 
	
	
		
			
				|  | @@ -95,9 +96,31 @@ public:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Forward to the per-class implementation.
 | 
	
		
			
				|  |  |    virtual unsigned int GetNumberOfSections() const = 0;
 | 
	
		
			
				|  |  | -  virtual bool GetSOName(std::string& soname) = 0;
 | 
	
		
			
				|  |  | +  virtual StringEntry const* GetDynamicSectionString(int tag) = 0;
 | 
	
		
			
				|  |  |    virtual void PrintInfo(std::ostream& os) const = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  // Lookup the SONAME in the DYNAMIC section.
 | 
	
		
			
				|  |  | +  StringEntry const* GetSOName()
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    return this->GetDynamicSectionString(DT_SONAME);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Lookup the RPATH in the DYNAMIC section.
 | 
	
		
			
				|  |  | +  StringEntry const* GetRPath()
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    return this->GetDynamicSectionString(DT_RPATH);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Lookup the RUNPATH in the DYNAMIC section.
 | 
	
		
			
				|  |  | +  StringEntry const* GetRunPath()
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +#if defined(DT_RUNPATH)
 | 
	
		
			
				|  |  | +    return this->GetDynamicSectionString(DT_RUNPATH);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    // Return the recorded ELF type.
 | 
	
		
			
				|  |  |    cmELF::FileType GetFileType() const { return this->ELFType; }
 | 
	
		
			
				|  |  |  protected:
 | 
	
	
		
			
				|  | @@ -127,6 +150,9 @@ protected:
 | 
	
		
			
				|  |  |      this->External->ErrorMessage = msg;
 | 
	
		
			
				|  |  |      this->ELFType = cmELF::FileTypeInvalid;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Store string table entry states.
 | 
	
		
			
				|  |  | +  std::map<int, StringEntry> DynamicSectionStrings;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
	
		
			
				|  | @@ -173,8 +199,8 @@ public:
 | 
	
		
			
				|  |  |      return static_cast<unsigned int>(this->ELFHeader.e_shnum);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Lookup the SONAME in the DYNAMIC section.
 | 
	
		
			
				|  |  | -  virtual bool GetSOName(std::string& soname);
 | 
	
		
			
				|  |  | +  // Lookup a string from the dynamic section with the given tag.
 | 
	
		
			
				|  |  | +  virtual StringEntry const* GetDynamicSectionString(int tag);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Print information about the ELF file.
 | 
	
		
			
				|  |  |    virtual void PrintInfo(std::ostream& os) const
 | 
	
	
		
			
				|  | @@ -270,6 +296,33 @@ private:
 | 
	
		
			
				|  |  |        case DT_DEBUG:    cmELFByteSwap(dyn.d_un.d_ptr); break;
 | 
	
		
			
				|  |  |        case DT_TEXTREL:  /* dyn.d_un ignored */         break;
 | 
	
		
			
				|  |  |        case DT_JMPREL:   cmELFByteSwap(dyn.d_un.d_ptr); break;
 | 
	
		
			
				|  |  | +#ifdef T_BIND_NOW
 | 
	
		
			
				|  |  | +      case T_BIND_NOW:         /* dyn.d_un ignored */         break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef DT_INIT_ARRAY
 | 
	
		
			
				|  |  | +      case DT_INIT_ARRAY:      cmELFByteSwap(dyn.d_un.d_ptr); break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef DT_FINI_ARRAY
 | 
	
		
			
				|  |  | +      case DT_FINI_ARRAY:      cmELFByteSwap(dyn.d_un.d_ptr); break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef DT_INIT_ARRAYSZ
 | 
	
		
			
				|  |  | +      case DT_INIT_ARRAYSZ:    cmELFByteSwap(dyn.d_un.d_val); break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef DT_FINI_ARRAYSZ
 | 
	
		
			
				|  |  | +      case DT_FINI_ARRAYSZ:    cmELFByteSwap(dyn.d_un.d_val); break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef DT_RUNPATH
 | 
	
		
			
				|  |  | +      case DT_RUNPATH:         cmELFByteSwap(dyn.d_un.d_val); break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef DT_FLAGS
 | 
	
		
			
				|  |  | +      case DT_FLAGS:           cmELFByteSwap(dyn.d_un.d_val); break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef DT_PREINIT_ARRAY
 | 
	
		
			
				|  |  | +      case DT_PREINIT_ARRAY:   cmELFByteSwap(dyn.d_un.d_ptr); break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef DT_PREINIT_ARRAYSZ
 | 
	
		
			
				|  |  | +      case DT_PREINIT_ARRAYSZ: cmELFByteSwap(dyn.d_un.d_val); break;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -329,10 +382,6 @@ private:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Store all entries of the DYNAMIC section.
 | 
	
		
			
				|  |  |    std::vector<ELF_Dyn> DynamicSectionEntries;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  // Store the SOName if it has been loaded.
 | 
	
		
			
				|  |  | -  std::string SOName;
 | 
	
		
			
				|  |  | -  bool SONameChecked;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
	
		
			
				|  | @@ -343,9 +392,6 @@ cmELFInternalImpl<Types>
 | 
	
		
			
				|  |  |                      ByteOrderType order):
 | 
	
		
			
				|  |  |    cmELFInternal(external, fin, order)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  // Initialize state.
 | 
	
		
			
				|  |  | -  this->SONameChecked = false;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    // Read the main header.
 | 
	
		
			
				|  |  |    if(!this->Read(this->ELFHeader))
 | 
	
		
			
				|  |  |      {
 | 
	
	
		
			
				|  | @@ -424,20 +470,29 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  |  template <class Types>
 | 
	
		
			
				|  |  | -bool cmELFInternalImpl<Types>::GetSOName(std::string& soname)
 | 
	
		
			
				|  |  | +cmELF::StringEntry const*
 | 
	
		
			
				|  |  | +cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    // Short-circuit if already checked.
 | 
	
		
			
				|  |  | -  if(this->SONameChecked)
 | 
	
		
			
				|  |  | +  std::map<int, StringEntry>::iterator dssi =
 | 
	
		
			
				|  |  | +    this->DynamicSectionStrings.find(tag);
 | 
	
		
			
				|  |  | +  if(dssi != this->DynamicSectionStrings.end())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    soname = this->SOName;
 | 
	
		
			
				|  |  | -    return !soname.empty();
 | 
	
		
			
				|  |  | +    if(dssi->second.Position > 0)
 | 
	
		
			
				|  |  | +      {
 | 
	
		
			
				|  |  | +      return &dssi->second;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -  this->SONameChecked = true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Create an entry for this tag.  Assume it is missing until found.
 | 
	
		
			
				|  |  | +  StringEntry& se = this->DynamicSectionStrings[tag];
 | 
	
		
			
				|  |  | +  se.Position = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Try reading the dynamic section.
 | 
	
		
			
				|  |  |    if(!this->LoadDynamicSection())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    return false;
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Get the string table referenced by the DYNAMIC section.
 | 
	
	
		
			
				|  | @@ -445,35 +500,43 @@ bool cmELFInternalImpl<Types>::GetSOName(std::string& soname)
 | 
	
		
			
				|  |  |    if(sec.sh_link >= this->SectionHeaders.size())
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |      this->SetErrorMessage("Section DYNAMIC has invalid string table index.");
 | 
	
		
			
				|  |  | -    return false;
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    ELF_Shdr const& strtab = this->SectionHeaders[sec.sh_link];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Look for the soname entry.
 | 
	
		
			
				|  |  | +  // Look for the requested entry.
 | 
	
		
			
				|  |  |    for(typename std::vector<ELF_Dyn>::iterator
 | 
	
		
			
				|  |  |          di = this->DynamicSectionEntries.begin();
 | 
	
		
			
				|  |  |        di != this->DynamicSectionEntries.end(); ++di)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |      ELF_Dyn& dyn = *di;
 | 
	
		
			
				|  |  | -    if(dyn.d_tag == DT_SONAME)
 | 
	
		
			
				|  |  | +    if(dyn.d_tag == tag)
 | 
	
		
			
				|  |  |        {
 | 
	
		
			
				|  |  | +      // Seek to the position reported by the entry.
 | 
	
		
			
				|  |  |        this->Stream.seekg(strtab.sh_offset + dyn.d_un.d_val);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // Read the string.
 | 
	
		
			
				|  |  |        char c;
 | 
	
		
			
				|  |  |        while(this->Stream.get(c) && c != 0)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -        this->SOName += c;
 | 
	
		
			
				|  |  | +        se.Value += c;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // Make sure the whole value was read.
 | 
	
		
			
				|  |  |        if(!this->Stream)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -        this->SetErrorMessage("Dynamic section specifies unreadable SONAME.");
 | 
	
		
			
				|  |  | -        this->SOName = "";
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | +        this->SetErrorMessage("Dynamic section specifies unreadable RPATH.");
 | 
	
		
			
				|  |  | +        se.Value = "";
 | 
	
		
			
				|  |  | +        return 0;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -      soname = this->SOName;
 | 
	
		
			
				|  |  | -      return true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // The value has been read successfully.  Report it.
 | 
	
		
			
				|  |  | +      se.Position =
 | 
	
		
			
				|  |  | +        static_cast<unsigned long>(strtab.sh_offset + dyn.d_un.d_val);
 | 
	
		
			
				|  |  | +      return &se;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -  return false;
 | 
	
		
			
				|  |  | +  return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //============================================================================
 | 
	
	
		
			
				|  | @@ -592,15 +655,59 @@ unsigned int cmELF::GetNumberOfSections() const
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  //----------------------------------------------------------------------------
 | 
	
		
			
				|  |  |  bool cmELF::GetSOName(std::string& soname)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  if(StringEntry const* se = this->GetSOName())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    soname = se->Value;
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  else
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    return false;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +cmELF::StringEntry const* cmELF::GetSOName()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    if(this->Valid() &&
 | 
	
		
			
				|  |  |       this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    return this->Internal->GetSOName(soname);
 | 
	
		
			
				|  |  | +    return this->Internal->GetSOName();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    else
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -    return false;
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +cmELF::StringEntry const* cmELF::GetRPath()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  if(this->Valid() &&
 | 
	
		
			
				|  |  | +     this->Internal->GetFileType() == cmELF::FileTypeExecutable ||
 | 
	
		
			
				|  |  | +     this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    return this->Internal->GetRPath();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  else
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//----------------------------------------------------------------------------
 | 
	
		
			
				|  |  | +cmELF::StringEntry const* cmELF::GetRunPath()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  if(this->Valid() &&
 | 
	
		
			
				|  |  | +     this->Internal->GetFileType() == cmELF::FileTypeExecutable ||
 | 
	
		
			
				|  |  | +     this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    return this->Internal->GetRunPath();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  else
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |