DexBackedTryBlock.java revision 56c7adde039ecccf074bc42258c22ae006a33d0a
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
3456c7adde039ecccf074bc42258c22ae006a33d0aIzzat Bahadirovimport org.jf.dexlib2.dexbacked.util.VariableSizeList;
35be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport org.jf.dexlib2.iface.ExceptionHandler;
36be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport org.jf.dexlib2.iface.TryBlock;
37be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
38be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverimport javax.annotation.Nonnull;
3956c7adde039ecccf074bc42258c22ae006a33d0aIzzat Bahadirovimport java.util.List;
40be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
41be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruverpublic class DexBackedTryBlock implements TryBlock {
4225d385a441b95d56987c81f00f19297d799e1b31Ben Gruver    @Nonnull public final DexBuffer dexBuf;
43d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    private final int tryItemOffset;
44d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    private final int handlersStartOffset;
45be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
465ec83fb0f01281f60123b206ccec7b2a453ead93Ben Gruver    private static final int START_ADDRESS_OFFSET = 0;
475ec83fb0f01281f60123b206ccec7b2a453ead93Ben Gruver    private static final int CODE_UNIT_COUNT_OFFSET = 4;
485ec83fb0f01281f60123b206ccec7b2a453ead93Ben Gruver    private static final int HANDLER_OFFSET_OFFSET = 6;
495ec83fb0f01281f60123b206ccec7b2a453ead93Ben Gruver
5025d385a441b95d56987c81f00f19297d799e1b31Ben Gruver    public DexBackedTryBlock(@Nonnull DexBuffer dexBuf,
515ec83fb0f01281f60123b206ccec7b2a453ead93Ben Gruver                             int tryItemOffset,
52ccc4c13ae6cf774126749a5ad8f45de0c08edbeeBen Gruver                             int handlersStartOffset) {
5336e2ee200517b36652a6e8fe1c5aa24ce249765eBen Gruver        this.dexBuf = dexBuf;
54d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver        this.tryItemOffset = tryItemOffset;
55d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver        this.handlersStartOffset = handlersStartOffset;
56be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    }
57be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
58bea9627ed75546d7df9e79c927b9329c70a29808Ben Gruver    @Override public int getStartCodeAddress() { return dexBuf.readSmallUint(tryItemOffset + START_ADDRESS_OFFSET); }
59d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver    @Override public int getCodeUnitCount() { return dexBuf.readUshort(tryItemOffset + CODE_UNIT_COUNT_OFFSET); }
60be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
61be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    @Nonnull
62be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    @Override
6356c7adde039ecccf074bc42258c22ae006a33d0aIzzat Bahadirov    public List<? extends ExceptionHandler> getExceptionHandlers() {
64d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver        DexReader reader =
65d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver                dexBuf.readerAt(handlersStartOffset + dexBuf.readUshort(tryItemOffset + HANDLER_OFFSET_OFFSET));
66be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        final int encodedSize = reader.readSleb128();
67be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver
68be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        if (encodedSize > 0) {
69be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            //no catch-all
7056c7adde039ecccf074bc42258c22ae006a33d0aIzzat Bahadirov            return new VariableSizeList<ExceptionHandler>(dexBuf, reader.getOffset(), encodedSize) {
718daecd0246fb0d4eb29f53ab4ef99b506d395401Ben Gruver                @Nonnull
72be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                @Override
7356c7adde039ecccf074bc42258c22ae006a33d0aIzzat Bahadirov                protected ExceptionHandler readNextItem(@Nonnull DexReader reader, int index) {
74d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver                    return new DexBackedExceptionHandler(reader);
75be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                }
76be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            };
77be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        } else {
78be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            //with catch-all
79be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            final int sizeWithCatchAll = (-1 * encodedSize) + 1;
8056c7adde039ecccf074bc42258c22ae006a33d0aIzzat Bahadirov            return new VariableSizeList<ExceptionHandler>(dexBuf, reader.getOffset(), sizeWithCatchAll) {
818daecd0246fb0d4eb29f53ab4ef99b506d395401Ben Gruver                @Nonnull
82be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                @Override
8312b970ed4dfad768002335503e49c348ea0ed69bBen Gruver                protected ExceptionHandler readNextItem(@Nonnull DexReader dexReader, int index) {
84be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                    if (index == sizeWithCatchAll-1) {
85ccc4c13ae6cf774126749a5ad8f45de0c08edbeeBen Gruver                        return new DexBackedCatchAllExceptionHandler(dexReader);
86be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                    } else {
87d1662b67fecaf835227aff3a136949a2358ccd4eBen Gruver                        return new DexBackedExceptionHandler(dexReader);
88be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                    }
89be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver                }
90be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver            };
91be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver        }
92be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver    }
93be799799ff8bbc5d86f8cfdc850947ab4f41695fBen Gruver}
94