• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package org.jf.dexlib2.writer;
33 
34 import com.google.common.collect.Ordering;
35 import com.google.common.primitives.Ints;
36 import org.jf.dexlib2.Opcode;
37 import org.jf.dexlib2.Opcodes;
38 import org.jf.dexlib2.ReferenceType;
39 import org.jf.dexlib2.iface.instruction.DualReferenceInstruction;
40 import org.jf.dexlib2.iface.instruction.ReferenceInstruction;
41 import org.jf.dexlib2.iface.instruction.SwitchElement;
42 import org.jf.dexlib2.iface.instruction.formats.*;
43 import org.jf.dexlib2.iface.reference.FieldReference;
44 import org.jf.dexlib2.iface.reference.MethodProtoReference;
45 import org.jf.dexlib2.iface.reference.MethodReference;
46 import org.jf.dexlib2.iface.reference.Reference;
47 import org.jf.dexlib2.iface.reference.StringReference;
48 import org.jf.dexlib2.iface.reference.TypeReference;
49 import org.jf.util.ExceptionWithContext;
50 
51 import javax.annotation.Nonnull;
52 import java.io.IOException;
53 import java.util.Comparator;
54 import java.util.List;
55 
56 public class InstructionWriter<StringRef extends StringReference, TypeRef extends TypeReference,
57         FieldRefKey extends FieldReference, MethodRefKey extends MethodReference,
58         ProtoRefKey extends MethodProtoReference> {
59     @Nonnull private final Opcodes opcodes;
60     @Nonnull private final DexDataWriter writer;
61     @Nonnull private final StringSection<?, StringRef> stringSection;
62     @Nonnull private final TypeSection<?, ?, TypeRef> typeSection;
63     @Nonnull private final FieldSection<?, ?, FieldRefKey, ?> fieldSection;
64     @Nonnull private final MethodSection<?, ?, ?, MethodRefKey, ?> methodSection;
65     @Nonnull private final ProtoSection<?, ?, ProtoRefKey, ?> protoSection;
66 
67     @Nonnull static <StringRef extends StringReference, TypeRef extends TypeReference, FieldRefKey extends FieldReference,
68             MethodRefKey extends MethodReference, ProtoRefKey extends MethodProtoReference>
69             InstructionWriter<StringRef, TypeRef, FieldRefKey, MethodRefKey, ProtoRefKey>
makeInstructionWriter( @onnull Opcodes opcodes, @Nonnull DexDataWriter writer, @Nonnull StringSection<?, StringRef> stringSection, @Nonnull TypeSection<?, ?, TypeRef> typeSection, @Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection, @Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection, @Nonnull ProtoSection<?, ?, ProtoRefKey, ?> protoSection)70             makeInstructionWriter(
71                 @Nonnull Opcodes opcodes,
72                 @Nonnull DexDataWriter writer,
73                 @Nonnull StringSection<?, StringRef> stringSection,
74                 @Nonnull TypeSection<?, ?, TypeRef> typeSection,
75                 @Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
76                 @Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection,
77                 @Nonnull ProtoSection<?, ?, ProtoRefKey, ?> protoSection) {
78         return new InstructionWriter<StringRef, TypeRef, FieldRefKey, MethodRefKey, ProtoRefKey>(
79                 opcodes, writer, stringSection, typeSection, fieldSection, methodSection, protoSection);
80     }
81 
InstructionWriter(@onnull Opcodes opcodes, @Nonnull DexDataWriter writer, @Nonnull StringSection<?, StringRef> stringSection, @Nonnull TypeSection<?, ?, TypeRef> typeSection, @Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection, @Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection, @Nonnull ProtoSection<?, ?, ProtoRefKey, ?> protoSection)82     InstructionWriter(@Nonnull Opcodes opcodes,
83                       @Nonnull DexDataWriter writer,
84                       @Nonnull StringSection<?, StringRef> stringSection,
85                       @Nonnull TypeSection<?, ?, TypeRef> typeSection,
86                       @Nonnull FieldSection<?, ?, FieldRefKey, ?> fieldSection,
87                       @Nonnull MethodSection<?, ?, ?, MethodRefKey, ?> methodSection,
88                       @Nonnull ProtoSection<?, ?, ProtoRefKey, ?> protoSection) {
89         this.opcodes = opcodes;
90         this.writer = writer;
91         this.stringSection = stringSection;
92         this.typeSection = typeSection;
93         this.fieldSection = fieldSection;
94         this.methodSection = methodSection;
95         this.protoSection = protoSection;
96     }
97 
getOpcodeValue(Opcode opcode)98     private short getOpcodeValue(Opcode opcode) {
99         Short value = opcodes.getOpcodeValue(opcode);
100         if (value == null) {
101             throw new ExceptionWithContext("Instruction %s is invalid for api %d", opcode.name, opcodes.api);
102         }
103         return value;
104     }
105 
write(@onnull Instruction10t instruction)106     public void write(@Nonnull Instruction10t instruction) {
107         try {
108             writer.write(getOpcodeValue(instruction.getOpcode()));
109             writer.write(instruction.getCodeOffset());
110         } catch (IOException ex) {
111             throw new RuntimeException(ex);
112         }
113     }
114 
write(@onnull Instruction10x instruction)115     public void write(@Nonnull Instruction10x instruction) {
116         try {
117             writer.write(getOpcodeValue(instruction.getOpcode()));
118             writer.write(0);
119         } catch (IOException ex) {
120             throw new RuntimeException(ex);
121         }
122     }
123 
write(@onnull Instruction11n instruction)124     public void write(@Nonnull Instruction11n instruction) {
125         try {
126             writer.write(getOpcodeValue(instruction.getOpcode()));
127             writer.write(packNibbles(instruction.getRegisterA(), instruction.getNarrowLiteral()));
128         } catch (IOException ex) {
129             throw new RuntimeException(ex);
130         }
131     }
132 
write(@onnull Instruction11x instruction)133     public void write(@Nonnull Instruction11x instruction) {
134         try {
135             writer.write(getOpcodeValue(instruction.getOpcode()));
136             writer.write(instruction.getRegisterA());
137         } catch (IOException ex) {
138             throw new RuntimeException(ex);
139         }
140     }
141 
write(@onnull Instruction12x instruction)142     public void write(@Nonnull Instruction12x instruction) {
143         try {
144             writer.write(getOpcodeValue(instruction.getOpcode()));
145             writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
146         } catch (IOException ex) {
147             throw new RuntimeException(ex);
148         }
149     }
150 
write(@onnull Instruction20bc instruction)151     public void write(@Nonnull Instruction20bc instruction) {
152         try {
153             writer.write(getOpcodeValue(instruction.getOpcode()));
154             writer.write(instruction.getVerificationError());
155             writer.writeUshort(getReferenceIndex(instruction));
156         } catch (IOException ex) {
157             throw new RuntimeException(ex);
158         }
159     }
160 
write(@onnull Instruction20t instruction)161     public void write(@Nonnull Instruction20t instruction) {
162         try {
163             writer.write(getOpcodeValue(instruction.getOpcode()));
164             writer.write(0);
165             writer.writeShort(instruction.getCodeOffset());
166         } catch (IOException ex) {
167             throw new RuntimeException(ex);
168         }
169     }
170 
write(@onnull Instruction21c instruction)171     public void write(@Nonnull Instruction21c instruction) {
172         try {
173             writer.write(getOpcodeValue(instruction.getOpcode()));
174             writer.write(instruction.getRegisterA());
175             writer.writeUshort(getReferenceIndex(instruction));
176         } catch (IOException ex) {
177             throw new RuntimeException(ex);
178         }
179     }
180 
write(@onnull Instruction21ih instruction)181     public void write(@Nonnull Instruction21ih instruction) {
182         try {
183             writer.write(getOpcodeValue(instruction.getOpcode()));
184             writer.write(instruction.getRegisterA());
185             writer.writeShort(instruction.getHatLiteral());
186         } catch (IOException ex) {
187             throw new RuntimeException(ex);
188         }
189     }
190 
write(@onnull Instruction21lh instruction)191     public void write(@Nonnull Instruction21lh instruction) {
192         try {
193             writer.write(getOpcodeValue(instruction.getOpcode()));
194             writer.write(instruction.getRegisterA());
195             writer.writeShort(instruction.getHatLiteral());
196         } catch (IOException ex) {
197             throw new RuntimeException(ex);
198         }
199     }
200 
write(@onnull Instruction21s instruction)201     public void write(@Nonnull Instruction21s instruction) {
202         try {
203             writer.write(getOpcodeValue(instruction.getOpcode()));
204             writer.write(instruction.getRegisterA());
205             writer.writeShort(instruction.getNarrowLiteral());
206         } catch (IOException ex) {
207             throw new RuntimeException(ex);
208         }
209     }
210 
write(@onnull Instruction21t instruction)211     public void write(@Nonnull Instruction21t instruction) {
212         try {
213             writer.write(getOpcodeValue(instruction.getOpcode()));
214             writer.write(instruction.getRegisterA());
215             writer.writeShort(instruction.getCodeOffset());
216         } catch (IOException ex) {
217             throw new RuntimeException(ex);
218         }
219     }
220 
write(@onnull Instruction22b instruction)221     public void write(@Nonnull Instruction22b instruction) {
222         try {
223             writer.write(getOpcodeValue(instruction.getOpcode()));
224             writer.write(instruction.getRegisterA());
225             writer.write(instruction.getRegisterB());
226             writer.write(instruction.getNarrowLiteral());
227         } catch (IOException ex) {
228             throw new RuntimeException(ex);
229         }
230     }
231 
write(@onnull Instruction22c instruction)232     public void write(@Nonnull Instruction22c instruction) {
233         try {
234             writer.write(getOpcodeValue(instruction.getOpcode()));
235             writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
236             writer.writeUshort(getReferenceIndex(instruction));
237         } catch (IOException ex) {
238             throw new RuntimeException(ex);
239         }
240     }
241 
write(@onnull Instruction22cs instruction)242     public void write(@Nonnull Instruction22cs instruction) {
243         try {
244             writer.write(getOpcodeValue(instruction.getOpcode()));
245             writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
246             writer.writeUshort(instruction.getFieldOffset());
247         } catch (IOException ex) {
248             throw new RuntimeException(ex);
249         }
250     }
251 
write(@onnull Instruction22s instruction)252     public void write(@Nonnull Instruction22s instruction) {
253         try {
254             writer.write(getOpcodeValue(instruction.getOpcode()));
255             writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
256             writer.writeShort(instruction.getNarrowLiteral());
257         } catch (IOException ex) {
258             throw new RuntimeException(ex);
259         }
260     }
261 
write(@onnull Instruction22t instruction)262     public void write(@Nonnull Instruction22t instruction) {
263         try {
264             writer.write(getOpcodeValue(instruction.getOpcode()));
265             writer.write(packNibbles(instruction.getRegisterA(), instruction.getRegisterB()));
266             writer.writeShort(instruction.getCodeOffset());
267         } catch (IOException ex) {
268             throw new RuntimeException(ex);
269         }
270     }
271 
write(@onnull Instruction22x instruction)272     public void write(@Nonnull Instruction22x instruction) {
273         try {
274             writer.write(getOpcodeValue(instruction.getOpcode()));
275             writer.write(instruction.getRegisterA());
276             writer.writeUshort(instruction.getRegisterB());
277         } catch (IOException ex) {
278             throw new RuntimeException(ex);
279         }
280     }
281 
write(@onnull Instruction23x instruction)282     public void write(@Nonnull Instruction23x instruction) {
283         try {
284             writer.write(getOpcodeValue(instruction.getOpcode()));
285             writer.write(instruction.getRegisterA());
286             writer.write(instruction.getRegisterB());
287             writer.write(instruction.getRegisterC());
288         } catch (IOException ex) {
289             throw new RuntimeException(ex);
290         }
291     }
292 
write(@onnull Instruction30t instruction)293     public void write(@Nonnull Instruction30t instruction) {
294         try {
295             writer.write(getOpcodeValue(instruction.getOpcode()));
296             writer.write(0);
297             writer.writeInt(instruction.getCodeOffset());
298         } catch (IOException ex) {
299             throw new RuntimeException(ex);
300         }
301     }
302 
write(@onnull Instruction31c instruction)303     public void write(@Nonnull Instruction31c instruction) {
304         try {
305             writer.write(getOpcodeValue(instruction.getOpcode()));
306             writer.write(instruction.getRegisterA());
307             writer.writeInt(getReferenceIndex(instruction));
308         } catch (IOException ex) {
309             throw new RuntimeException(ex);
310         }
311     }
312 
write(@onnull Instruction31i instruction)313     public void write(@Nonnull Instruction31i instruction) {
314         try {
315             writer.write(getOpcodeValue(instruction.getOpcode()));
316             writer.write(instruction.getRegisterA());
317             writer.writeInt(instruction.getNarrowLiteral());
318         } catch (IOException ex) {
319             throw new RuntimeException(ex);
320         }
321     }
322 
write(@onnull Instruction31t instruction)323     public void write(@Nonnull Instruction31t instruction) {
324         try {
325             writer.write(getOpcodeValue(instruction.getOpcode()));
326             writer.write(instruction.getRegisterA());
327             writer.writeInt(instruction.getCodeOffset());
328         } catch (IOException ex) {
329             throw new RuntimeException(ex);
330         }
331     }
332 
write(@onnull Instruction32x instruction)333     public void write(@Nonnull Instruction32x instruction) {
334         try {
335             writer.write(getOpcodeValue(instruction.getOpcode()));
336             writer.write(0);
337             writer.writeUshort(instruction.getRegisterA());
338             writer.writeUshort(instruction.getRegisterB());
339         } catch (IOException ex) {
340             throw new RuntimeException(ex);
341         }
342     }
343 
write(@onnull Instruction35c instruction)344     public void write(@Nonnull Instruction35c instruction) {
345         try {
346             writer.write(getOpcodeValue(instruction.getOpcode()));
347             writer.write(packNibbles(instruction.getRegisterG(), instruction.getRegisterCount()));
348             writer.writeUshort(getReferenceIndex(instruction));
349             writer.write(packNibbles(instruction.getRegisterC(), instruction.getRegisterD()));
350             writer.write(packNibbles(instruction.getRegisterE(), instruction.getRegisterF()));
351         } catch (IOException ex) {
352             throw new RuntimeException(ex);
353         }
354     }
355 
write(@onnull Instruction35mi instruction)356     public void write(@Nonnull Instruction35mi instruction) {
357         try {
358             writer.write(getOpcodeValue(instruction.getOpcode()));
359             writer.write(packNibbles(instruction.getRegisterG(), instruction.getRegisterCount()));
360             writer.writeUshort(instruction.getInlineIndex());
361             writer.write(packNibbles(instruction.getRegisterC(), instruction.getRegisterD()));
362             writer.write(packNibbles(instruction.getRegisterE(), instruction.getRegisterF()));
363         } catch (IOException ex) {
364             throw new RuntimeException(ex);
365         }
366     }
367 
write(@onnull Instruction35ms instruction)368     public void write(@Nonnull Instruction35ms instruction) {
369         try {
370             writer.write(getOpcodeValue(instruction.getOpcode()));
371             writer.write(packNibbles(instruction.getRegisterG(), instruction.getRegisterCount()));
372             writer.writeUshort(instruction.getVtableIndex());
373             writer.write(packNibbles(instruction.getRegisterC(), instruction.getRegisterD()));
374             writer.write(packNibbles(instruction.getRegisterE(), instruction.getRegisterF()));
375         } catch (IOException ex) {
376             throw new RuntimeException(ex);
377         }
378     }
379 
write(@onnull Instruction3rc instruction)380     public void write(@Nonnull Instruction3rc instruction) {
381         try {
382             writer.write(getOpcodeValue(instruction.getOpcode()));
383             writer.write(instruction.getRegisterCount());
384             writer.writeUshort(getReferenceIndex(instruction));
385             writer.writeUshort(instruction.getStartRegister());
386         } catch (IOException ex) {
387             throw new RuntimeException(ex);
388         }
389     }
390 
write(@onnull Instruction3rmi instruction)391     public void write(@Nonnull Instruction3rmi instruction) {
392         try {
393             writer.write(getOpcodeValue(instruction.getOpcode()));
394             writer.write(instruction.getRegisterCount());
395             writer.writeUshort(instruction.getInlineIndex());
396             writer.writeUshort(instruction.getStartRegister());
397         } catch (IOException ex) {
398             throw new RuntimeException(ex);
399         }
400     }
401 
402 
write(@onnull Instruction3rms instruction)403     public void write(@Nonnull Instruction3rms instruction) {
404         try {
405             writer.write(getOpcodeValue(instruction.getOpcode()));
406             writer.write(instruction.getRegisterCount());
407             writer.writeUshort(instruction.getVtableIndex());
408             writer.writeUshort(instruction.getStartRegister());
409         } catch (IOException ex) {
410             throw new RuntimeException(ex);
411         }
412     }
413 
write(@onnull Instruction45cc instruction)414     public void write(@Nonnull Instruction45cc instruction) {
415         try {
416             writer.write(getOpcodeValue(instruction.getOpcode()));
417             writer.write(packNibbles(instruction.getRegisterG(), instruction.getRegisterCount()));
418             writer.writeUshort(getReferenceIndex(instruction));
419             writer.write(packNibbles(instruction.getRegisterC(), instruction.getRegisterD()));
420             writer.write(packNibbles(instruction.getRegisterE(), instruction.getRegisterF()));
421             writer.writeUshort(getReference2Index(instruction));
422         } catch (IOException ex) {
423             throw new RuntimeException(ex);
424         }
425     }
426 
write(@onnull Instruction4rcc instruction)427     public void write(@Nonnull Instruction4rcc instruction) {
428         try {
429             writer.write(getOpcodeValue(instruction.getOpcode()));
430             writer.write(instruction.getRegisterCount());
431             writer.writeUshort(getReferenceIndex(instruction));
432             writer.writeUshort(instruction.getStartRegister());
433             writer.writeUshort(getReference2Index(instruction));
434         } catch (IOException ex) {
435             throw new RuntimeException(ex);
436         }
437     }
438 
write(@onnull Instruction51l instruction)439     public void write(@Nonnull Instruction51l instruction) {
440         try {
441             writer.write(getOpcodeValue(instruction.getOpcode()));
442             writer.write(instruction.getRegisterA());
443             writer.writeLong(instruction.getWideLiteral());
444         } catch (IOException ex) {
445             throw new RuntimeException(ex);
446         }
447     }
448 
write(@onnull ArrayPayload instruction)449     public void write(@Nonnull ArrayPayload instruction) {
450         try {
451             writer.writeUshort(getOpcodeValue(instruction.getOpcode()));
452             writer.writeUshort(instruction.getElementWidth());
453             List<Number> elements = instruction.getArrayElements();
454             writer.writeInt(elements.size());
455             switch (instruction.getElementWidth()) {
456                 case 1:
457                     for (Number element: elements) {
458                         writer.write(element.byteValue());
459                     }
460                     break;
461                 case 2:
462                     for (Number element: elements) {
463                         writer.writeShort(element.shortValue());
464                     }
465                     break;
466                 case 4:
467                     for (Number element: elements) {
468                         writer.writeInt(element.intValue());
469                     }
470                     break;
471                 case 8:
472                     for (Number element: elements) {
473                         writer.writeLong(element.longValue());
474                     }
475                     break;
476             }
477             if ((writer.getPosition() & 1) != 0) {
478                 writer.write(0);
479             }
480         } catch (IOException ex) {
481             throw new RuntimeException(ex);
482         }
483     }
484 
write(@onnull SparseSwitchPayload instruction)485     public void write(@Nonnull SparseSwitchPayload instruction) {
486         try {
487             writer.writeUbyte(0);
488             writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8);
489             List<? extends SwitchElement> elements = Ordering.from(switchElementComparator).immutableSortedCopy(
490                     instruction.getSwitchElements());
491             writer.writeUshort(elements.size());
492             for (SwitchElement element: elements) {
493                 writer.writeInt(element.getKey());
494             }
495             for (SwitchElement element: elements) {
496                 writer.writeInt(element.getOffset());
497             }
498         } catch (IOException ex) {
499             throw new RuntimeException(ex);
500         }
501     }
502 
503     private final Comparator<SwitchElement> switchElementComparator = new Comparator<SwitchElement>() {
504         @Override public int compare(SwitchElement element1, SwitchElement element2) {
505             return Ints.compare(element1.getKey(), element2.getKey());
506         }
507     };
508 
write(@onnull PackedSwitchPayload instruction)509     public void write(@Nonnull PackedSwitchPayload instruction) {
510         try {
511             writer.writeUbyte(0);
512             writer.writeUbyte(getOpcodeValue(instruction.getOpcode()) >> 8);
513             List<? extends SwitchElement> elements = instruction.getSwitchElements();
514             writer.writeUshort(elements.size());
515             if (elements.size() == 0) {
516                 writer.writeInt(0);
517             } else {
518                 writer.writeInt(elements.get(0).getKey());
519                 for (SwitchElement element: elements) {
520                     writer.writeInt(element.getOffset());
521                 }
522             }
523         } catch (IOException ex) {
524             throw new RuntimeException(ex);
525         }
526     }
527 
packNibbles(int a, int b)528     private static int packNibbles(int a, int b) {
529         return (b << 4) | a;
530     }
531 
getReferenceIndex(ReferenceInstruction referenceInstruction)532     private int getReferenceIndex(ReferenceInstruction referenceInstruction) {
533         return getReferenceIndex(referenceInstruction.getReferenceType(),
534                 referenceInstruction.getReference());
535     }
536 
getReference2Index(DualReferenceInstruction referenceInstruction)537     private int getReference2Index(DualReferenceInstruction referenceInstruction) {
538         return getReferenceIndex(referenceInstruction.getReferenceType2(),
539                 referenceInstruction.getReference2());
540     }
541 
getReferenceIndex(int referenceType, Reference reference)542     private int getReferenceIndex(int referenceType, Reference reference) {
543         switch (referenceType) {
544             case ReferenceType.FIELD:
545                 return fieldSection.getItemIndex((FieldRefKey) reference);
546             case ReferenceType.METHOD:
547                 return methodSection.getItemIndex((MethodRefKey) reference);
548             case ReferenceType.STRING:
549                 return stringSection.getItemIndex((StringRef) reference);
550             case ReferenceType.TYPE:
551                 return typeSection.getItemIndex((TypeRef) reference);
552             case ReferenceType.METHOD_PROTO:
553                 return protoSection.getItemIndex((ProtoRefKey) reference);
554             default:
555                 throw new ExceptionWithContext("Unknown reference type: %d",  referenceType);
556         }
557     }
558 }
559