1959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle/*
2959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Copyright (C) 2014 The Android Open Source Project
3959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle *
4959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Licensed under the Apache License, Version 2.0 (the "License");
5959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * you may not use this file except in compliance with the License.
6959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * You may obtain a copy of the License at
7959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle *
8959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle *      http://www.apache.org/licenses/LICENSE-2.0
9959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle *
10959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Unless required by applicable law or agreed to in writing, software
11959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * distributed under the License is distributed on an "AS IS" BASIS,
12959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * See the License for the specific language governing permissions and
14959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * limitations under the License.
15959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */
16959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
17959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepackage dexfuzz.rawdex;
18959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
19959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.Log;
20959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
21959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.io.IOException;
22959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
23959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepublic class EncodedMethod implements RawDexObject {
24959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public int methodIdxDiff;
25959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public int accessFlags;
26959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public Offset codeOff;
27959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
28959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  @Override
29959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public void read(DexRandomAccessFile file) throws IOException {
30959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    methodIdxDiff = file.readUleb128();
31959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    accessFlags = file.readUleb128();
32959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    codeOff = file.getOffsetTracker().getNewOffset(file.readUleb128());
33959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    if (isNative()) {
34959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      Log.errorAndQuit("Sorry, DEX files with native methods are not supported yet.");
35959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    }
36959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
37959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
38959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  @Override
39959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public void write(DexRandomAccessFile file) throws IOException {
40959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    file.writeUleb128(methodIdxDiff);
41959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    file.writeUleb128(accessFlags);
42959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    file.getOffsetTracker().tryToWriteOffset(codeOff, file, true /* ULEB128 */);
43959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
44959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
45959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  @Override
46959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public void incrementIndex(IndexUpdateKind kind, int insertedIdx) {
47959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    // Do nothing.
48959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    // NB: our idx_diff is handled in ClassDataItem...
49959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
50959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
51959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public boolean isStatic() {
52959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    return ((accessFlags & Flag.ACC_STATIC.getValue()) != 0);
53959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
54959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
55959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public boolean isNative() {
56959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    return ((accessFlags & Flag.ACC_NATIVE.getValue()) != 0);
57959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
58959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
59959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  /**
60959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   * Set/unset the static flag for this EncodedMethod.
61959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle   */
62959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  public void setStatic(boolean turnOn) {
63959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    if (turnOn) {
64959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      accessFlags |= Flag.ACC_STATIC.getValue();
65959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    } else {
66959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      accessFlags &= ~(Flag.ACC_STATIC.getValue());
67959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    }
68959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
69959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
70959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  private static enum Flag {
71959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_PUBLIC(0x1),
72959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_PRIVATE(0x2),
73959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_PROTECTED(0x4),
74959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_STATIC(0x8),
75959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_FINAL(0x10),
76959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_SYNCHRONIZED(0x20),
77959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_VARARGS(0x80),
78959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_NATIVE(0x100),
79959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_ABSTRACT(0x400),
80959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_STRICT(0x800),
81959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_SYNTHETIC(0x1000),
82959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_ENUM(0x4000),
83959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    ACC_CONSTRUCTOR(0x10000);
84959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
85959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    private int value;
86959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
87959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    private Flag(int value) {
88959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      this.value = value;
89959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    }
90959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle
91959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    public int getValue() {
92959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle      return value;
93959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle    }
94959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle  }
95959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle}
96