oat.cc revision 81f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bc
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
17e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat.h"
18e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
19e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include <zlib.h>
20e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
21e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromnamespace art {
22e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
23e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromconst uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
24e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromconst uint8_t OatHeader::kOatVersion[] = { '0', '0', '1', '\0' };
25e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
26a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott HughesOatHeader::OatHeader() {
27a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes  memset(this, 0, sizeof(*this));
28a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes}
29a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes
3081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian CarlstromOatHeader::OatHeader(InstructionSet instruction_set,
3181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom                     const std::vector<const DexFile*>* dex_files,
3281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom                     uint32_t image_file_location_checksum,
3381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom                     const std::string& image_file_location) {
34e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  memcpy(magic_, kOatMagic, sizeof(kOatMagic));
35e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  memcpy(version_, kOatVersion, sizeof(kOatVersion));
3681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
37e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  adler32_checksum_ = adler32(0L, Z_NULL, 0);
3881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
39a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes  instruction_set_ = instruction_set;
40a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes  UpdateChecksum(&instruction_set_, sizeof(instruction_set_));
4181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
42e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  dex_file_count_ = dex_files->size();
43e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  UpdateChecksum(&dex_file_count_, sizeof(dex_file_count_));
4481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
4581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  image_file_location_checksum_ = image_file_location_checksum;
4681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  UpdateChecksum(&image_file_location_checksum_, sizeof(image_file_location_checksum_));
4781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
4881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  image_file_location_size_ = image_file_location.size();
4981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  UpdateChecksum(&image_file_location_size_, sizeof(image_file_location_size_));
5081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  UpdateChecksum(image_file_location.data(), image_file_location_size_);
5181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
52e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  executable_offset_ = 0;
53e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
54e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
55e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool OatHeader::IsValid() const {
56e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  if (memcmp(magic_, kOatMagic, sizeof(kOatMagic) != 0)) {
57e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    return false;
58e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
59e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  if (memcmp(version_, kOatVersion, sizeof(kOatVersion) != 0)) {
60e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    return false;
61e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
62e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  return true;
63e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
64e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
65e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromconst char* OatHeader::GetMagic() const {
66e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  CHECK(IsValid());
67e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  return reinterpret_cast<const char*>(magic_);
68e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
69e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
70e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetDexFileCount() const {
71e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  DCHECK(IsValid());
72e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  return dex_file_count_;
73e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
74e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
75e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetChecksum() const {
76e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  CHECK(IsValid());
77e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  return adler32_checksum_;
78e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
79e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
80e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatHeader::UpdateChecksum(const void* data, size_t length) {
81e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  DCHECK(IsValid());
82e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
83e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  adler32_checksum_ = adler32(adler32_checksum_, bytes, length);
84e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
85e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
86a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott HughesInstructionSet OatHeader::GetInstructionSet() const {
87a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes  CHECK(IsValid());
88a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes  return instruction_set_;
89a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes}
90a72ec820f8cb8e04b0ba87a62e36b05a2c92ef36Elliott Hughes
91e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromuint32_t OatHeader::GetExecutableOffset() const {
92e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  DCHECK(IsValid());
9306b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes  DCHECK_ALIGNED(executable_offset_, kPageSize);
94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  CHECK_GT(executable_offset_, sizeof(OatHeader));
95e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  return executable_offset_;
96e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
97e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
9881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstromuint32_t OatHeader::GetImageFileLocationChecksum() const {
9981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  CHECK(IsValid());
10081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  return image_file_location_checksum_;
10181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom}
10281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
10381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstromuint32_t OatHeader::GetImageFileLocationSize() const {
10481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  CHECK(IsValid());
10581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  return image_file_location_size_;
10681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom}
10781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
10881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstromconst uint8_t* OatHeader::GetImageFileLocationData() const {
10981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  CHECK(IsValid());
11081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  return image_file_location_data_;
11181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom}
11281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
11381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstromstd::string OatHeader::GetImageFileLocation() const {
11481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  CHECK(IsValid());
11581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom  return std::string(reinterpret_cast<const char*>(GetImageFileLocationData()),
11681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom                     GetImageFileLocationSize());
11781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom}
11881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
119e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid OatHeader::SetExecutableOffset(uint32_t executable_offset) {
12006b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes  DCHECK_ALIGNED(executable_offset, kPageSize);
121e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  CHECK_GT(executable_offset, sizeof(OatHeader));
122e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  DCHECK(IsValid());
123e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  DCHECK_EQ(executable_offset_, 0U);
12481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
125e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  executable_offset_ = executable_offset;
126e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  UpdateChecksum(&executable_offset_, sizeof(executable_offset));
127e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}
128e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
1293320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatMethodOffsets::OatMethodOffsets()
130362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes  : code_offset_(0),
131362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    frame_size_in_bytes_(0),
132362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    core_spill_mask_(0),
133362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    fp_spill_mask_(0),
134362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    mapping_table_offset_(0),
135362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    vmap_table_offset_(0),
136e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    gc_map_offset_(0),
137362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    invoke_stub_offset_(0) {}
1383320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1393320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
1403320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                   uint32_t frame_size_in_bytes,
1413320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                   uint32_t core_spill_mask,
1423320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                   uint32_t fp_spill_mask,
1433320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                   uint32_t mapping_table_offset,
1443320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                   uint32_t vmap_table_offset,
145e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom                                   uint32_t gc_map_offset,
1463320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom                                   uint32_t invoke_stub_offset)
147362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes  : code_offset_(code_offset),
148362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    frame_size_in_bytes_(frame_size_in_bytes),
149362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    core_spill_mask_(core_spill_mask),
150362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    fp_spill_mask_(fp_spill_mask),
151362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    mapping_table_offset_(mapping_table_offset),
152362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    vmap_table_offset_(vmap_table_offset),
153e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom    gc_map_offset_(gc_map_offset),
154362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes    invoke_stub_offset_(invoke_stub_offset) {}
1553320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
1563320cf46afd082398aa401b246e6f301cebdf64dBrian CarlstromOatMethodOffsets::~OatMethodOffsets() {}
1573320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom
158e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom}  // namespace art
159