15b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver/*
25b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * Copyright 2013, Google Inc.
35b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * All rights reserved.
45b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver *
55b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * Redistribution and use in source and binary forms, with or without
65b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * modification, are permitted provided that the following conditions are
75b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * met:
85b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver *
95b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver *     * Redistributions of source code must retain the above copyright
105b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * notice, this list of conditions and the following disclaimer.
115b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver *     * Redistributions in binary form must reproduce the above
125b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * copyright notice, this list of conditions and the following disclaimer
135b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * in the documentation and/or other materials provided with the
145b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * distribution.
155b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver *     * Neither the name of Google Inc. nor the names of its
165b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * contributors may be used to endorse or promote products derived from
175b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * this software without specific prior written permission.
185b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver *
195b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver */
315b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
325b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruverpackage org.jf.dexlib2.dexbacked.raw;
335b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
345b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruverimport org.jf.dexlib2.dexbacked.DexBackedDexFile;
358f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruverimport org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
365b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruverimport org.jf.dexlib2.util.AnnotatedBytes;
375b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
385b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruverimport javax.annotation.Nonnull;
398f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruverimport javax.annotation.Nullable;
405b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
415b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruverpublic class ProtoIdItem {
425b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver    public static final int ITEM_SIZE = 12;
435b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
445b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver    public static final int SHORTY_OFFSET = 0;
455b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver    public static final int RETURN_TYPE_OFFSET = 4;
465b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver    public static final int PARAMETERS_OFFSET = 8;
475b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
4818b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver    @Nonnull
498f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver    public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
508f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver        return new SectionAnnotator(annotator, mapItem) {
5178612c755447a47945d7179a688120856db0a76dBen Gruver            @Nonnull @Override public String getItemName() {
5278612c755447a47945d7179a688120856db0a76dBen Gruver                return "proto_id_item";
535b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver            }
545b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
5578612c755447a47945d7179a688120856db0a76dBen Gruver            @Override
568f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver            protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
5778612c755447a47945d7179a688120856db0a76dBen Gruver                int shortyIndex = dexFile.readSmallUint(out.getCursor());
5878612c755447a47945d7179a688120856db0a76dBen Gruver                out.annotate(4, "shorty_idx = %s", StringIdItem.getReferenceAnnotation(dexFile, shortyIndex));
595b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
6078612c755447a47945d7179a688120856db0a76dBen Gruver                int returnTypeIndex = dexFile.readSmallUint(out.getCursor());
6178612c755447a47945d7179a688120856db0a76dBen Gruver                out.annotate(4, "return_type_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, returnTypeIndex));
625b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver
6378612c755447a47945d7179a688120856db0a76dBen Gruver                int parametersOffset = dexFile.readSmallUint(out.getCursor());
6478612c755447a47945d7179a688120856db0a76dBen Gruver                out.annotate(4, "parameters_off = %s", TypeListItem.getReferenceAnnotation(dexFile, parametersOffset));
6578612c755447a47945d7179a688120856db0a76dBen Gruver            }
6678612c755447a47945d7179a688120856db0a76dBen Gruver        };
6718b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver    }
6818b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver
6918b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver    @Nonnull
7018b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver    public static String getReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int protoIndex) {
7118b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        try {
7218b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver            String protoString = asString(dexFile, protoIndex);
7378612c755447a47945d7179a688120856db0a76dBen Gruver            return String.format("proto_id_item[%d]: %s", protoIndex, protoString);
7418b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        } catch (Exception ex) {
7518b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver            ex.printStackTrace(System.err);
765b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver        }
7718b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        return String.format("proto_id_item[%d]", protoIndex);
7818b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver    }
7918b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver
8018b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver    @Nonnull
8118b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver    public static String asString(@Nonnull DexBackedDexFile dexFile, int protoIndex) {
8218b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        int offset = dexFile.getProtoIdItemOffset(protoIndex);
8318b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver
8418b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        StringBuilder sb = new StringBuilder();
8518b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        sb.append("(");
8618b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver
8718b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        int parametersOffset = dexFile.readSmallUint(offset + PARAMETERS_OFFSET);
8818b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        sb.append(TypeListItem.asString(dexFile, parametersOffset));
8918b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        sb.append(")");
9018b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver
9118b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        int returnTypeIndex = dexFile.readSmallUint(offset + RETURN_TYPE_OFFSET);
9218b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        String returnType = dexFile.getType(returnTypeIndex);
9318b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        sb.append(returnType);
9418b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver
9518b069d17ee8f0fb589c31de0afbbb8240975d14Ben Gruver        return sb.toString();
965b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver    }
97132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver
98132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver    public static String[] getProtos(@Nonnull RawDexFile dexFile) {
99132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver        MapItem mapItem = dexFile.getMapItemForSection(ItemType.PROTO_ID_ITEM);
100132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver        if (mapItem == null) {
101132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver            return new String[0];
102132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver        }
103132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver
104132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver        int protoCount = mapItem.getItemCount();
105132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver        String[] ret = new String[protoCount];
106132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver        for (int i=0; i<protoCount; i++) {
107132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver            ret[i] = asString(dexFile, i);
108132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver        }
109132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver        return ret;
110132eeaedf7d0980397fbdac41e1a7aebff01adbfBen Gruver    }
1115b71582325a2e9df14f627d731b46a91ee8064c5Ben Gruver}
112