Add oatdump support for app images
Example usage on host:
oatdumpd --app-oat=art/plus32.odex --app-image=art/plus32.art
--image=art/oats/system@framework@boot.art --instruction-set=arm
TODO: Add to oatdump test.
Bug: 27408512
Bug: 22858531
(cherry picked from commit bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0)
Change-Id: I9d1aa7eaa16795e5fbabc6974d245849e16b1d03
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index bea1dcc..895d3d3 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -617,7 +617,7 @@
}
// Returns the delta between the dest from the source.
- off_t Delta() const {
+ uintptr_t Delta() const {
return dest_ - source_;
}
@@ -639,6 +639,13 @@
const uintptr_t length_;
};
+std::ostream& operator<<(std::ostream& os, const RelocationRange& reloc) {
+ return os << "(" << reinterpret_cast<const void*>(reloc.Source()) << "-"
+ << reinterpret_cast<const void*>(reloc.Source() + reloc.Length()) << ")->("
+ << reinterpret_cast<const void*>(reloc.Dest()) << "-"
+ << reinterpret_cast<const void*>(reloc.Dest() + reloc.Length()) << ")";
+}
+
class FixupVisitor : public ValueObject {
public:
FixupVisitor(const RelocationRange& boot_image,
@@ -670,7 +677,7 @@
ALWAYS_INLINE const void* ForwardCode(const void* src) const {
const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src);
if (boot_oat_.InSource(uint_src)) {
- return reinterpret_cast<const void*>(boot_oat_.ToDest(uint_src));
+ return reinterpret_cast<const void*>(boot_oat_.ToDest(uint_src));
}
if (app_oat_.InSource(uint_src)) {
return reinterpret_cast<const void*>(app_oat_.ToDest(uint_src));
@@ -687,13 +694,6 @@
const RelocationRange app_oat_;
};
-std::ostream& operator<<(std::ostream& os, const RelocationRange& reloc) {
- return os << "(" << reinterpret_cast<const void*>(reloc.Source()) << "-"
- << reinterpret_cast<const void*>(reloc.Source() + reloc.Length()) << ")->("
- << reinterpret_cast<const void*>(reloc.Dest()) << "-"
- << reinterpret_cast<const void*>(reloc.Dest() + reloc.Length()) << ")";
-}
-
// Adapt for mirror::Class::FixupNativePointers.
class FixupObjectAdapter : public FixupVisitor {
public:
@@ -756,8 +756,10 @@
public:
template<typename... Args>
explicit FixupObjectVisitor(gc::accounting::ContinuousSpaceBitmap* pointer_array_visited,
+ const size_t pointer_size,
Args... args)
: FixupVisitor(args...),
+ pointer_size_(pointer_size),
pointer_array_visited_(pointer_array_visited) {}
// Fix up separately since we also need to fix up method entrypoints.
@@ -791,7 +793,7 @@
if (array != nullptr &&
visitor.IsInAppImage(array) &&
!pointer_array_visited_->Test(array)) {
- array->Fixup<kVerifyNone, kWithoutReadBarrier>(array, sizeof(void*), visitor);
+ array->Fixup<kVerifyNone, kWithoutReadBarrier>(array, pointer_size_, visitor);
pointer_array_visited_->Set(array);
}
}
@@ -813,7 +815,7 @@
if (obj->IsClass<kVerifyNone, kWithoutReadBarrier>()) {
mirror::Class* klass = obj->AsClass<kVerifyNone, kWithoutReadBarrier>();
FixupObjectAdapter visitor(boot_image_, boot_oat_, app_image_, app_oat_);
- klass->FixupNativePointers<kVerifyNone, kWithoutReadBarrier>(klass, sizeof(void*), visitor);
+ klass->FixupNativePointers<kVerifyNone, kWithoutReadBarrier>(klass, pointer_size_, visitor);
// Deal with the pointer arrays. Use the helper function since multiple classes can reference
// the same arrays.
VisitPointerArray(klass->GetVTable<kVerifyNone, kWithoutReadBarrier>(), visitor);
@@ -832,6 +834,7 @@
}
private:
+ const size_t pointer_size_;
gc::accounting::ContinuousSpaceBitmap* const pointer_array_visited_;
};
@@ -850,7 +853,8 @@
class ForwardCodeAdapter {
public:
- ALWAYS_INLINE ForwardCodeAdapter(const FixupVisitor* visitor) : visitor_(visitor) {}
+ ALWAYS_INLINE ForwardCodeAdapter(const FixupVisitor* visitor)
+ : visitor_(visitor) {}
template <typename T>
ALWAYS_INLINE T* operator()(T* src) const {
@@ -864,19 +868,21 @@
class FixupArtMethodVisitor : public FixupVisitor, public ArtMethodVisitor {
public:
template<typename... Args>
- explicit FixupArtMethodVisitor(bool fixup_heap_objects, Args... args)
+ explicit FixupArtMethodVisitor(bool fixup_heap_objects, size_t pointer_size, Args... args)
: FixupVisitor(args...),
- fixup_heap_objects_(fixup_heap_objects) {}
+ fixup_heap_objects_(fixup_heap_objects),
+ pointer_size_(pointer_size) {}
virtual void Visit(ArtMethod* method) NO_THREAD_SAFETY_ANALYSIS {
if (fixup_heap_objects_) {
- method->UpdateObjectsForImageRelocation(ForwardObjectAdapter(this));
+ method->UpdateObjectsForImageRelocation(ForwardObjectAdapter(this), pointer_size_);
}
- method->UpdateEntrypoints<kWithoutReadBarrier>(ForwardCodeAdapter(this));
+ method->UpdateEntrypoints<kWithoutReadBarrier>(ForwardCodeAdapter(this), pointer_size_);
}
private:
const bool fixup_heap_objects_;
+ const size_t pointer_size_;
};
class FixupArtFieldVisitor : public FixupVisitor, public ArtFieldVisitor {
@@ -912,6 +918,7 @@
uint32_t boot_image_end = 0;
uint32_t boot_oat_begin = 0;
uint32_t boot_oat_end = 0;
+ const size_t pointer_size = image_header.GetPointerSize();
gc::Heap* const heap = Runtime::Current()->GetHeap();
heap->GetBootImagesSize(&boot_image_begin, &boot_image_end, &boot_oat_begin, &boot_oat_end);
CHECK_NE(boot_image_begin, boot_image_end)
@@ -974,6 +981,7 @@
target_base,
image_header.GetImageSize()));
FixupObjectVisitor fixup_object_visitor(visited_bitmap.get(),
+ pointer_size,
boot_image,
boot_oat,
app_image,
@@ -1023,10 +1031,10 @@
dex_cache->SetResolvedMethods(new_methods);
}
for (size_t j = 0, num = dex_cache->NumResolvedMethods(); j != num; ++j) {
- ArtMethod* orig = mirror::DexCache::GetElementPtrSize(new_methods, j, sizeof(void*));
+ ArtMethod* orig = mirror::DexCache::GetElementPtrSize(new_methods, j, pointer_size);
ArtMethod* copy = fixup_adapter.ForwardObject(orig);
if (orig != copy) {
- mirror::DexCache::SetElementPtrSize(new_methods, j, copy, sizeof(void*));
+ mirror::DexCache::SetElementPtrSize(new_methods, j, copy, pointer_size);
}
}
}
@@ -1037,10 +1045,10 @@
dex_cache->SetResolvedFields(new_fields);
}
for (size_t j = 0, num = dex_cache->NumResolvedFields(); j != num; ++j) {
- ArtField* orig = mirror::DexCache::GetElementPtrSize(new_fields, j, sizeof(void*));
+ ArtField* orig = mirror::DexCache::GetElementPtrSize(new_fields, j, pointer_size);
ArtField* copy = fixup_adapter.ForwardObject(orig);
if (orig != copy) {
- mirror::DexCache::SetElementPtrSize(new_fields, j, copy, sizeof(void*));
+ mirror::DexCache::SetElementPtrSize(new_fields, j, copy, pointer_size);
}
}
}
@@ -1049,11 +1057,16 @@
{
// Only touches objects in the app image, no need for mutator lock.
TimingLogger::ScopedTiming timing("Fixup methods", &logger);
- FixupArtMethodVisitor method_visitor(fixup_image, boot_image, boot_oat, app_image, app_oat);
+ FixupArtMethodVisitor method_visitor(fixup_image,
+ pointer_size,
+ boot_image,
+ boot_oat,
+ app_image,
+ app_oat);
image_header.GetImageSection(ImageHeader::kSectionArtMethods).VisitPackedArtMethods(
&method_visitor,
target_base,
- sizeof(void*));
+ pointer_size);
}
if (fixup_image) {
{
@@ -1381,6 +1394,7 @@
image_header.GetOatDataBegin(),
image_header.GetOatFileBegin(),
!Runtime::Current()->IsAotCompiler(),
+ /*low_4gb*/false,
nullptr,
error_msg);
if (oat_file == nullptr) {