diff --git a/debian/changelog b/debian/changelog index 9dd303233..91b438e12 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ cmake (3.8.0-1) UNRELEASED; urgency=medium * New upstream release. * Refresh fix-ftbfs-on-kfreebsd.patch + * Drop mips-rld-map-rel.patch, merged upstream. -- Felix Geyer Fri, 14 Apr 2017 19:02:17 +0200 diff --git a/debian/patches/mips-rld-map-rel.patch b/debian/patches/mips-rld-map-rel.patch deleted file mode 100644 index 6484399c4..000000000 --- a/debian/patches/mips-rld-map-rel.patch +++ /dev/null @@ -1,475 +0,0 @@ -From c51099bb1018191964e5ee05e17f133233160806 Mon Sep 17 00:00:00 2001 -From: James Cowgill -Date: Thu, 13 Oct 2016 11:00:00 +0100 -Subject: [PATCH] MIPS: Handle DT_MIPS_RLD_MAP_REL tag when removing RPath from - ELFs - -This is a combination of 5 commits. - -elf: remove tag switch from ELF_Dyn ByteSwap function -elf: add DynamicEntryList methods and rpath tag constants -cmSystemTools: rewrite RemoveRPath using DyanmicEntryList methods -cmSystemTools, elf: handle DT_MIPS_RLD_REL_MAP in RemoveRPath -elf: Remove GetDynamicEntryCount and ReadBytes methods - -diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx -index 2d86674..0655da9 100644 ---- a/Source/cmELF.cxx -+++ b/Source/cmELF.cxx -@@ -132,18 +132,13 @@ public: - - // Forward to the per-class implementation. - virtual unsigned int GetNumberOfSections() const = 0; -- virtual unsigned int GetDynamicEntryCount() = 0; - virtual unsigned long GetDynamicEntryPosition(int j) = 0; -+ virtual cmELF::DynamicEntryList GetDynamicEntries() = 0; -+ virtual std::vector EncodeDynamicEntries( -+ const cmELF::DynamicEntryList&) = 0; - virtual StringEntry const* GetDynamicSectionString(unsigned int tag) = 0; - virtual void PrintInfo(std::ostream& os) const = 0; - -- bool ReadBytes(unsigned long pos, unsigned long size, char* buf) -- { -- this->Stream.seekg(pos); -- this->Stream.read(buf, size); -- return !this->Stream.fail(); -- } -- - // Lookup the SONAME in the DYNAMIC section. - StringEntry const* GetSOName() - { -@@ -246,10 +241,13 @@ public: - return static_cast(this->ELFHeader.e_shnum); - } - -- // Get the file position and size of a dynamic section entry. -- unsigned int GetDynamicEntryCount() CM_OVERRIDE; -+ // Get the file position of a dynamic section entry. - unsigned long GetDynamicEntryPosition(int j) CM_OVERRIDE; - -+ cmELF::DynamicEntryList GetDynamicEntries() CM_OVERRIDE; -+ std::vector EncodeDynamicEntries(const cmELF::DynamicEntryList&) -+ CM_OVERRIDE; -+ - // Lookup a string from the dynamic section with the given tag. - StringEntry const* GetDynamicSectionString(unsigned int tag) CM_OVERRIDE; - -@@ -289,6 +287,10 @@ public: - } - - private: -+ // ByteSwap(ELF_Dyn) assumes d_val and d_ptr are the same size -+ typedef char dyn_size_assert -+ [sizeof(ELF_Dyn().d_un.d_val) == sizeof(ELF_Dyn().d_un.d_ptr) ? 1 : -1]; -+ - void ByteSwap(ELF_Ehdr& elf_header) - { - cmELFByteSwap(elf_header.e_type); -@@ -323,121 +325,7 @@ private: - void ByteSwap(ELF_Dyn& dyn) - { - cmELFByteSwap(dyn.d_tag); -- switch (dyn.d_tag) { -- case DT_NULL: /* dyn.d_un ignored */ -- break; -- case DT_NEEDED: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_PLTRELSZ: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_PLTGOT: -- cmELFByteSwap(dyn.d_un.d_ptr); -- break; -- case DT_HASH: -- cmELFByteSwap(dyn.d_un.d_ptr); -- break; -- case DT_STRTAB: -- cmELFByteSwap(dyn.d_un.d_ptr); -- break; -- case DT_SYMTAB: -- cmELFByteSwap(dyn.d_un.d_ptr); -- break; -- case DT_RELA: -- cmELFByteSwap(dyn.d_un.d_ptr); -- break; -- case DT_RELASZ: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_RELAENT: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_STRSZ: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_SYMENT: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_INIT: -- cmELFByteSwap(dyn.d_un.d_ptr); -- break; -- case DT_FINI: -- cmELFByteSwap(dyn.d_un.d_ptr); -- break; -- case DT_SONAME: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_RPATH: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_SYMBOLIC: /* dyn.d_un ignored */ -- break; -- case DT_REL: -- cmELFByteSwap(dyn.d_un.d_ptr); -- break; -- case DT_RELSZ: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_RELENT: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- case DT_PLTREL: -- cmELFByteSwap(dyn.d_un.d_val); -- break; -- 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 -- } -+ cmELFByteSwap(dyn.d_un.d_val); - } - - bool FileTypeValid(ELF_Half et) -@@ -636,30 +524,64 @@ bool cmELFInternalImpl::LoadDynamicSection() - } - - template --unsigned int cmELFInternalImpl::GetDynamicEntryCount() -+unsigned long cmELFInternalImpl::GetDynamicEntryPosition(int j) - { - if (!this->LoadDynamicSection()) { - return 0; - } -- for (unsigned int i = 0; i < this->DynamicSectionEntries.size(); ++i) { -- if (this->DynamicSectionEntries[i].d_tag == DT_NULL) { -- return i; -- } -+ if (j < 0 || j >= static_cast(this->DynamicSectionEntries.size())) { -+ return 0; - } -- return static_cast(this->DynamicSectionEntries.size()); -+ ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; -+ return static_cast(sec.sh_offset + sec.sh_entsize * j); - } - - template --unsigned long cmELFInternalImpl::GetDynamicEntryPosition(int j) -+cmELF::DynamicEntryList cmELFInternalImpl::GetDynamicEntries() - { -+ cmELF::DynamicEntryList result; -+ -+ // Ensure entries have been read from file - if (!this->LoadDynamicSection()) { -- return 0; -+ return result; - } -- if (j < 0 || j >= static_cast(this->DynamicSectionEntries.size())) { -- return 0; -+ -+ // Copy into public array -+ result.reserve(this->DynamicSectionEntries.size()); -+ for (typename std::vector::iterator di = -+ this->DynamicSectionEntries.begin(); -+ di != this->DynamicSectionEntries.end(); ++di) { -+ ELF_Dyn& dyn = *di; -+ result.push_back( -+ std::pair(dyn.d_tag, dyn.d_un.d_val)); - } -- ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex]; -- return static_cast(sec.sh_offset + sec.sh_entsize * j); -+ -+ return result; -+} -+ -+template -+std::vector cmELFInternalImpl::EncodeDynamicEntries( -+ const cmELF::DynamicEntryList& entries) -+{ -+ std::vector result; -+ result.reserve(sizeof(ELF_Dyn) * entries.size()); -+ -+ for (cmELF::DynamicEntryList::const_iterator it = entries.begin(); -+ it != entries.end(); it++) { -+ // Store the entry in an ELF_Dyn, byteswap it, then serialize to chars -+ ELF_Dyn dyn; -+ dyn.d_tag = static_cast(it->first); -+ dyn.d_un.d_val = static_cast(it->second); -+ -+ if (this->NeedSwap) { -+ ByteSwap(dyn); -+ } -+ -+ char* pdyn = reinterpret_cast(&dyn); -+ result.insert(result.end(), pdyn, pdyn + sizeof(ELF_Dyn)); -+ } -+ -+ return result; - } - - template -@@ -752,6 +674,15 @@ cmELF::StringEntry const* cmELFInternalImpl::GetDynamicSectionString( - //============================================================================ - // External class implementation. - -+const long cmELF::TagRPath = DT_RPATH; -+const long cmELF::TagRunPath = DT_RUNPATH; -+ -+#ifdef DT_MIPS_RLD_MAP_REL -+const long cmELF::TagMipsRldMapRel = DT_MIPS_RLD_MAP_REL; -+#else -+const long cmELF::TagMipsRldMapRel = 0; -+#endif -+ - cmELF::cmELF(const char* fname) - : Internal(CM_NULLPTR) - { -@@ -839,28 +770,31 @@ unsigned int cmELF::GetNumberOfSections() const - return 0; - } - --unsigned int cmELF::GetDynamicEntryCount() const -+unsigned long cmELF::GetDynamicEntryPosition(int index) const - { - if (this->Valid()) { -- return this->Internal->GetDynamicEntryCount(); -+ return this->Internal->GetDynamicEntryPosition(index); - } - return 0; - } - --unsigned long cmELF::GetDynamicEntryPosition(int index) const -+cmELF::DynamicEntryList cmELF::GetDynamicEntries() const - { - if (this->Valid()) { -- return this->Internal->GetDynamicEntryPosition(index); -+ return this->Internal->GetDynamicEntries(); - } -- return 0; -+ -+ return cmELF::DynamicEntryList(); - } - --bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const -+std::vector cmELF::EncodeDynamicEntries( -+ const cmELF::DynamicEntryList& dentries) const - { - if (this->Valid()) { -- return this->Internal->ReadBytes(pos, size, buf); -+ return this->Internal->EncodeDynamicEntries(dentries); - } -- return false; -+ -+ return std::vector(); - } - - bool cmELF::GetSOName(std::string& soname) -diff --git a/Source/cmELF.h b/Source/cmELF.h -index 7e7c1d6..763a240 100644 ---- a/Source/cmELF.h -+++ b/Source/cmELF.h -@@ -7,6 +7,8 @@ - - #include - #include -+#include -+#include - - #if !defined(CMAKE_USE_ELF_PARSER) - #error "This file may be included only if CMAKE_USE_ELF_PARSER is enabled." -@@ -61,22 +63,27 @@ public: - int IndexInSection; - }; - -+ /** Represent entire dynamic section header */ -+ typedef std::vector > DynamicEntryList; -+ - /** Get the type of the file opened. */ - FileType GetFileType() const; - - /** Get the number of ELF sections present. */ - unsigned int GetNumberOfSections() const; - -- /** Get the number of DYNAMIC section entries before the first -- DT_NULL. Returns zero on error. */ -- unsigned int GetDynamicEntryCount() const; -- - /** Get the position of a DYNAMIC section header entry. Returns - zero on error. */ - unsigned long GetDynamicEntryPosition(int index) const; - -- /** Read bytes from the file. */ -- bool ReadBytes(unsigned long pos, unsigned long size, char* buf) const; -+ /** Get a copy of all the DYNAMIC section header entries. -+ Returns an empty vector on error */ -+ DynamicEntryList GetDynamicEntries() const; -+ -+ /** Encodes a DYNAMIC section header entry list into a char vector according -+ to the type of ELF file this is */ -+ std::vector EncodeDynamicEntries( -+ const DynamicEntryList& entries) const; - - /** Get the SONAME field if any. */ - bool GetSOName(std::string& soname); -@@ -91,6 +98,10 @@ public: - /** Print human-readable information about the ELF file. */ - void PrintInfo(std::ostream& os) const; - -+ /** Interesting dynamic tags. -+ If the tag is 0, it does not exist in the host ELF implementation */ -+ static const long TagRPath, TagRunPath, TagMipsRldMapRel; -+ - private: - friend class cmELFInternal; - bool Valid() const; -diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx -index 3d8fdf5..d800ef8 100644 ---- a/Source/cmSystemTools.cxx -+++ b/Source/cmSystemTools.cxx -@@ -2518,9 +2518,9 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, - std::swap(se[0], se[1]); - } - -- // Get the size of the dynamic section header. -- unsigned int count = elf.GetDynamicEntryCount(); -- if (count == 0) { -+ // Obtain a copy of the dynamic entries -+ cmELF::DynamicEntryList dentries = elf.GetDynamicEntries(); -+ if (dentries.empty()) { - // This should happen only for invalid ELF files where a DT_NULL - // appears before the end of the table. - if (emsg) { -@@ -2536,40 +2536,46 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, - zeroSize[i] = se[i]->Size; - } - -- // Get the range of file positions corresponding to each entry and -- // the rest of the table after them. -- unsigned long entryBegin[3] = { 0, 0, 0 }; -- unsigned long entryEnd[2] = { 0, 0 }; -- for (int i = 0; i < se_count; ++i) { -- entryBegin[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection); -- entryEnd[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection + 1); -- } -- entryBegin[se_count] = elf.GetDynamicEntryPosition(count); -- -- // The data are to be written over the old table entries starting at -- // the first one being removed. -- bytesBegin = entryBegin[0]; -- unsigned long bytesEnd = entryBegin[se_count]; -+ // Get size of one DYNAMIC entry -+ unsigned long const sizeof_dentry = -+ elf.GetDynamicEntryPosition(1) - elf.GetDynamicEntryPosition(0); - -- // Allocate a buffer to hold the part of the file to be written. -- // Initialize it with zeros. -- bytes.resize(bytesEnd - bytesBegin, 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. -- char* data = &bytes[0]; -- for (int i = 0; i < se_count; ++i) { -- // Read data between the entries being removed. -- unsigned long sz = entryBegin[i + 1] - entryEnd[i]; -- if (sz > 0 && !elf.ReadBytes(entryEnd[i], sz, data)) { -- if (emsg) { -- *emsg = "Failed to read DYNAMIC section header."; -+ // Adjust the entry list as necessary to remove the run path -+ unsigned long entriesErased = 0; -+ for (cmELF::DynamicEntryList::iterator it = dentries.begin(); -+ it != dentries.end();) { -+ if (it->first == cmELF::TagRPath || it->first == cmELF::TagRunPath) { -+ it = dentries.erase(it); -+ entriesErased++; -+ continue; -+ } else { -+ if (cmELF::TagMipsRldMapRel != 0 && -+ it->first == cmELF::TagMipsRldMapRel) { -+ // Background: debuggers need to know the "linker map" which contains -+ // the addresses each dynamic object is loaded at. Most arches use -+ // the DT_DEBUG tag which the dynamic linker writes to (directly) and -+ // contain the location of the linker map, however on MIPS the -+ // .dynamic section is always read-only so this is not possible. MIPS -+ // objects instead contain a DT_MIPS_RLD_MAP tag which contains the -+ // address where the dyanmic linker will write to (an indirect -+ // version of DT_DEBUG). Since this doesn't work when using PIE, a -+ // relative equivalent was created - DT_MIPS_RLD_MAP_REL. Since this -+ // version contains a relative offset, moving it changes the -+ // calculated address. This may cause the dyanmic linker to write -+ // into memory it should not be changing. -+ // -+ // To fix this, we adjust the value of DT_MIPS_RLD_MAP_REL here. If -+ // we move it up by n bytes, we add n bytes to the value of this tag. -+ it->second += entriesErased * sizeof_dentry; - } -- return false; -+ -+ it++; - } -- data += sz; - } -+ -+ // Encode new entries list -+ bytes = elf.EncodeDynamicEntries(dentries); -+ bytesBegin = elf.GetDynamicEntryPosition(0); - } - - // Open the file for update. diff --git a/debian/patches/series b/debian/patches/series index 400dc0d2f..e9e2070cc 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,4 +1,3 @@ FindBoost_add_-lpthread_#563479.diff qt_import_dir_variable.diff fix-ftbfs-on-kfreebsd.patch -mips-rld-map-rel.patch