1be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver/*
2be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * Copyright 2012, Google Inc.
3be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * All rights reserved.
4be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *
5be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * Redistribution and use in source and binary forms, with or without
6be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * modification, are permitted provided that the following conditions are
7be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * met:
8be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *
9be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *     * Redistributions of source code must retain the above copyright
10be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * notice, this list of conditions and the following disclaimer.
11be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *     * Redistributions in binary form must reproduce the above
12be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * copyright notice, this list of conditions and the following disclaimer
13be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * in the documentation and/or other materials provided with the
14be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * distribution.
15be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *     * Neither the name of Google Inc. nor the names of its
16be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * contributors may be used to endorse or promote products derived from
17be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * this software without specific prior written permission.
18be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver *
19be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver */
31be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
32be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverpackage org.jf.dexlib2.dexbacked;
33be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
345916df99999ae58f707d829792ef3997546628fdBen Gruverimport org.jf.dexlib2.base.BaseTryBlock;
35e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruverimport org.jf.dexlib2.dexbacked.raw.CodeItem;
3656c7adde039ecccf074bc42258c22ae006a33d0aIzzat Bahadirovimport org.jf.dexlib2.dexbacked.util.VariableSizeList;
37be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
38be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport javax.annotation.Nonnull;
3956c7adde039ecccf074bc42258c22ae006a33d0aIzzat Bahadirovimport java.util.List;
40be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
411bf6f2324541df184689fdb2c0d8188af5221784Ben Gruverpublic class DexBackedTryBlock extends BaseTryBlock<DexBackedExceptionHandler> {
4284c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver    @Nonnull public final DexBackedDexFile dexFile;
43d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    private final int tryItemOffset;
44d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    private final int handlersStartOffset;
45be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
4684c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver    public DexBackedTryBlock(@Nonnull DexBackedDexFile dexFile,
475ec83fb0f01281f60123b206ccec7b2a453ead93Ben Gruver                             int tryItemOffset,
48ccc4c13ae6cf774126749a5ad8f45de0c08edbeeBen Gruver                             int handlersStartOffset) {
4984c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver        this.dexFile = dexFile;
50d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver        this.tryItemOffset = tryItemOffset;
51d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver        this.handlersStartOffset = handlersStartOffset;
52be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    }
53be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
54e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver    @Override public int getStartCodeAddress() {
55e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver        return dexFile.readSmallUint(tryItemOffset + CodeItem.TryItem.START_ADDRESS_OFFSET);
56e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver    }
57e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver
58e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver    @Override public int getCodeUnitCount() {
59e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver        return dexFile.readUshort(tryItemOffset + CodeItem.TryItem.CODE_UNIT_COUNT_OFFSET);
60e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver    }
61be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
62be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    @Nonnull
63be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    @Override
641bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver    public List<? extends DexBackedExceptionHandler> getExceptionHandlers() {
65e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver        DexReader reader = dexFile.readerAt(
66e8158c86efe5494fb5b369e096c7a857623a1b11Ben Gruver                handlersStartOffset + dexFile.readUshort(tryItemOffset + CodeItem.TryItem.HANDLER_OFFSET));
67be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        final int encodedSize = reader.readSleb128();
68be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
69be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        if (encodedSize > 0) {
70be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            //no catch-all
711bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver            return new VariableSizeList<DexBackedTypedExceptionHandler>(dexFile, reader.getOffset(), encodedSize) {
728daecd0246fb0d4eb29f53ab4ef99b506d395401Ben Gruver                @Nonnull
73be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                @Override
741bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver                protected DexBackedTypedExceptionHandler readNextItem(@Nonnull DexReader reader, int index) {
751bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver                    return new DexBackedTypedExceptionHandler(reader);
76be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                }
77be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            };
78be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        } else {
79be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            //with catch-all
80be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            final int sizeWithCatchAll = (-1 * encodedSize) + 1;
811bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver            return new VariableSizeList<DexBackedExceptionHandler>(dexFile, reader.getOffset(), sizeWithCatchAll) {
828daecd0246fb0d4eb29f53ab4ef99b506d395401Ben Gruver                @Nonnull
83be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                @Override
841bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver                protected DexBackedExceptionHandler readNextItem(@Nonnull DexReader dexReader, int index) {
85be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                    if (index == sizeWithCatchAll-1) {
86ccc4c13ae6cf774126749a5ad8f45de0c08edbeeBen Gruver                        return new DexBackedCatchAllExceptionHandler(dexReader);
87be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                    } else {
881bf6f2324541df184689fdb2c0d8188af5221784Ben Gruver                        return new DexBackedTypedExceptionHandler(dexReader);
89be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                    }
90be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                }
91be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            };
92be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        }
93be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    }
94be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver}
95