Commit Diff


commit - 1f373332ee43b7a9c5af2a4a97a736ab63073c96
commit + 047062a2f005cb2382e7ab336c79e084f4dc6567
blob - 553f50f8707eccbfe3c691978635429358441118
blob + 04e7a99f6764824e1494ae9bc5c2eefef0084bff
--- tools/img_eGON.BT0/img_eGON.BT0.cc
+++ tools/img_eGON.BT0/img_eGON.BT0.cc
@@ -6,10 +6,14 @@
 #include <iostream>
 #include <iomanip>
 #include <memory>
+#include <array>
+#include <algorithm>
 
 namespace
 {
 
+
+
  /** Non-copiable objects */
 struct NonCopiable
 {
@@ -33,6 +37,12 @@ class UniqueFd : public NonCopiable (private)
 };
 
 
+char printable(char ch)
+{
+    return std::isprint(ch) ? ch : '.';
+}
+
+
 struct CommandLineArguments
 {
     const char *m_image_file_path{nullptr};
@@ -80,18 +90,25 @@ parse_command_line(
 }
 
 
-char printable(char ch)
+namespace header
 {
-    return ch ? (std::isprint(ch) ? ch : '?') : ' ';
-}
 
 
+constexpr auto MAGIC_LENGTH{8};
+const std::array<uint8_t, MAGIC_LENGTH> MAGIC{'e', 'G', 'O', 'N', '.', 'B', 'T', '0'};
+
+constexpr auto SPL_SIGNATURE_LENGTH{3};
+const std::array<uint8_t, SPL_SIGNATURE_LENGTH> SPL_SIGNATURE{'S', 'P', 'L'};
+
+constexpr uint8_t SPL_VERSION_0_2 = 0x02;
+
 struct Header {
     uint32_t m_jump_instruction;
-    uint8_t m_magic[8];
+    uint8_t m_magic[MAGIC_LENGTH];
     uint32_t m_checksum;
     uint32_t m_length;
-    uint8_t m_spl_signature[4];
+    uint8_t m_spl_signature[SPL_SIGNATURE_LENGTH];
+    uint8_t m_spl_version;
     uint32_t m_zero18;
     uint32_t m_zero1C;
     uint32_t m_name_offset;
@@ -100,37 +117,51 @@ struct Header {
     uint8_t m_strings[52];
 };
 
+constexpr uint32_t JUMP_INSTRUCTION{0xea000000 | ((sizeof(Header) / 4) - 2)};
 
-bool run(int argc, char *argv[])
-{
-    CommandLineArguments args;
-    if (!parse_command_line(argc, argv, args))
-    {
-        usage(argv[0]);
-        return false;
-    }
 
-    const UniqueFd image_file{open(args.m_image_file_path, O_RDONLY)};
+bool validate_and_dump(const char *image_file_path)
+{
+    const UniqueFd image_file{open(image_file_path, O_RDONLY)};
     if (!image_file)
     {
         const auto error{errno};
-        std::cerr << "Open file \"" << args.m_image_file_path << "\" failed. "
+        std::cerr << "Open file \"" << image_file_path << "\" failed. "
                   << "Error code (" << std::dec << error << "): " << strerror(error) << std::endl;
         return false;
     }
 
     Header header{};
-    if (read(image_file.get(), &header, sizeof(header)) == -1)
+    const auto readed{read(image_file.get(), &header, sizeof(header))};
+    if (readed != sizeof(header))
     {
         const auto error{errno};
-        std::cerr << "Read file \"" << args.m_image_file_path << "\" failed. "
-                  << "Error code (" << std::dec << error << "): " << strerror(error) << std::endl;
+        std::cerr << "Read file \"" << image_file_path << "\" failed. ";
+        if (readed == -1)
+            std::cerr << "Error code (" << std::dec << error << "): " 
+                      << strerror(error) << std::endl;
+        else
+            std::cerr << "Probably the file is too small";
         return false;
     }
 
+    bool ret_value = true;
+
+    std::cout << std::endl << "# Header (size=0x" << std::hex << sizeof(header) 
+              << "," << std::dec << sizeof(header) << ")" << std::endl << std::endl;
+
     std::cout << "+0x00 Jump instruction : 0x"
               << std::hex << std::setw(8) << std::setfill('0') 
               << header.m_jump_instruction << std::endl;
+    if (header.m_jump_instruction == JUMP_INSTRUCTION)
+    {
+        std::cout << "                         (v) OK" << std::endl;
+    }
+    else
+    {
+        std::cout << "                         (x) Unexpected" << std::endl;
+        ret_value = false;
+    }
 
     std::cout << "+0x04 Magic            :";
     for (const auto ch : header.m_magic)
@@ -142,6 +173,16 @@ bool run(int argc, char *argv[])
         std::cout << printable(ch);
     std::cout << std::endl;
 
+    if (std::equal(MAGIC.cbegin(), MAGIC.cend(), &header.m_magic[0]))
+    {
+        std::cout << "                         (v) OK" << std::endl;
+    }
+    else
+    {
+        std::cout << "                         (x) Unexpected" << std::endl;
+        ret_value = false;
+    }
+
     std::cout << "+0x0C Checksum         : 0x" 
               << std::hex << std::setw(8) << std::setfill('0') 
               << header.m_checksum << std::endl;
@@ -149,7 +190,17 @@ bool run(int argc, char *argv[])
     std::cout << "+0x10 Length           : 0x" 
               << std::hex << std::setw(8) << std::setfill('0') << header.m_length
               << ", " << std::dec << header.m_length << std::endl;
+    if ((header.m_length & 511) == 0)
+    {
+        std::cout << "                         (v) OK" << std::endl;
+    }
+    else
+    {
+        std::cout << "                         (x) Unexpected" << std::endl;
+        ret_value = false;
+    }
 
+
     std::cout << "+0x14 SPL signature    :";
     for (const auto ch : header.m_spl_signature)
         std::cout << " 0x" << std::hex << std::setw(2) << std::setfill('0')
@@ -160,6 +211,30 @@ bool run(int argc, char *argv[])
         std::cout << printable(ch);
     std::cout << std::endl;
 
+    if (std::equal(SPL_SIGNATURE.cbegin(), SPL_SIGNATURE.cend(), &header.m_spl_signature[0]))
+    {
+        std::cout << "                         (v) OK" << std::endl;
+    }
+    else
+    {
+        std::cout << "                         (x) Unexpected" << std::endl;
+        ret_value = false;
+    }
+
+    std::cout << "+0x17 SPL version      : 0x" 
+              << std::hex << std::setw(2) << std::setfill('0') << uint32_t(header.m_spl_version)
+              << ", " << std::dec << uint32_t(header.m_spl_version) << std::endl;
+
+    if (header.m_spl_version == SPL_VERSION_0_2)
+    {
+        std::cout << "                         (v) OK, v0.2" << std::endl;
+    }
+    else
+    {
+        std::cout << "                         (x) Unexpected" << std::endl;
+        ret_value = false;
+    }
+
     std::cout << "+0x18                  : 0x" 
               << std::hex << std::setw(8) << std::setfill('0') 
               << header.m_zero18 << std::endl;
@@ -197,13 +272,22 @@ bool run(int argc, char *argv[])
         std::cout << printable(ch);
     std::cout << std::endl;
 
-    return true;
+    return ret_value;
 }
 
 
+}   // namespace header
+
+
+bool run(const CommandLineArguments &args)
+{
+    return header::validate_and_dump(args.m_image_file_path);
 }
 
 
+}
+
+
 extern "C"
 int
 main(
@@ -211,5 +295,11 @@ main(
     /* in */ char *argv[]
 )
 {
-    return run(argc, argv) ? 0 : 1;
+    CommandLineArguments args;
+    if (!parse_command_line(argc, argv, args))
+    {
+        usage(argv[0]);
+        return 1;
+    }
+    return run(args) ? 0 : 1;
 }