1bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant/*
2bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * Copyright 2013, Google Inc.
3f5256e16dfc425c1d466f6308d4026d529ce9e0bHoward Hinnant * All rights reserved.
4bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant *
5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant * Redistribution and use in source and binary forms, with or without
6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant * modification, are permitted provided that the following conditions are
7bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * met:
8bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant *
9bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant *     * Redistributions of source code must retain the above copyright
10bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * notice, this list of conditions and the following disclaimer.
11bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant *     * Redistributions in binary form must reproduce the above
12bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * copyright notice, this list of conditions and the following disclaimer
13bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * in the documentation and/or other materials provided with the
14bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * distribution.
15bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant *     * Neither the name of Google Inc. nor the names of its
16bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * contributors may be used to endorse or promote products derived from
17bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * this software without specific prior written permission.
18bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant *
19bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant */
31bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
32bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpackage org.jf.dexlib2.dexbacked.raw;
33bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
34061d0cc4db18d17bf01ed14c5db0be098205bd47Marshall Clowimport org.jf.dexlib2.dexbacked.DexBackedDexFile;
357a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnantimport org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
36bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantimport org.jf.dexlib2.util.AnnotatedBytes;
37bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
38bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantimport javax.annotation.Nonnull;
39bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantimport javax.annotation.Nullable;
40bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
41bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnantpublic class FieldIdItem {
42bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    public static final int ITEM_SIZE = 8;
43bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
44bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    public static final int CLASS_OFFSET = 0;
45bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    public static final int TYPE_OFFSET = 2;
46bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    public static final int NAME_OFFSET = 4;
47bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant
48bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    @Nonnull
49bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant    public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
50bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        return new SectionAnnotator(annotator, mapItem) {
51bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant            @Nonnull @Override public String getItemName() {
52bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant                return "field_id_item";
537a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant            }
547a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant
557a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant            @Override
567a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant            protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
577a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant                int classIndex = dexFile.readUshort(out.getCursor());
587a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant                out.annotate(2, "class_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, classIndex));
597a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant
607a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant                int typeIndex = dexFile.readUshort(out.getCursor());
617a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant                out.annotate(2, "return_type_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, typeIndex));
627a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant
637a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant                int nameIndex = dexFile.readSmallUint(out.getCursor());
647a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant                out.annotate(4, "name_idx = %s", StringIdItem.getReferenceAnnotation(dexFile, nameIndex));
657a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant            }
667a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant        };
677a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant    }
687a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant
697a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant    @Nonnull
707a6b7cedcb3359ad7d77e355b02ab982d9d2b25bHoward Hinnant    public static String asString(@Nonnull DexBackedDexFile dexFile, int fieldIndex) {
71bc8d3f97eb5c958007f2713238472e0c1c8fe02Howard Hinnant        int fieldOffset = dexFile.getFieldIdItemOffset(fieldIndex);
72        int classIndex = dexFile.readUshort(fieldOffset + CLASS_OFFSET);
73        String classType = dexFile.getType(classIndex);
74
75        int typeIndex = dexFile.readUshort(fieldOffset + TYPE_OFFSET);
76        String fieldType = dexFile.getType(typeIndex);
77
78        int nameIndex = dexFile.readSmallUint(fieldOffset + NAME_OFFSET);
79        String fieldName = dexFile.getString(nameIndex);
80
81        return String.format("%s->%s:%s", classType, fieldName, fieldType);
82    }
83
84    @Nonnull
85    public static String getReferenceAnnotation(@Nonnull DexBackedDexFile dexFile, int fieldIndex) {
86        try {
87            String fieldString = asString(dexFile, fieldIndex);
88            return String.format("field_id_item[%d]: %s", fieldIndex, fieldString);
89        } catch (Exception ex) {
90            ex.printStackTrace(System.err);
91        }
92        return String.format("field_id_item[%d]", fieldIndex);
93    }
94
95    public static String[] getFields(@Nonnull RawDexFile dexFile) {
96        MapItem mapItem = dexFile.getMapItemForSection(ItemType.FIELD_ID_ITEM);
97        if (mapItem == null) {
98            return new String[0];
99        }
100
101        int fieldCount = mapItem.getItemCount();
102        String[] ret = new String[fieldCount];
103        for (int i=0; i<fieldCount; i++) {
104            ret[i] = asString(dexFile, i);
105        }
106        return ret;
107    }
108}
109