summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-12-12 15:25:14 -0800
committerAndreas Gampe <agampe@google.com>2014-12-15 08:13:39 -0800
commit2bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5 (patch)
tree8c37d77a5d7784ddbbaf221c72c0e66792c5a872
parentd1512fed4e43bba77fb21fd1b6322c22ef7c5881 (diff)
downloadart-2bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5.zip
art-2bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5.tar.gz
art-2bcb3b228bc418bcc7fdc3d58d0a0da422a0b6d5.tar.bz2
ART: Show invalid oat header cause in error message
Include the IsValid failure cause in the error message of opening an oat file. Make oat magic and version constexpr so we can have static_asserts over the lengths. Bug: 17187621 Change-Id: I8cef1c6cc9cb2faa052167a3437e81b4c2cbefa7
-rw-r--r--runtime/oat.cc34
-rw-r--r--runtime/oat.h5
-rw-r--r--runtime/oat_file.cc4
3 files changed, 38 insertions, 5 deletions
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 9307598..c223e2e 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -20,12 +20,13 @@
#include <zlib.h>
#include "arch/instruction_set_features.h"
+#include "base/stringprintf.h"
#include "utils.h"
namespace art {
-const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '5', '2', '\0' };
+constexpr uint8_t OatHeader::kOatMagic[4];
+constexpr uint8_t OatHeader::kOatVersion[4];
static size_t ComputeOatHeaderSize(const SafeMap<std::string, std::string>* variable_data) {
size_t estimate = 0U;
@@ -67,6 +68,13 @@ OatHeader::OatHeader(InstructionSet instruction_set,
uint32_t image_file_location_oat_checksum,
uint32_t image_file_location_oat_data_begin,
const SafeMap<std::string, std::string>* variable_data) {
+ // Don't want asserts in header as they would be checked in each file that includes it. But the
+ // fields are private, so we check inside a method.
+ static_assert(sizeof(magic_) == sizeof(kOatMagic),
+ "Oat magic and magic_ have different lengths.");
+ static_assert(sizeof(version_) == sizeof(kOatVersion),
+ "Oat version and version_ have different lengths.");
+
memcpy(magic_, kOatMagic, sizeof(kOatMagic));
memcpy(version_, kOatVersion, sizeof(kOatVersion));
executable_offset_ = 0;
@@ -127,6 +135,28 @@ bool OatHeader::IsValid() const {
return true;
}
+std::string OatHeader::GetValidationErrorMessage() const {
+ if (memcmp(magic_, kOatMagic, sizeof(kOatMagic)) != 0) {
+ static_assert(sizeof(kOatMagic) == 4, "kOatMagic has unexpected length");
+ return StringPrintf("Invalid oat magic, expected 0x%x%x%x%x, got 0x%x%x%x%x.",
+ kOatMagic[0], kOatMagic[1], kOatMagic[2], kOatMagic[3],
+ magic_[0], magic_[1], magic_[2], magic_[3]);
+ }
+ if (memcmp(version_, kOatVersion, sizeof(kOatVersion)) != 0) {
+ static_assert(sizeof(kOatVersion) == 4, "kOatVersion has unexpected length");
+ return StringPrintf("Invalid oat version, expected 0x%x%x%x%x, got 0x%x%x%x%x.",
+ kOatVersion[0], kOatVersion[1], kOatVersion[2], kOatVersion[3],
+ version_[0], version_[1], version_[2], version_[3]);
+ }
+ if (!IsAligned<kPageSize>(executable_offset_)) {
+ return "Executable offset not page-aligned.";
+ }
+ if (!IsAligned<kPageSize>(image_patch_delta_)) {
+ return "Image patch delta not page-aligned.";
+ }
+ return "";
+}
+
const char* OatHeader::GetMagic() const {
CHECK(IsValid());
return reinterpret_cast<const char*>(magic_);
diff --git a/runtime/oat.h b/runtime/oat.h
index 6098fbd..f218482 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -31,8 +31,8 @@ class InstructionSetFeatures;
class PACKED(4) OatHeader {
public:
- static const uint8_t kOatMagic[4];
- static const uint8_t kOatVersion[4];
+ static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
+ static constexpr uint8_t kOatVersion[] = { '0', '4', '5', '\0' };
static constexpr const char* kImageLocationKey = "image-location";
static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
@@ -47,6 +47,7 @@ class PACKED(4) OatHeader {
const SafeMap<std::string, std::string>* variable_data);
bool IsValid() const;
+ std::string GetValidationErrorMessage() const;
const char* GetMagic() const;
uint32_t GetChecksum() const;
void UpdateChecksum(const void* data, size_t length);
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index aa85ff0..1c6cc8b 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -227,7 +227,9 @@ bool OatFile::ElfFileOpen(File* file, uint8_t* requested_base, uint8_t* oat_file
bool OatFile::Setup(std::string* error_msg) {
if (!GetOatHeader().IsValid()) {
- *error_msg = StringPrintf("Invalid oat magic for '%s'", GetLocation().c_str());
+ std::string cause = GetOatHeader().GetValidationErrorMessage();
+ *error_msg = StringPrintf("Invalid oat header for '%s': %s", GetLocation().c_str(),
+ cause.c_str());
return false;
}
const uint8_t* oat = Begin();