/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "slicer/dex_format.h" #include "slicer/common.h" #include <zlib.h> #include <sstream> namespace dex { // Compute the DEX file checksum for a memory-mapped DEX file u4 ComputeChecksum(const Header* header) { const u1* start = reinterpret_cast<const u1*>(header); uLong adler = adler32(0L, Z_NULL, 0); const int non_sum = sizeof(header->magic) + sizeof(header->checksum); return static_cast<u4>( adler32(adler, start + non_sum, header->file_size - non_sum)); } // Returns the human-readable name for a primitive type static const char* PrimitiveTypeName(char type_char) { switch (type_char) { case 'B': return "byte"; case 'C': return "char"; case 'D': return "double"; case 'F': return "float"; case 'I': return "int"; case 'J': return "long"; case 'S': return "short"; case 'V': return "void"; case 'Z': return "boolean"; } SLICER_CHECK(!"unexpected type"); return nullptr; } // Converts a type descriptor to human-readable "dotted" form. For // example, "Ljava/lang/String;" becomes "java.lang.String", and // "[I" becomes "int[]". std::string DescriptorToDecl(const char* descriptor) { std::stringstream ss; int array_dimensions = 0; while (*descriptor == '[') { ++array_dimensions; ++descriptor; } if (*descriptor == 'L') { for (++descriptor; *descriptor != ';'; ++descriptor) { SLICER_CHECK(*descriptor != '\0'); ss << (*descriptor == '/' ? '.' : *descriptor); } } else { ss << PrimitiveTypeName(*descriptor); } SLICER_CHECK(descriptor[1] == '\0'); // add the array brackets for (int i = 0; i < array_dimensions; ++i) { ss << "[]"; } return ss.str(); } // Converts a type descriptor to a single "shorty" char // (ex. "LFoo;" and "[[I" become 'L', "I" stays 'I') char DescriptorToShorty(const char* descriptor) { // skip array dimensions int array_dimensions = 0; while (*descriptor == '[') { ++array_dimensions; ++descriptor; } char short_descriptor = *descriptor; if (short_descriptor == 'L') { // skip the full class name for(; *descriptor && *descriptor != ';'; ++descriptor); SLICER_CHECK(*descriptor == ';'); } SLICER_CHECK(descriptor[1] == '\0'); SLICER_CHECK(short_descriptor == 'L' || PrimitiveTypeName(short_descriptor) != nullptr); return array_dimensions > 0 ? 'L' : short_descriptor; } } // namespace dex