[Cmake-commits] [cmake-commits] king committed cmSystemTools.cxx 1.376 1.377 cmSystemTools.h 1.151 1.152
cmake-commits at cmake.org
cmake-commits at cmake.org
Mon Apr 14 15:02:37 EDT 2008
Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv28073/Source
Modified Files:
cmSystemTools.cxx cmSystemTools.h
Log Message:
ENH: Added RPATH methods to cmSystemTools
- RemoveRPath to remove the RPATH from a binary
- CheckRPath to check for an existing RPATH in a binary
Index: cmSystemTools.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.h,v
retrieving revision 1.151
retrieving revision 1.152
diff -C 2 -d -r1.151 -r1.152
*** cmSystemTools.h 14 Apr 2008 15:43:45 -0000 1.151
--- cmSystemTools.h 14 Apr 2008 19:02:34 -0000 1.152
***************
*** 394,397 ****
--- 394,405 ----
std::string* emsg = 0);
+ /** Try to remove the RPATH from an ELF binary. */
+ static bool RemoveRPath(std::string const& file, std::string* emsg = 0);
+
+ /** Check whether the RPATH in an ELF binary contains the path
+ given. */
+ static bool CheckRPath(std::string const& file,
+ std::string const& newRPath);
+
private:
static bool s_ForceUnixPaths;
Index: cmSystemTools.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.cxx,v
retrieving revision 1.376
retrieving revision 1.377
diff -C 2 -d -r1.376 -r1.377
*** cmSystemTools.cxx 14 Apr 2008 16:44:01 -0000 1.376
--- cmSystemTools.cxx 14 Apr 2008 19:02:33 -0000 1.377
***************
*** 2464,2465 ****
--- 2464,2635 ----
#endif
}
+
+ //----------------------------------------------------------------------------
+ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
+ {
+ #if defined(CMAKE_USE_ELF_PARSER)
+ unsigned long rpathPosition = 0;
+ unsigned long rpathSize = 0;
+ unsigned long rpathEntryPosition = 0;
+ std::vector<char> bytes;
+ {
+ // Parse the ELF binary.
+ cmELF elf(file.c_str());
+
+ // Get the RPATH or RUNPATH entry from it.
+ cmELF::StringEntry const* se = elf.GetRPath();
+ if(!se)
+ {
+ se = elf.GetRunPath();
+ }
+
+ if(se)
+ {
+ // Store information about the entry.
+ rpathPosition = se->Position;
+ rpathSize = se->Size;
+ rpathEntryPosition = elf.GetDynamicEntryPosition(se->IndexInSection);
+
+ // Get the file range containing the rest of the DYNAMIC table
+ // after the RPATH entry.
+ unsigned long nextEntryPosition =
+ elf.GetDynamicEntryPosition(se->IndexInSection+1);
+ unsigned int count = elf.GetDynamicEntryCount();
+ if(count == 0)
+ {
+ // This should happen only for invalid ELF files where a DT_NULL
+ // appears before the end of the table.
+ if(emsg)
+ {
+ *emsg = "DYNAMIC section contains a DT_NULL before the end.";
+ }
+ return false;
+ }
+ unsigned long nullEntryPosition = elf.GetDynamicEntryPosition(count);
+
+ // Allocate and fill a buffer with zeros.
+ bytes.resize(nullEntryPosition - rpathEntryPosition, 0);
+
+ // Read the part of the DYNAMIC section header that will move.
+ // The remainder of the buffer will be left with zeros which
+ // represent a DT_NULL entry.
+ if(!elf.ReadBytes(nextEntryPosition,
+ nullEntryPosition - nextEntryPosition,
+ &bytes[0]))
+ {
+ if(emsg)
+ {
+ *emsg = "Failed to read DYNAMIC section header.";
+ }
+ return false;
+ }
+ }
+ else
+ {
+ // There is no RPATH or RUNPATH anyway.
+ return true;
+ }
+ }
+
+ // Open the file for update.
+ std::ofstream f(file.c_str(),
+ std::ios::in | std::ios::out | std::ios::binary);
+ if(!f)
+ {
+ if(emsg)
+ {
+ *emsg = "Error opening file for update.";
+ }
+ return false;
+ }
+
+ // Write the new DYNAMIC table header.
+ if(!f.seekp(rpathEntryPosition))
+ {
+ if(emsg)
+ {
+ *emsg = "Error seeking to DYNAMIC table header for RPATH.";
+ }
+ return false;
+ }
+ if(!f.write(&bytes[0], bytes.size()))
+ {
+ if(emsg)
+ {
+ *emsg = "Error replacing DYNAMIC table header.";
+ }
+ return false;
+ }
+
+ // Fill the RPATH string with zero bytes.
+ if(!f.seekp(rpathPosition))
+ {
+ if(emsg)
+ {
+ *emsg = "Error seeking to RPATH position.";
+ }
+ return false;
+ }
+ for(unsigned long i=0; i < rpathSize; ++i)
+ {
+ f << '\0';
+ }
+
+ // Make sure everything was okay.
+ if(f)
+ {
+ return true;
+ }
+ else
+ {
+ if(emsg)
+ {
+ *emsg = "Error writing the empty rpath to the file.";
+ }
+ return false;
+ }
+ #else
+ (void)file;
+ (void)emsg;
+ return false;
+ #endif
+ }
+
+ //----------------------------------------------------------------------------
+ bool cmSystemTools::CheckRPath(std::string const& file,
+ std::string const& newRPath)
+ {
+ #if defined(CMAKE_USE_ELF_PARSER)
+ // Parse the ELF binary.
+ cmELF elf(file.c_str());
+
+ // Get the RPATH or RUNPATH entry from it.
+ cmELF::StringEntry const* se = elf.GetRPath();
+ if(!se)
+ {
+ se = elf.GetRunPath();
+ }
+
+ // Make sure the current rpath contains the new rpath.
+ if(newRPath.empty())
+ {
+ if(!se)
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if(se &&
+ cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
+ {
+ return true;
+ }
+ }
+ return false;
+ #else
+ (void)file;
+ (void)newRPath;
+ return false;
+ #endif
+ }
More information about the Cmake-commits
mailing list