1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dexfuzz.rawdex;
18 
19 import dexfuzz.Log;
20 
21 import java.io.IOException;
22 
23 public class EncodedMethod implements RawDexObject {
24   public int methodIdxDiff;
25   public int accessFlags;
26   public Offset codeOff;
27 
28   @Override
read(DexRandomAccessFile file)29   public void read(DexRandomAccessFile file) throws IOException {
30     methodIdxDiff = file.readUleb128();
31     accessFlags = file.readUleb128();
32     codeOff = file.getOffsetTracker().getNewOffset(file.readUleb128());
33     if (isNative()) {
34       Log.errorAndQuit("Sorry, DEX files with native methods are not supported yet.");
35     }
36   }
37 
38   @Override
write(DexRandomAccessFile file)39   public void write(DexRandomAccessFile file) throws IOException {
40     file.writeUleb128(methodIdxDiff);
41     file.writeUleb128(accessFlags);
42     file.getOffsetTracker().tryToWriteOffset(codeOff, file, true /* ULEB128 */);
43   }
44 
45   @Override
incrementIndex(IndexUpdateKind kind, int insertedIdx)46   public void incrementIndex(IndexUpdateKind kind, int insertedIdx) {
47     // Do nothing.
48     // NB: our idx_diff is handled in ClassDataItem...
49   }
50 
isStatic()51   public boolean isStatic() {
52     return ((accessFlags & Flag.ACC_STATIC.getValue()) != 0);
53   }
54 
isNative()55   public boolean isNative() {
56     return ((accessFlags & Flag.ACC_NATIVE.getValue()) != 0);
57   }
58 
59   /**
60    * Set/unset the static flag for this EncodedMethod.
61    */
setStatic(boolean turnOn)62   public void setStatic(boolean turnOn) {
63     if (turnOn) {
64       accessFlags |= Flag.ACC_STATIC.getValue();
65     } else {
66       accessFlags &= ~(Flag.ACC_STATIC.getValue());
67     }
68   }
69 
70   private static enum Flag {
71     ACC_PUBLIC(0x1),
72     ACC_PRIVATE(0x2),
73     ACC_PROTECTED(0x4),
74     ACC_STATIC(0x8),
75     ACC_FINAL(0x10),
76     ACC_SYNCHRONIZED(0x20),
77     ACC_VARARGS(0x80),
78     ACC_NATIVE(0x100),
79     ACC_ABSTRACT(0x400),
80     ACC_STRICT(0x800),
81     ACC_SYNTHETIC(0x1000),
82     ACC_ENUM(0x4000),
83     ACC_CONSTRUCTOR(0x10000);
84 
85     private int value;
86 
Flag(int value)87     private Flag(int value) {
88       this.value = value;
89     }
90 
getValue()91     public int getValue() {
92       return value;
93     }
94   }
95 }
96