You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2016/07/02 22:22:24 UTC

[1/2] mesos git commit: Added get_abi_version() to stout's ELF abstraction.

Repository: mesos
Updated Branches:
  refs/heads/master 8912a7ba2 -> 5ed7389f4


Added get_abi_version() to stout's ELF abstraction.

This function returns the ABI version of the ELF file by parsing the
contents of its '.note.ABI-tag' section. This section is Linux
specific and adheres to the format described in the links below.

https://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf

https://reviews.apache.org/r/49564/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/20ca33f2
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/20ca33f2
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/20ca33f2

Branch: refs/heads/master
Commit: 20ca33f272506988834bbd9cdd980df17627084b
Parents: 8912a7b
Author: Kevin Klues <kl...@gmail.com>
Authored: Sat Jul 2 15:20:26 2016 -0700
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Jul 2 15:20:26 2016 -0700

----------------------------------------------------------------------
 3rdparty/stout/include/stout/elf.hpp | 82 +++++++++++++++++++++++++++++--
 1 file changed, 79 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/20ca33f2/3rdparty/stout/include/stout/elf.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/elf.hpp b/3rdparty/stout/include/stout/elf.hpp
index 67d8962..94b1de9 100644
--- a/3rdparty/stout/include/stout/elf.hpp
+++ b/3rdparty/stout/include/stout/elf.hpp
@@ -25,7 +25,13 @@
 
 #include <stout/error.hpp>
 #include <stout/foreach.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+#include <stout/stringify.hpp>
+#include <stout/strings.hpp>
 #include <stout/try.hpp>
+#include <stout/version.hpp>
 
 namespace elf {
 
@@ -39,6 +45,7 @@ enum Class
 enum class SectionType
 {
   DYNAMIC = SHT_DYNAMIC,
+  NOTE = SHT_NOTE,
 };
 
 enum class DynamicTag
@@ -74,7 +81,7 @@ public:
 
     // Create the mapping from section type to sections.
     foreach (ELFIO::section* section, file->elf.sections) {
-      SectionType section_type = (SectionType) section->get_type();
+      SectionType section_type = SectionType(section->get_type());
       file->sections_by_type[section_type].push_back(section);
     }
 
@@ -97,7 +104,7 @@ public:
   Try<std::vector<std::string>> get_dynamic_strings(DynamicTag tag) const
   {
     if (sections_by_type.count(SectionType::DYNAMIC) == 0) {
-      return Error("No DYNAMIC sections found in ELF");
+      return Error("No DYNAMIC sections found");
     }
 
     std::vector<std::string> strings;
@@ -112,7 +119,7 @@ public:
         std::string entry_string;
 
         if (!accessor.get_entry(i, entry_tag, entry_value, entry_string)) {
-          return Error("Failed to get entry from DYNAMIC section of elf");
+          return Error("Failed to get entry from DYNAMIC section");
         }
 
         if (tag == DynamicTag(entry_tag)) {
@@ -124,6 +131,75 @@ public:
     return strings;
   }
 
+  // Get the ABI version of the ELF file by parsing the contents of
+  // the `.note.ABI-tag` section. This section is Linux specific and
+  // adheres to the format described in the links below.
+  //
+  // NOTE: Not all ELF files have a `.note.ABI-tag` section (even on
+  // Linux), so we return a `Result` to allow the return value to be
+  // `None()`.
+  //
+  // https://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
+  // http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf
+  Result<Version> get_abi_version() const
+  {
+    ELFIO::section* section = elf.sections[".note.ABI-tag"];
+
+    if (section == nullptr) {
+      return None();
+    }
+
+    if (SectionType(section->get_type()) != SectionType::NOTE) {
+      return Error("Section '.note.ABI-tag' is not a NOTE");
+    }
+
+    auto accessor = ELFIO::note_section_accessor(elf, section);
+
+    if (accessor.get_notes_num() != 1) {
+      return Error("Section '.note.ABI-tag' does not have exactly one entry");
+    }
+
+    ELFIO::Elf_Word type;
+    std::string name;
+    void* descriptor;
+    ELFIO::Elf_Word descriptor_size;
+
+    if (!accessor.get_note(0, type, name, descriptor, descriptor_size)) {
+      return Error("Failed to get entry from '.note.ABI-tag' section");
+    }
+
+    // The note in a `.note.ABI-tag` section must have `type == 1`.
+    if (type != 1) {
+      return Error("Corrupt tag type '" + stringify(type) + "' from"
+                   " entry in '.note.ABI-tag' section");
+    }
+
+    // Linux mandates `name == GNU`.
+    // However, ELFIO seems to include '\0' in the string itself
+    // when constructing `name`, so instead we make sure that
+    // `name` starts with "GNU" instead.
+    if (!strings::startsWith(name, "GNU")) {
+      return Error("Corrupt label '" + name + "' from"
+                   " entry in '.note.ABI-tag' section");
+    }
+
+    // The version array consists of 4 32-bit numbers, with the
+    // first number fixed at 0 (meaning it is a Linux ELF file), and
+    // the rest specifying the ABI version. For example, if the array
+    // contains {0, 2, 3, 99}, this signifies a Linux ELF file
+    // with an ABI version of 2.3.99.
+    std::vector<uint32_t> version(
+        (uint32_t*)descriptor,
+        (uint32_t*)((char*)descriptor + descriptor_size));
+
+    if (version.size() != 4 && version[0] != 0) {
+      return Error("Corrupt version '" + stringify(version) + "'"
+                   " from entry in '.note.ABI-tag' section");
+    }
+
+    return Version(version[1], version[2], version[3]);
+  }
+
 private:
   explicit File() {}
 


[2/2] mesos git commit: Updated ldcache_tests.cpp to check ELF ABI version.

Posted by bm...@apache.org.
Updated ldcache_tests.cpp to check ELF ABI version.

Review: https://reviews.apache.org/r/49564/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5ed7389f
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5ed7389f
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5ed7389f

Branch: refs/heads/master
Commit: 5ed7389f4e67176d0aa6e8c14e3c175d4def96eb
Parents: 20ca33f
Author: Kevin Klues <kl...@gmail.com>
Authored: Sat Jul 2 15:21:22 2016 -0700
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Sat Jul 2 15:21:22 2016 -0700

----------------------------------------------------------------------
 src/tests/ldcache_tests.cpp | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/5ed7389f/src/tests/ldcache_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/ldcache_tests.cpp b/src/tests/ldcache_tests.cpp
index 8e24e94..89901c1 100644
--- a/src/tests/ldcache_tests.cpp
+++ b/src/tests/ldcache_tests.cpp
@@ -62,6 +62,11 @@ TEST(LdcacheTest, Parse)
       file->get_dynamic_strings(elf::DynamicTag::NEEDED);
     ASSERT_SOME(needed);
     ASSERT_LE(needed->size(), cache->size());
+
+    Result<Version> abiVersion = file->get_abi_version();
+    if (!abiVersion.isNone()) {
+      ASSERT_SOME(abiVersion);
+    }
   }
 }