blob: e0cf42e395f92389c0edc05d9f2b6012e9aa6161 [file] [log] [blame]
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +09001// Copyright 2001,2007 Alan Donovan. All rights reserved.
2//
3// Author: Alan Donovan <adonovan@google.com>
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16//
17// classfile.cc -- classfile parsing and stripping.
18//
19
20// TODO(adonovan) don't pass pointers by reference; this is not
21// compatible with Google C++ style.
22
23// See README.txt for details.
24//
25// For definition of JVM class file format, see:
26// Java SE 8 Edition:
27// http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4
28
29#define __STDC_FORMAT_MACROS 1
30#define __STDC_LIMIT_MACROS 1
31#include <inttypes.h> // for PRIx32
32#include <stddef.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36
37#include <set>
38#include <string>
39#include <vector>
40
41#include "common.h"
42
43namespace devtools_ijar {
44
45// See Table 4.3 in JVM Spec.
46enum CONSTANT {
47 CONSTANT_Class = 7,
48 CONSTANT_FieldRef = 9,
49 CONSTANT_Methodref = 10,
50 CONSTANT_Interfacemethodref = 11,
51 CONSTANT_String = 8,
52 CONSTANT_Integer = 3,
53 CONSTANT_Float = 4,
54 CONSTANT_Long = 5,
55 CONSTANT_Double = 6,
56 CONSTANT_NameAndType = 12,
57 CONSTANT_Utf8 = 1,
58 CONSTANT_MethodHandle = 15,
59 CONSTANT_MethodType = 16,
60 CONSTANT_InvokeDynamic = 18
61};
62
63// See Tables 4.1, 4.4, 4.5 in JVM Spec.
64enum ACCESS {
65 ACC_PUBLIC = 0x0001,
66 ACC_PRIVATE = 0x0002,
67 ACC_PROTECTED = 0x0004,
68 ACC_STATIC = 0x0008,
69 ACC_FINAL = 0x0010,
70 ACC_SYNCHRONIZED = 0x0020,
71 ACC_VOLATILE = 0x0040,
72 ACC_TRANSIENT = 0x0080,
73 ACC_INTERFACE = 0x0200,
74 ACC_ABSTRACT = 0x0400
75};
76
77// See Table 4.7.20-A in Java 8 JVM Spec.
78enum TARGET_TYPE {
79 // Targets for type parameter declarations (ElementType.TYPE_PARAMETER):
80 CLASS_TYPE_PARAMETER = 0x00,
81 METHOD_TYPE_PARAMETER = 0x01,
82
83 // Targets for type uses that may be externally visible in classes and members
84 // (ElementType.TYPE_USE):
85 CLASS_EXTENDS = 0x10,
86 CLASS_TYPE_PARAMETER_BOUND = 0x11,
87 METHOD_TYPE_PARAMETER_BOUND = 0x12,
88 FIELD = 0x13,
89 METHOD_RETURN = 0x14,
90 METHOD_RECEIVER = 0x15,
91 METHOD_FORMAL_PARAMETER = 0x16,
92 THROWS = 0x17,
93
94 // TARGET_TYPE >= 0x40 is reserved for type uses that occur only within code
95 // blocks. Ijar doesn't need to know about these.
96};
97
98struct Constant;
99
100// TODO(adonovan) these globals are unfortunate
101static std::vector<Constant*> const_pool_in; // input constant pool
102static std::vector<Constant*> const_pool_out; // output constant_pool
103static std::set<std::string> used_class_names;
104static Constant * class_name;
105
106// Returns the Constant object, given an index into the input constant pool.
107// Note: constant(0) == NULL; this invariant is exploited by the
108// InnerClassesAttribute, inter alia.
109inline Constant *constant(int idx) {
110 if (idx < 0 || (unsigned)idx >= const_pool_in.size()) {
111 fprintf(stderr, "Illegal constant pool index: %d\n", idx);
112 abort();
113 }
114 return const_pool_in[idx];
115}
116
117/**********************************************************************
118 * *
119 * Constants *
120 * *
121 **********************************************************************/
122
123// See sec.4.4 of JVM spec.
124struct Constant {
125
126 Constant(u1 tag) :
127 slot_(0),
128 tag_(tag) {}
129
130 virtual ~Constant() {}
131
132 // For UTF-8 string constants, returns the encoded string.
133 // Otherwise, returns an undefined string value suitable for debugging.
134 virtual std::string Display() = 0;
135
136 virtual void Write(u1 *&p) = 0;
137
138 // Called by slot() when a constant has been identified as required
139 // in the output classfile's constant pool. This is a hook allowing
140 // constants to register their dependency on other constants, by
141 // calling slot() on them in turn.
142 virtual void Keep() {}
143
144 bool Kept() {
145 return slot_ != 0;
146 }
147
148 // Returns the index of this constant in the output class's constant
149 // pool, assigning a slot if not already done.
150 u2 slot() {
151 if (slot_ == 0) {
152 Keep();
153 slot_ = const_pool_out.size(); // BugBot's "narrowing" warning
154 // is bogus. The number of
155 // output constants can't exceed
156 // the number of input constants.
157 if (slot_ == 0) {
158 fprintf(stderr, "Constant::slot() called before output phase.\n");
159 abort();
160 }
161 const_pool_out.push_back(this);
162 if (tag_ == CONSTANT_Long || tag_ == CONSTANT_Double) {
163 const_pool_out.push_back(NULL);
164 }
165 }
166 return slot_;
167 }
168
169 u2 slot_; // zero => "this constant is unreachable garbage"
170 u1 tag_;
171};
172
173// Extracts class names from a signature and puts them into the global
174// variable used_class_names.
175//
176// desc: the descriptor class names should be extracted from.
177// p: the position where the extraction should tart.
178void ExtractClassNames(const std::string& desc, size_t* p);
179
180// See sec.4.4.1 of JVM spec.
181struct Constant_Class : Constant
182{
183 Constant_Class(u2 name_index) :
184 Constant(CONSTANT_Class),
185 name_index_(name_index) {}
186
187 void Write(u1 *&p) {
188 put_u1(p, tag_);
189 put_u2be(p, constant(name_index_)->slot());
190 }
191
192 std::string Display() {
193 return constant(name_index_)->Display();
194 }
195
196 void Keep() { constant(name_index_)->slot(); }
197
198 u2 name_index_;
199};
200
201// See sec.4.4.2 of JVM spec.
202struct Constant_FMIref : Constant
203{
204 Constant_FMIref(u1 tag,
205 u2 class_index,
206 u2 name_type_index) :
207 Constant(tag),
208 class_index_(class_index),
209 name_type_index_(name_type_index) {}
210
211 void Write(u1 *&p) {
212 put_u1(p, tag_);
213 put_u2be(p, constant(class_index_)->slot());
214 put_u2be(p, constant(name_type_index_)->slot());
215 }
216
217 std::string Display() {
218 return constant(class_index_)->Display() + "::" +
219 constant(name_type_index_)->Display();
220 }
221
222 void Keep() {
223 constant(class_index_)->slot();
224 constant(name_type_index_)->slot();
225 }
226
227 u2 class_index_;
228 u2 name_type_index_;
229};
230
231// See sec.4.4.3 of JVM spec.
232struct Constant_String : Constant
233{
234 Constant_String(u2 string_index) :
235 Constant(CONSTANT_String),
236 string_index_(string_index) {}
237
238 void Write(u1 *&p) {
239 put_u1(p, tag_);
240 put_u2be(p, constant(string_index_)->slot());
241 }
242
243 std::string Display() {
244 return "\"" + constant(string_index_)->Display() + "\"";
245 }
246
247 void Keep() { constant(string_index_)->slot(); }
248
249 u2 string_index_;
250};
251
252// See sec.4.4.4 of JVM spec.
253struct Constant_IntegerOrFloat : Constant
254{
255 Constant_IntegerOrFloat(u1 tag, u4 bytes) :
256 Constant(tag),
257 bytes_(bytes) {}
258
259 void Write(u1 *&p) {
260 put_u1(p, tag_);
261 put_u4be(p, bytes_);
262 }
263
264 std::string Display() { return "int/float"; }
265
266 u4 bytes_;
267};
268
269// See sec.4.4.5 of JVM spec.
270struct Constant_LongOrDouble : Constant_IntegerOrFloat
271{
272 Constant_LongOrDouble(u1 tag, u4 high_bytes, u4 low_bytes) :
273 Constant_IntegerOrFloat(tag, high_bytes),
274 low_bytes_(low_bytes) {}
275
276 void Write(u1 *&p) {
277 put_u1(p, tag_);
278 put_u4be(p, bytes_);
279 put_u4be(p, low_bytes_);
280 }
281
282 std::string Display() { return "long/double"; }
283
284 u4 low_bytes_;
285};
286
287// See sec.4.4.6 of JVM spec.
288struct Constant_NameAndType : Constant
289{
290 Constant_NameAndType(u2 name_index, u2 descr_index) :
291 Constant(CONSTANT_NameAndType),
292 name_index_(name_index),
293 descr_index_(descr_index) {}
294
295 void Write(u1 *&p) {
296 put_u1(p, tag_);
297 put_u2be(p, constant(name_index_)->slot());
298 put_u2be(p, constant(descr_index_)->slot());
299 }
300
301 std::string Display() {
302 return constant(name_index_)->Display() + "::" +
303 constant(descr_index_)->Display();
304 }
305
306 void Keep() {
307 constant(name_index_)->slot();
308 constant(descr_index_)->slot();
309 }
310
311 u2 name_index_;
312 u2 descr_index_;
313};
314
315// See sec.4.4.7 of JVM spec.
316struct Constant_Utf8 : Constant
317{
318 Constant_Utf8(u4 length, const u1 *utf8) :
319 Constant(CONSTANT_Utf8),
320 length_(length),
321 utf8_(utf8) {}
322
323 void Write(u1 *&p) {
324 put_u1(p, tag_);
325 put_u2be(p, length_);
326 put_n(p, utf8_, length_);
327 }
328
329 std::string Display() {
330 return std::string((const char*) utf8_, length_);
331 }
332
333 u4 length_;
334 const u1 *utf8_;
335};
336
337// See sec.4.4.8 of JVM spec.
338struct Constant_MethodHandle : Constant
339{
340 Constant_MethodHandle(u1 reference_kind, u2 reference_index) :
341 Constant(CONSTANT_MethodHandle),
342 reference_kind_(reference_kind),
343 reference_index_(reference_index) {}
344
345 void Write(u1 *&p) {
346 put_u1(p, tag_);
347 put_u1(p, reference_kind_);
348 put_u2be(p, reference_index_);
349 }
350
351 std::string Display() {
352 return "Constant_MethodHandle::" + std::to_string(reference_kind_) + "::"
353 + constant(reference_index_)->Display();
354 }
355
356 u1 reference_kind_;
357 u2 reference_index_;
358};
359
360// See sec.4.4.9 of JVM spec.
361struct Constant_MethodType : Constant
362{
363 Constant_MethodType(u2 descriptor_index) :
364 Constant(CONSTANT_MethodType),
365 descriptor_index_(descriptor_index) {}
366
367 void Write(u1 *&p) {
368 put_u1(p, tag_);
369 put_u2be(p, descriptor_index_);
370 }
371
372 std::string Display() {
373 return "Constant_MethodType::" + constant(descriptor_index_)->Display();
374 }
375
376 u2 descriptor_index_;
377};
378
379// See sec.4.4.10 of JVM spec.
380struct Constant_InvokeDynamic : Constant
381{
382 Constant_InvokeDynamic(u2 bootstrap_method_attr_index, u2 name_and_type_index) :
383 Constant(CONSTANT_InvokeDynamic),
384 bootstrap_method_attr_index_(bootstrap_method_attr_index),
385 name_and_type_index_(name_and_type_index) {}
386
387 void Write(u1 *&p) {
388 put_u1(p, tag_);
389 put_u2be(p, bootstrap_method_attr_index_);
390 put_u2be(p, name_and_type_index_);
391 }
392
393 std::string Display() {
394 return "Constant_InvokeDynamic::"
395 + std::to_string(bootstrap_method_attr_index_) + "::"
396 + constant(name_and_type_index_)->Display();
397 }
398
399 u2 bootstrap_method_attr_index_;
400 u2 name_and_type_index_;
401};
402
403/**********************************************************************
404 * *
405 * Attributes *
406 * *
407 **********************************************************************/
408
409// See sec.4.7 of JVM spec.
410struct Attribute {
411
412 virtual ~Attribute() {}
413 virtual void Write(u1 *&p) = 0;
414 virtual void ExtractClassNames() {}
415
416 void WriteProlog(u1 *&p, u2 length) {
417 put_u2be(p, attribute_name_->slot());
418 put_u4be(p, length);
419 }
420
421 Constant *attribute_name_;
422};
423
424// See sec.4.7.5 of JVM spec.
425struct ExceptionsAttribute : Attribute {
426
427 static ExceptionsAttribute* Read(const u1 *&p, Constant *attribute_name) {
428 ExceptionsAttribute *attr = new ExceptionsAttribute;
429 attr->attribute_name_ = attribute_name;
430 u2 number_of_exceptions = get_u2be(p);
431 for (int ii = 0; ii < number_of_exceptions; ++ii) {
432 attr->exceptions_.push_back(constant(get_u2be(p)));
433 }
434 return attr;
435 }
436
437 void Write(u1 *&p) {
438 WriteProlog(p, exceptions_.size() * 2 + 2);
439 put_u2be(p, exceptions_.size());
440 for (size_t ii = 0; ii < exceptions_.size(); ++ii) {
441 put_u2be(p, exceptions_[ii]->slot());
442 }
443 }
444
445 std::vector<Constant*> exceptions_;
446};
447
448// See sec.4.7.6 of JVM spec.
449struct InnerClassesAttribute : Attribute {
450
451 struct Entry {
452 Constant *inner_class_info;
453 Constant *outer_class_info;
454 Constant *inner_name;
455 u2 inner_class_access_flags;
456 };
457
458 virtual ~InnerClassesAttribute() {
459 for (size_t i = 0; i < entries_.size(); i++) {
460 delete entries_[i];
461 }
462 }
463
464 static InnerClassesAttribute* Read(const u1 *&p, Constant *attribute_name) {
465 InnerClassesAttribute *attr = new InnerClassesAttribute;
466 attr->attribute_name_ = attribute_name;
467
468 u2 number_of_classes = get_u2be(p);
469 for (int ii = 0; ii < number_of_classes; ++ii) {
470 Entry *entry = new Entry;
471 entry->inner_class_info = constant(get_u2be(p));
472 entry->outer_class_info = constant(get_u2be(p));
473 entry->inner_name = constant(get_u2be(p));
474 entry->inner_class_access_flags = get_u2be(p);
475
476 attr->entries_.push_back(entry);
477 }
478 return attr;
479 }
480
481 void Write(u1 *&p) {
482 std::set<int> kept_entries;
483 // We keep an entry if the constant referring to the inner class is already
484 // kept. Then we mark its outer class and its class name as kept, too, then
485 // iterate until a fixed point is reached.
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +0900486 size_t entry_count;
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +0900487 int iteration = 0;
488
489 do {
490 entry_count = kept_entries.size();
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +0900491 for (size_t i_entry = 0; i_entry < entries_.size(); ++i_entry) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +0900492 Entry* entry = entries_[i_entry];
493 if (entry->inner_class_info->Kept() ||
494 used_class_names.find(entry->inner_class_info->Display())
495 != used_class_names.end() ||
496 entry->outer_class_info == class_name ||
497 entry->outer_class_info == NULL ||
498 entry->inner_name == NULL) {
499 kept_entries.insert(i_entry);
500
501 // These are zero for anonymous inner classes
502 if (entry->outer_class_info != NULL) {
503 entry->outer_class_info->slot();
504 }
505
506 if (entry->inner_name != NULL) {
507 entry->inner_name->slot();
508 }
509 }
510 }
511 iteration += 1;
512 } while (entry_count != kept_entries.size());
513
514 if (kept_entries.size() == 0) {
515 return;
516 }
517
518 WriteProlog(p, 2 + kept_entries.size() * 8);
519 put_u2be(p, kept_entries.size());
520
521 for (std::set<int>::iterator it = kept_entries.begin();
522 it != kept_entries.end();
523 ++it) {
524 Entry *entry = entries_[*it];
525 put_u2be(p, entry->inner_class_info == NULL
526 ? 0
527 : entry->inner_class_info->slot());
528 put_u2be(p, entry->outer_class_info == NULL
529 ? 0
530 : entry->outer_class_info->slot());
531 put_u2be(p, entry->inner_name == NULL
532 ? 0
533 : entry->inner_name->slot());
534 put_u2be(p, entry->inner_class_access_flags);
535 }
536 }
537
538 std::vector<Entry*> entries_;
539};
540
541// See sec.4.7.7 of JVM spec.
542// We preserve EnclosingMethod attributes to be able to identify local and
543// anonymous classes. These classes will be stripped of most content, as they
544// represent implementation details that shoudn't leak into the ijars. Omitting
545// EnclosingMethod attributes can lead to type-checking failures in the presence
546// of generics (see b/9070939).
547struct EnclosingMethodAttribute : Attribute {
548
549 static EnclosingMethodAttribute* Read(const u1 *&p,
550 Constant *attribute_name) {
551 EnclosingMethodAttribute *attr = new EnclosingMethodAttribute;
552 attr->attribute_name_ = attribute_name;
553 attr->class_ = constant(get_u2be(p));
554 attr->method_ = constant(get_u2be(p));
555 return attr;
556 }
557
558 void Write(u1 *&p) {
559 WriteProlog(p, 4);
560 put_u2be(p, class_->slot());
561 put_u2be(p, method_ == NULL ? 0 : method_->slot());
562 }
563
564 Constant *class_;
565 Constant *method_;
566};
567
568// See sec.4.7.16.1 of JVM spec.
569// Used by AnnotationDefault and other attributes.
570struct ElementValue {
571 virtual ~ElementValue() {}
572 virtual void Write(u1 *&p) = 0;
573 virtual void ExtractClassNames() {}
574 static ElementValue* Read(const u1 *&p);
575 u1 tag_;
576 u4 length_;
577};
578
579struct BaseTypeElementValue : ElementValue {
580 void Write(u1 *&p) {
581 put_u1(p, tag_);
582 put_u2be(p, const_value_->slot());
583 }
584 static BaseTypeElementValue *Read(const u1 *&p) {
585 BaseTypeElementValue *value = new BaseTypeElementValue;
586 value->const_value_ = constant(get_u2be(p));
587 return value;
588 }
589 Constant *const_value_;
590};
591
592struct EnumTypeElementValue : ElementValue {
593 void Write(u1 *&p) {
594 put_u1(p, tag_);
595 put_u2be(p, type_name_->slot());
596 put_u2be(p, const_name_->slot());
597 }
598 static EnumTypeElementValue *Read(const u1 *&p) {
599 EnumTypeElementValue *value = new EnumTypeElementValue;
600 value->type_name_ = constant(get_u2be(p));
601 value->const_name_ = constant(get_u2be(p));
602 return value;
603 }
604 Constant *type_name_;
605 Constant *const_name_;
606};
607
608struct ClassTypeElementValue : ElementValue {
609 void Write(u1 *&p) {
610 put_u1(p, tag_);
611 put_u2be(p, class_info_->slot());
612 }
613
614 virtual void ExtractClassNames() {
615 size_t idx = 0;
616 devtools_ijar::ExtractClassNames(class_info_->Display(), &idx);
617 }
618
619 static ClassTypeElementValue *Read(const u1 *&p) {
620 ClassTypeElementValue *value = new ClassTypeElementValue;
621 value->class_info_ = constant(get_u2be(p));
622 return value;
623 }
624 Constant *class_info_;
625};
626
627struct ArrayTypeElementValue : ElementValue {
628 virtual ~ArrayTypeElementValue() {
629 for (size_t i = 0; i < values_.size(); i++) {
630 delete values_[i];
631 }
632 }
633
634 virtual void ExtractClassNames() {
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +0900635 for (size_t i = 0; i < values_.size(); i++) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +0900636 values_[i]->ExtractClassNames();
637 }
638 }
639
640 void Write(u1 *&p) {
641 put_u1(p, tag_);
642 put_u2be(p, values_.size());
643 for (size_t ii = 0; ii < values_.size(); ++ii) {
644 values_[ii]->Write(p);
645 }
646 }
647 static ArrayTypeElementValue *Read(const u1 *&p) {
648 ArrayTypeElementValue *value = new ArrayTypeElementValue;
649 u2 num_values = get_u2be(p);
650 for (int ii = 0; ii < num_values; ++ii) {
651 value->values_.push_back(ElementValue::Read(p));
652 }
653 return value;
654 }
655 std::vector<ElementValue*> values_;
656};
657
658// See sec.4.7.16 of JVM spec.
659struct Annotation {
660 virtual ~Annotation() {
661 for (size_t i = 0; i < element_value_pairs_.size(); i++) {
662 delete element_value_pairs_[i]->element_value_;
663 delete element_value_pairs_[i];
664 }
665 }
666
667 void ExtractClassNames() {
668 for (size_t i = 0; i < element_value_pairs_.size(); i++) {
669 element_value_pairs_[i]->element_value_->ExtractClassNames();
670 }
671 }
672
673 void Write(u1 *&p) {
674 put_u2be(p, type_->slot());
675 put_u2be(p, element_value_pairs_.size());
676 for (size_t ii = 0; ii < element_value_pairs_.size(); ++ii) {
677 put_u2be(p, element_value_pairs_[ii]->element_name_->slot());
678 element_value_pairs_[ii]->element_value_->Write(p);
679 }
680 }
681 static Annotation *Read(const u1 *&p) {
682 Annotation *value = new Annotation;
683 value->type_ = constant(get_u2be(p));
684 u2 num_element_value_pairs = get_u2be(p);
685 for (int ii = 0; ii < num_element_value_pairs; ++ii) {
686 ElementValuePair *pair = new ElementValuePair;
687 pair->element_name_ = constant(get_u2be(p));
688 pair->element_value_ = ElementValue::Read(p);
689 value->element_value_pairs_.push_back(pair);
690 }
691 return value;
692 }
693 Constant *type_;
694 struct ElementValuePair {
695 Constant *element_name_;
696 ElementValue *element_value_;
697 };
698 std::vector<ElementValuePair*> element_value_pairs_;
699};
700
701// See sec 4.7.20 of Java 8 JVM Spec
702//
703// Each entry in the annotations table represents a single run-time visible
704// annotation on a type used in a declaration or expression. The type_annotation
705// structure has the following format:
706//
707// type_annotation {
708// u1 target_type;
709// union {
710// type_parameter_target;
711// supertype_target;
712// type_parameter_bound_target;
713// empty_target;
714// method_formal_parameter_target;
715// throws_target;
716// localvar_target;
717// catch_target;
718// offset_target;
719// type_argument_target;
720// } target_info;
721// type_path target_path;
722// u2 type_index;
723// u2 num_element_value_pairs;
724// {
725// u2 element_name_index;
726// element_value value;
727// }
728// element_value_pairs[num_element_value_pairs];
729// }
730//
731struct TypeAnnotation {
732 virtual ~TypeAnnotation() {
733 delete target_info_;
734 delete type_path_;
735 delete annotation_;
736 }
737
738 void ExtractClassNames() {
739 annotation_->ExtractClassNames();
740 }
741
742 void Write(u1 *&p) {
743 put_u1(p, target_type_);
744 target_info_->Write(p);
745 type_path_->Write(p);
746 annotation_->Write(p);
747 }
748
749 static TypeAnnotation *Read(const u1 *&p) {
750 TypeAnnotation *value = new TypeAnnotation;
751 value->target_type_ = get_u1(p);
752 value->target_info_ = ReadTargetInfo(p, value->target_type_);
753 value->type_path_ = TypePath::Read(p);
754 value->annotation_ = Annotation::Read(p);
755 return value;
756 }
757
758 struct TargetInfo {
759 virtual ~TargetInfo() {}
760 virtual void Write(u1 *&p) = 0;
761 };
762
763 struct TypeParameterTargetInfo : TargetInfo {
764 void Write(u1 *&p) {
765 put_u1(p, type_parameter_index_);
766 }
767 static TypeParameterTargetInfo *Read(const u1 *&p) {
768 TypeParameterTargetInfo *value = new TypeParameterTargetInfo;
769 value->type_parameter_index_ = get_u1(p);
770 return value;
771 }
772 u1 type_parameter_index_;
773 };
774
775 struct ClassExtendsInfo : TargetInfo {
776 void Write(u1 *&p) {
777 put_u2be(p, supertype_index_);
778 }
779 static ClassExtendsInfo *Read(const u1 *&p) {
780 ClassExtendsInfo *value = new ClassExtendsInfo;
781 value->supertype_index_ = get_u2be(p);
782 return value;
783 }
784 u2 supertype_index_;
785 };
786
787 struct TypeParameterBoundInfo : TargetInfo {
788 void Write(u1 *&p) {
789 put_u1(p, type_parameter_index_);
790 put_u1(p, bound_index_);
791 }
792 static TypeParameterBoundInfo *Read(const u1 *&p) {
793 TypeParameterBoundInfo *value = new TypeParameterBoundInfo;
794 value->type_parameter_index_ = get_u1(p);
795 value->bound_index_ = get_u1(p);
796 return value;
797 }
798 u1 type_parameter_index_;
799 u1 bound_index_;
800 };
801
802 struct EmptyInfo : TargetInfo {
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +0900803 void Write(u1 *&) {}
804 static EmptyInfo *Read(const u1 *&) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +0900805 return new EmptyInfo;
806 }
807 };
808
809 struct MethodFormalParameterInfo : TargetInfo {
810 void Write(u1 *&p) {
811 put_u1(p, method_formal_parameter_index_);
812 }
813 static MethodFormalParameterInfo *Read(const u1 *&p) {
814 MethodFormalParameterInfo *value = new MethodFormalParameterInfo;
815 value->method_formal_parameter_index_ = get_u1(p);
816 return value;
817 }
818 u1 method_formal_parameter_index_;
819 };
820
821 struct ThrowsTypeInfo : TargetInfo {
822 void Write(u1 *&p) {
823 put_u2be(p, throws_type_index_);
824 }
825 static ThrowsTypeInfo *Read(const u1 *&p) {
826 ThrowsTypeInfo *value = new ThrowsTypeInfo;
827 value->throws_type_index_ = get_u2be(p);
828 return value;
829 }
830 u2 throws_type_index_;
831 };
832
833 static TargetInfo *ReadTargetInfo(const u1 *&p, u1 target_type) {
834 switch (target_type) {
835 case CLASS_TYPE_PARAMETER:
836 case METHOD_TYPE_PARAMETER:
837 return TypeParameterTargetInfo::Read(p);
838 case CLASS_EXTENDS:
839 return ClassExtendsInfo::Read(p);
840 case CLASS_TYPE_PARAMETER_BOUND:
841 case METHOD_TYPE_PARAMETER_BOUND:
842 return TypeParameterBoundInfo::Read(p);
843 case FIELD:
844 case METHOD_RETURN:
845 case METHOD_RECEIVER:
846 return new EmptyInfo;
847 case METHOD_FORMAL_PARAMETER:
848 return MethodFormalParameterInfo::Read(p);
849 case THROWS:
850 return ThrowsTypeInfo::Read(p);
851 default:
852 fprintf(stderr, "Illegal type annotation target type: %d\n",
853 target_type);
854 abort();
855 }
856 }
857
858 struct TypePath {
859 void Write(u1 *&p) {
860 put_u1(p, path_.size());
861 for (TypePathEntry entry : path_) {
862 put_u1(p, entry.type_path_kind_);
863 put_u1(p, entry.type_argument_index_);
864 }
865 }
866 static TypePath *Read(const u1 *&p) {
867 TypePath *value = new TypePath;
868 u1 path_length = get_u1(p);
869 for (int ii = 0; ii < path_length; ++ii) {
870 TypePathEntry entry;
871 entry.type_path_kind_ = get_u1(p);
872 entry.type_argument_index_ = get_u1(p);
873 value->path_.push_back(entry);
874 }
875 return value;
876 }
877
878 struct TypePathEntry {
879 u1 type_path_kind_;
880 u1 type_argument_index_;
881 };
882 std::vector<TypePathEntry> path_;
883 };
884
885 u1 target_type_;
886 TargetInfo *target_info_;
887 TypePath *type_path_;
888 Annotation *annotation_;
889};
890
891struct AnnotationTypeElementValue : ElementValue {
892 virtual ~AnnotationTypeElementValue() {
893 delete annotation_;
894 }
895
896 void Write(u1 *&p) {
897 put_u1(p, tag_);
898 annotation_->Write(p);
899 }
900 static AnnotationTypeElementValue *Read(const u1 *&p) {
901 AnnotationTypeElementValue *value = new AnnotationTypeElementValue;
902 value->annotation_ = Annotation::Read(p);
903 return value;
904 }
905
906 Annotation *annotation_;
907};
908
909ElementValue* ElementValue::Read(const u1 *&p) {
910 const u1* start = p;
911 ElementValue *result;
912 u1 tag = get_u1(p);
913 if (tag != 0 && strchr("BCDFIJSZs", (char) tag) != NULL) {
914 result = BaseTypeElementValue::Read(p);
915 } else if ((char) tag == 'e') {
916 result = EnumTypeElementValue::Read(p);
917 } else if ((char) tag == 'c') {
918 result = ClassTypeElementValue::Read(p);
919 } else if ((char) tag == '[') {
920 result = ArrayTypeElementValue::Read(p);
921 } else if ((char) tag == '@') {
922 result = AnnotationTypeElementValue::Read(p);
923 } else {
924 fprintf(stderr, "Illegal element_value::tag: %d\n", tag);
925 abort();
926 }
927 result->tag_ = tag;
928 result->length_ = p - start;
929 return result;
930}
931
932// See sec.4.7.20 of JVM spec.
933// We preserve AnnotationDefault attributes because they are required
934// in order to make use of an annotation in new code.
935struct AnnotationDefaultAttribute : Attribute {
936 virtual ~AnnotationDefaultAttribute() {
937 delete default_value_;
938 }
939
940 static AnnotationDefaultAttribute* Read(const u1 *&p,
941 Constant *attribute_name) {
942 AnnotationDefaultAttribute *attr = new AnnotationDefaultAttribute;
943 attr->attribute_name_ = attribute_name;
944 attr->default_value_ = ElementValue::Read(p);
945 return attr;
946 }
947
948 void Write(u1 *&p) {
949 WriteProlog(p, default_value_->length_);
950 default_value_->Write(p);
951 }
952
953 virtual void ExtractClassNames() {
954 default_value_->ExtractClassNames();
955 }
956
957 ElementValue *default_value_;
958};
959
960// See sec.4.7.2 of JVM spec.
961// We preserve ConstantValue attributes because they are required for
962// compile-time constant propagation.
963struct ConstantValueAttribute : Attribute {
964
965 static ConstantValueAttribute* Read(const u1 *&p, Constant *attribute_name) {
966 ConstantValueAttribute *attr = new ConstantValueAttribute;
967 attr->attribute_name_ = attribute_name;
968 attr->constantvalue_ = constant(get_u2be(p));
969 return attr;
970 }
971
972 void Write(u1 *&p) {
973 WriteProlog(p, 2);
974 put_u2be(p, constantvalue_->slot());
975 }
976
977 Constant *constantvalue_;
978};
979
980// See sec.4.7.9 of JVM spec.
981// We preserve Signature attributes because they are required by the
982// compiler for type-checking of generics.
983struct SignatureAttribute : Attribute {
984
985 static SignatureAttribute* Read(const u1 *&p, Constant *attribute_name) {
986 SignatureAttribute *attr = new SignatureAttribute;
987 attr->attribute_name_ = attribute_name;
988 attr->signature_ = constant(get_u2be(p));
989 return attr;
990 }
991
992 void Write(u1 *&p) {
993 WriteProlog(p, 2);
994 put_u2be(p, signature_->slot());
995 }
996
997 virtual void ExtractClassNames() {
998 size_t signature_idx = 0;
999 devtools_ijar::ExtractClassNames(signature_->Display(), &signature_idx);
1000 }
1001
1002 Constant *signature_;
1003};
1004
1005// See sec.4.7.15 of JVM spec.
1006// We preserve Deprecated attributes because they are required by the
1007// compiler to generate warning messages.
1008struct DeprecatedAttribute : Attribute {
1009
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +09001010 static DeprecatedAttribute* Read(const u1 *&, Constant *attribute_name) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +09001011 DeprecatedAttribute *attr = new DeprecatedAttribute;
1012 attr->attribute_name_ = attribute_name;
1013 return attr;
1014 }
1015
1016 void Write(u1 *&p) {
1017 WriteProlog(p, 0);
1018 }
1019};
1020
1021// See sec.4.7.16-17 of JVM spec v3. Includes RuntimeVisible and
1022// RuntimeInvisible.
1023//
1024// We preserve all annotations.
1025struct AnnotationsAttribute : Attribute {
1026 virtual ~AnnotationsAttribute() {
1027 for (size_t i = 0; i < annotations_.size(); i++) {
1028 delete annotations_[i];
1029 }
1030 }
1031
1032 static AnnotationsAttribute* Read(const u1 *&p, Constant *attribute_name) {
1033 AnnotationsAttribute *attr = new AnnotationsAttribute;
1034 attr->attribute_name_ = attribute_name;
1035 u2 num_annotations = get_u2be(p);
1036 for (int ii = 0; ii < num_annotations; ++ii) {
1037 Annotation *annotation = Annotation::Read(p);
1038 attr->annotations_.push_back(annotation);
1039 }
1040 return attr;
1041 }
1042
1043 virtual void ExtractClassNames() {
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +09001044 for (size_t i = 0; i < annotations_.size(); i++) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +09001045 annotations_[i]->ExtractClassNames();
1046 }
1047 }
1048
1049 void Write(u1 *&p) {
1050 WriteProlog(p, -1);
1051 u1 *payload_start = p - 4;
1052 put_u2be(p, annotations_.size());
1053 for (size_t ii = 0; ii < annotations_.size(); ++ii) {
1054 annotations_[ii]->Write(p);
1055 }
1056 put_u4be(payload_start, p - 4 - payload_start); // backpatch length
1057 }
1058
1059 std::vector<Annotation*> annotations_;
1060};
1061
1062// See sec.4.7.18-19 of JVM spec. Includes RuntimeVisible and
1063// RuntimeInvisible.
1064//
1065// We preserve all annotations.
1066struct ParameterAnnotationsAttribute : Attribute {
1067
1068 static ParameterAnnotationsAttribute* Read(const u1 *&p,
1069 Constant *attribute_name) {
1070 ParameterAnnotationsAttribute *attr = new ParameterAnnotationsAttribute;
1071 attr->attribute_name_ = attribute_name;
1072 u1 num_parameters = get_u1(p);
1073 for (int ii = 0; ii < num_parameters; ++ii) {
1074 std::vector<Annotation*> annotations;
1075 u2 num_annotations = get_u2be(p);
1076 for (int ii = 0; ii < num_annotations; ++ii) {
1077 Annotation *annotation = Annotation::Read(p);
1078 annotations.push_back(annotation);
1079 }
1080 attr->parameter_annotations_.push_back(annotations);
1081 }
1082 return attr;
1083 }
1084
1085 virtual void ExtractClassNames() {
1086 for (size_t i = 0; i < parameter_annotations_.size(); i++) {
1087 const std::vector<Annotation*>& annotations = parameter_annotations_[i];
1088 for (size_t j = 0; j < annotations.size(); j++) {
1089 annotations[j]->ExtractClassNames();
1090 }
1091 }
1092 }
1093
1094 void Write(u1 *&p) {
1095 WriteProlog(p, -1);
1096 u1 *payload_start = p - 4;
1097 put_u1(p, parameter_annotations_.size());
1098 for (size_t ii = 0; ii < parameter_annotations_.size(); ++ii) {
1099 std::vector<Annotation *> &annotations = parameter_annotations_[ii];
1100 put_u2be(p, annotations.size());
1101 for (size_t jj = 0; jj < annotations.size(); ++jj) {
1102 annotations[jj]->Write(p);
1103 }
1104 }
1105 put_u4be(payload_start, p - 4 - payload_start); // backpatch length
1106 }
1107
1108 std::vector<std::vector<Annotation*> > parameter_annotations_;
1109};
1110
1111// See sec.4.7.20 of Java 8 JVM spec. Includes RuntimeVisibleTypeAnnotations
1112// and RuntimeInvisibleTypeAnnotations.
1113struct TypeAnnotationsAttribute : Attribute {
1114 static TypeAnnotationsAttribute* Read(const u1 *&p, Constant *attribute_name,
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +09001115 u4) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +09001116 auto attr = new TypeAnnotationsAttribute;
1117 attr->attribute_name_ = attribute_name;
1118 u2 num_annotations = get_u2be(p);
1119 for (int ii = 0; ii < num_annotations; ++ii) {
1120 TypeAnnotation *annotation = TypeAnnotation::Read(p);
1121 attr->type_annotations_.push_back(annotation);
1122 }
1123 return attr;
1124 }
1125
1126 virtual void ExtractClassNames() {
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +09001127 for (size_t i = 0; i < type_annotations_.size(); i++) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +09001128 type_annotations_[i]->ExtractClassNames();
1129 }
1130 }
1131
1132 void Write(u1 *&p) {
1133 WriteProlog(p, -1);
1134 u1 *payload_start = p - 4;
1135 put_u2be(p, type_annotations_.size());
1136 for (TypeAnnotation *annotation : type_annotations_) {
1137 annotation->Write(p);
1138 }
1139 put_u4be(payload_start, p - 4 - payload_start); // backpatch length
1140 }
1141
1142 std::vector<TypeAnnotation*> type_annotations_;
1143};
1144
1145struct GeneralAttribute : Attribute {
1146 static GeneralAttribute* Read(const u1 *&p, Constant *attribute_name,
1147 u4 attribute_length) {
1148 auto attr = new GeneralAttribute;
1149 attr->attribute_name_ = attribute_name;
1150 attr->attribute_length_ = attribute_length;
1151 attr->attribute_content_ = p;
1152 p += attribute_length;
1153 return attr;
1154 }
1155
1156 void Write(u1 *&p) {
1157 WriteProlog(p, attribute_length_);
1158 put_n(p, attribute_content_, attribute_length_);
1159 }
1160
1161 u4 attribute_length_;
1162 const u1 *attribute_content_;
1163};
1164
1165/**********************************************************************
1166 * *
1167 * ClassFile *
1168 * *
1169 **********************************************************************/
1170
1171struct HasAttrs {
1172 std::vector<Attribute*> attributes;
1173
1174 void WriteAttrs(u1 *&p);
1175 void ReadAttrs(const u1 *&p);
1176
1177 virtual ~HasAttrs() {
1178 for (size_t i = 0; i < attributes.size(); i++) {
1179 delete attributes[i];
1180 }
1181 }
1182
1183 void ExtractClassNames() {
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +09001184 for (size_t i = 0; i < attributes.size(); i++) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +09001185 attributes[i]->ExtractClassNames();
1186 }
1187 }
1188};
1189
1190// A field or method.
1191// See sec.4.5 and 4.6 of JVM spec.
1192struct Member : HasAttrs {
1193 u2 access_flags;
1194 Constant *name;
1195 Constant *descriptor;
1196
1197 static Member* Read(const u1 *&p) {
1198 Member *m = new Member;
1199 m->access_flags = get_u2be(p);
1200 m->name = constant(get_u2be(p));
1201 m->descriptor = constant(get_u2be(p));
1202 m->ReadAttrs(p);
1203 return m;
1204 }
1205
1206 void Write(u1 *&p) {
1207 put_u2be(p, access_flags);
1208 put_u2be(p, name->slot());
1209 put_u2be(p, descriptor->slot());
1210 WriteAttrs(p);
1211 }
1212};
1213
1214// See sec.4.1 of JVM spec.
1215struct ClassFile : HasAttrs {
1216
1217 size_t length;
1218
1219 // Header:
1220 u4 magic;
1221 u2 major;
1222 u2 minor;
1223
1224 // Body:
1225 u2 access_flags;
1226 Constant *this_class;
1227 Constant *super_class;
1228 std::vector<Constant*> interfaces;
1229 std::vector<Member*> fields;
1230 std::vector<Member*> methods;
1231
1232 virtual ~ClassFile() {
1233 for (size_t i = 0; i < fields.size(); i++) {
1234 delete fields[i];
1235 }
1236
1237 for (size_t i = 0; i < methods.size(); i++) {
1238 delete methods[i];
1239 }
1240
1241 // Constants do not need to be deleted; they are owned by the constant pool.
1242 }
1243
1244 void WriteClass(u1 *&p);
1245
1246 bool ReadConstantPool(const u1 *&p);
1247
1248 void StripIfAnonymous();
1249
1250 void WriteHeader(u1 *&p) {
1251 put_u4be(p, magic);
1252 put_u2be(p, major);
1253 put_u2be(p, minor);
1254
1255 put_u2be(p, const_pool_out.size());
1256 for (u2 ii = 1; ii < const_pool_out.size(); ++ii) {
1257 if (const_pool_out[ii] != NULL) { // NB: NULLs appear after long/double.
1258 const_pool_out[ii]->Write(p);
1259 }
1260 }
1261 }
1262
1263 void WriteBody(u1 *&p) {
1264 put_u2be(p, access_flags);
1265 put_u2be(p, this_class->slot());
1266 put_u2be(p, super_class == NULL ? 0 : super_class->slot());
1267 put_u2be(p, interfaces.size());
1268 for (size_t ii = 0; ii < interfaces.size(); ++ii) {
1269 put_u2be(p, interfaces[ii]->slot());
1270 }
1271 put_u2be(p, fields.size());
1272 for (size_t ii = 0; ii < fields.size(); ++ii) {
1273 fields[ii]->Write(p);
1274 }
1275 put_u2be(p, methods.size());
1276 for (size_t ii = 0; ii < methods.size(); ++ii) {
1277 methods[ii]->Write(p);
1278 }
1279
1280 Attribute* inner_classes = NULL;
1281
1282 // Make the inner classes attribute the last, so that it can know which
1283 // constants were needed
1284 for (size_t ii = 0; ii < attributes.size(); ii++) {
1285 if (attributes[ii]->attribute_name_->Display() == "InnerClasses") {
1286 inner_classes = attributes[ii];
1287 attributes.erase(attributes.begin() + ii);
1288 break;
1289 }
1290 }
1291
1292 if (inner_classes != NULL) {
1293 attributes.push_back(inner_classes);
1294 }
1295
1296 WriteAttrs(p);
1297 }
1298
1299};
1300
1301void HasAttrs::ReadAttrs(const u1 *&p) {
1302 u2 attributes_count = get_u2be(p);
1303 for (int ii = 0; ii < attributes_count; ii++) {
1304 Constant *attribute_name = constant(get_u2be(p));
1305 u4 attribute_length = get_u4be(p);
1306
1307 std::string attr_name = attribute_name->Display();
1308 if (attr_name == "SourceFile" ||
1309 attr_name == "LineNumberTable" ||
1310 attr_name == "LocalVariableTable" ||
1311 attr_name == "LocalVariableTypeTable" ||
1312 attr_name == "Code" ||
1313 attr_name == "Synthetic" ||
1314 attr_name == "BootstrapMethods") {
1315 p += attribute_length; // drop these attributes
1316 } else if (attr_name == "Exceptions") {
1317 attributes.push_back(ExceptionsAttribute::Read(p, attribute_name));
1318 } else if (attr_name == "Signature") {
1319 attributes.push_back(SignatureAttribute::Read(p, attribute_name));
1320 } else if (attr_name == "Deprecated") {
1321 attributes.push_back(DeprecatedAttribute::Read(p, attribute_name));
1322 } else if (attr_name == "EnclosingMethod") {
1323 attributes.push_back(EnclosingMethodAttribute::Read(p, attribute_name));
1324 } else if (attr_name == "InnerClasses") {
1325 // TODO(bazel-team): omit private inner classes
1326 attributes.push_back(InnerClassesAttribute::Read(p, attribute_name));
1327 } else if (attr_name == "AnnotationDefault") {
1328 attributes.push_back(AnnotationDefaultAttribute::Read(p, attribute_name));
1329 } else if (attr_name == "ConstantValue") {
1330 attributes.push_back(ConstantValueAttribute::Read(p, attribute_name));
1331 } else if (attr_name == "RuntimeVisibleAnnotations" ||
1332 attr_name == "RuntimeInvisibleAnnotations") {
1333 attributes.push_back(AnnotationsAttribute::Read(p, attribute_name));
1334 } else if (attr_name == "RuntimeVisibleParameterAnnotations" ||
1335 attr_name == "RuntimeInvisibleParameterAnnotations") {
1336 attributes.push_back(
1337 ParameterAnnotationsAttribute::Read(p, attribute_name));
1338 } else if (attr_name == "Scala" ||
1339 attr_name == "ScalaSig" ||
1340 attr_name == "ScalaInlineInfo") {
1341 // These are opaque blobs, so can be handled with a general
1342 // attribute handler
1343 attributes.push_back(GeneralAttribute::Read(p, attribute_name,
1344 attribute_length));
1345 } else if (attr_name == "RuntimeVisibleTypeAnnotations" ||
1346 attr_name == "RuntimeInvisibleTypeAnnotations") {
1347 // JSR 308: annotations on types. JDK 7 has no use for these yet, but the
1348 // Checkers Framework relies on them.
1349 attributes.push_back(TypeAnnotationsAttribute::Read(p, attribute_name,
1350 attribute_length));
1351 } else {
1352 // Skip over unknown attributes with a warning. The JVM spec
1353 // says this is ok, so long as we handle the mandatory attributes.
1354 fprintf(stderr, "ijar: skipping unknown attribute: \"%s\".\n",
1355 attr_name.c_str());
1356 p += attribute_length;
1357 }
1358 }
1359}
1360
1361void HasAttrs::WriteAttrs(u1 *&p) {
1362 u1* p_size = p;
1363
1364 put_u2be(p, 0);
1365 int n_written_attrs = 0;
1366 for (size_t ii = 0; ii < attributes.size(); ii++) {
1367 u1* before = p;
1368 attributes[ii]->Write(p);
1369 if (p != before) {
1370 n_written_attrs++;
1371 }
1372 }
1373
1374 put_u2be(p_size, n_written_attrs);
1375}
1376
1377// See sec.4.4 of JVM spec.
1378bool ClassFile::ReadConstantPool(const u1 *&p) {
1379
1380 const_pool_in.clear();
1381 const_pool_in.push_back(NULL); // dummy first item
1382
1383 u2 cp_count = get_u2be(p);
1384 for (int ii = 1; ii < cp_count; ++ii) {
1385 u1 tag = get_u1(p);
1386
1387 if (devtools_ijar::verbose) {
1388 fprintf(stderr, "cp[%d/%d] = tag %d\n", ii, cp_count, tag);
1389 }
1390
1391 switch(tag) {
1392 case CONSTANT_Class: {
1393 u2 name_index = get_u2be(p);
1394 const_pool_in.push_back(new Constant_Class(name_index));
1395 break;
1396 }
1397 case CONSTANT_FieldRef:
1398 case CONSTANT_Methodref:
1399 case CONSTANT_Interfacemethodref: {
1400 u2 class_index = get_u2be(p);
1401 u2 nti = get_u2be(p);
1402 const_pool_in.push_back(new Constant_FMIref(tag, class_index, nti));
1403 break;
1404 }
1405 case CONSTANT_String: {
1406 u2 string_index = get_u2be(p);
1407 const_pool_in.push_back(new Constant_String(string_index));
1408 break;
1409 }
1410 case CONSTANT_NameAndType: {
1411 u2 name_index = get_u2be(p);
1412 u2 descriptor_index = get_u2be(p);
1413 const_pool_in.push_back(
1414 new Constant_NameAndType(name_index, descriptor_index));
1415 break;
1416 }
1417 case CONSTANT_Utf8: {
1418 u2 length = get_u2be(p);
1419 if (devtools_ijar::verbose) {
1420 fprintf(stderr, "Utf8: \"%s\" (%d)\n",
1421 std::string((const char*) p, length).c_str(), length);
1422 }
1423
1424 const_pool_in.push_back(new Constant_Utf8(length, p));
1425 p += length;
1426 break;
1427 }
1428 case CONSTANT_Integer:
1429 case CONSTANT_Float: {
1430 u4 bytes = get_u4be(p);
1431 const_pool_in.push_back(new Constant_IntegerOrFloat(tag, bytes));
1432 break;
1433 }
1434 case CONSTANT_Long:
1435 case CONSTANT_Double: {
1436 u4 high_bytes = get_u4be(p);
1437 u4 low_bytes = get_u4be(p);
1438 const_pool_in.push_back(
1439 new Constant_LongOrDouble(tag, high_bytes, low_bytes));
1440 // Longs and doubles occupy two constant pool slots.
1441 // ("In retrospect, making 8-byte constants take two "constant
1442 // pool entries was a poor choice." --JVM Spec.)
1443 const_pool_in.push_back(NULL);
1444 ii++;
1445 break;
1446 }
1447 case CONSTANT_MethodHandle: {
1448 u1 reference_kind = get_u1(p);
1449 u2 reference_index = get_u2be(p);
1450 const_pool_in.push_back(
1451 new Constant_MethodHandle(reference_kind, reference_index));
1452 break;
1453 }
1454 case CONSTANT_MethodType: {
1455 u2 descriptor_index = get_u2be(p);
1456 const_pool_in.push_back(new Constant_MethodType(descriptor_index));
1457 break;
1458 }
1459 case CONSTANT_InvokeDynamic: {
1460 u2 bootstrap_method_attr = get_u2be(p);
1461 u2 name_name_type_index = get_u2be(p);
1462 const_pool_in.push_back(new Constant_InvokeDynamic(
1463 bootstrap_method_attr, name_name_type_index));
1464 break;
1465 }
1466 default: {
1467 fprintf(stderr, "Unknown constant: %02x. Passing class through.\n",
1468 tag);
1469 return false;
1470 }
1471 }
1472 }
1473
1474 return true;
1475}
1476
1477// Anonymous inner classes are stripped to opaque classes that only extend
1478// Object. None of their methods or fields are accessible anyway.
1479void ClassFile::StripIfAnonymous() {
1480 int enclosing_index = -1;
1481 int inner_classes_index = -1;
1482
1483 for (size_t ii = 0; ii < attributes.size(); ++ii) {
1484 if (attributes[ii]->attribute_name_->Display() == "EnclosingMethod") {
1485 enclosing_index = ii;
1486 } else if (attributes[ii]->attribute_name_->Display() == "InnerClasses") {
1487 inner_classes_index = ii;
1488 }
1489 }
1490
1491 // Presence of an EnclosingMethod attribute indicates a local or anonymous
1492 // class, which can be stripped.
1493 if (enclosing_index > -1) {
1494 // Clear the signature to only extend java.lang.Object.
1495 super_class = NULL;
1496 interfaces.clear();
1497
1498 // Clear away all fields (implementation details).
1499 for (size_t ii = 0; ii < fields.size(); ++ii) {
1500 delete fields[ii];
1501 }
1502 fields.clear();
1503
1504 // Clear away all methods (implementation details).
1505 for (size_t ii = 0; ii < methods.size(); ++ii) {
1506 delete methods[ii];
1507 }
1508 methods.clear();
1509
1510 // Only preserve the InnerClasses attribute to comply with the spec.
1511 Attribute *attr = NULL;
1512 for (size_t ii = 0; ii < attributes.size(); ++ii) {
1513 if (static_cast<int>(ii) != inner_classes_index) {
1514 delete attributes[ii];
1515 } else {
1516 attr = attributes[ii];
1517 }
1518 }
1519 attributes.clear();
1520 if (attr != NULL) {
1521 attributes.push_back(attr);
1522 }
1523 }
1524}
1525
1526static ClassFile *ReadClass(const void *classdata, size_t length) {
1527 const u1 *p = (u1*) classdata;
1528
1529 ClassFile *clazz = new ClassFile;
1530
1531 clazz->length = length;
1532
1533 clazz->magic = get_u4be(p);
1534 if (clazz->magic != 0xCAFEBABE) {
1535 fprintf(stderr, "Bad magic %" PRIx32 "\n", clazz->magic);
1536 abort();
1537 }
1538 clazz->major = get_u2be(p);
1539 clazz->minor = get_u2be(p);
1540
1541 if (!clazz->ReadConstantPool(p)) {
1542 delete clazz;
1543 return NULL;
1544 }
1545
1546 clazz->access_flags = get_u2be(p);
1547 clazz->this_class = constant(get_u2be(p));
1548 class_name = clazz->this_class;
1549
1550 u2 super_class_id = get_u2be(p);
1551 clazz->super_class = super_class_id == 0 ? NULL : constant(super_class_id);
1552
1553 u2 interfaces_count = get_u2be(p);
1554 for (int ii = 0; ii < interfaces_count; ++ii) {
1555 clazz->interfaces.push_back(constant(get_u2be(p)));
1556 }
1557
1558 u2 fields_count = get_u2be(p);
1559 for (int ii = 0; ii < fields_count; ++ii) {
1560 Member *field = Member::Read(p);
1561
1562 if (!(field->access_flags & ACC_PRIVATE)) { // drop private fields
1563 clazz->fields.push_back(field);
1564 }
1565 }
1566
1567 u2 methods_count = get_u2be(p);
1568 for (int ii = 0; ii < methods_count; ++ii) {
1569 Member *method = Member::Read(p);
1570
1571 // drop class initializers
1572 if (method->name->Display() == "<clinit>") continue;
1573
1574 if (!(method->access_flags & ACC_PRIVATE)) { // drop private methods
1575 clazz->methods.push_back(method);
1576 }
1577 }
1578
1579 clazz->ReadAttrs(p);
1580 clazz->StripIfAnonymous();
1581
1582 return clazz;
1583}
1584
1585// In theory, '/' is also reserved, but it's okay if we just parse package
1586// identifiers as part of the class name. Note that signatures are UTF-8, but
1587// this works just as well as in plain ASCII.
1588static const char *SIGNATURE_NON_IDENTIFIER_CHARS = ".;[<>:";
1589
1590void Expect(const std::string& desc, size_t* p, char expected) {
1591 if (desc[*p] != expected) {
1592 fprintf(stderr, "Expected '%c' in '%s' at %zd in signature\n",
1593 expected, desc.substr(*p).c_str(), *p);
1594 exit(1);
1595 }
1596
1597 *p += 1;
1598}
1599
1600// These functions form a crude recursive descent parser for descriptors and
1601// signatures in class files (see JVM spec 4.3).
1602//
1603// This parser is a bit more liberal than the spec, but this should be fine,
1604// because it accepts all valid class files and croaks only on invalid ones.
1605void ParseFromClassTypeSignature(const std::string& desc, size_t* p);
1606void ParseSimpleClassTypeSignature(const std::string& desc, size_t* p);
1607void ParseClassTypeSignatureSuffix(const std::string& desc, size_t* p);
1608void ParseIdentifier(const std::string& desc, size_t* p);
1609void ParseTypeArgumentsOpt(const std::string& desc, size_t* p);
1610void ParseMethodDescriptor(const std::string& desc, size_t* p);
1611
1612void ParseClassTypeSignature(const std::string& desc, size_t* p) {
1613 Expect(desc, p, 'L');
1614 ParseSimpleClassTypeSignature(desc, p);
1615 ParseClassTypeSignatureSuffix(desc, p);
1616 Expect(desc, p, ';');
1617}
1618
1619void ParseSimpleClassTypeSignature(const std::string& desc, size_t* p) {
1620 ParseIdentifier(desc, p);
1621 ParseTypeArgumentsOpt(desc, p);
1622}
1623
1624void ParseClassTypeSignatureSuffix(const std::string& desc, size_t* p) {
1625 while (desc[*p] == '.') {
1626 *p += 1;
1627 ParseSimpleClassTypeSignature(desc, p);
1628 }
1629}
1630
1631void ParseIdentifier(const std::string& desc, size_t* p) {
1632 size_t next = desc.find_first_of(SIGNATURE_NON_IDENTIFIER_CHARS, *p);
1633 std::string id = desc.substr(*p, next - *p);
1634 used_class_names.insert(id);
1635 *p = next;
1636}
1637
1638void ParseTypeArgumentsOpt(const std::string& desc, size_t* p) {
1639 if (desc[*p] != '<') {
1640 return;
1641 }
1642
1643 *p += 1;
1644 while (desc[*p] != '>') {
1645 switch (desc[*p]) {
1646 case '*':
1647 *p += 1;
1648 break;
1649
1650 case '+':
1651 case '-':
1652 *p += 1;
1653 ExtractClassNames(desc, p);
1654 break;
1655
1656 default:
1657 ExtractClassNames(desc, p);
1658 break;
1659 }
1660 }
1661
1662 *p += 1;
1663}
1664
1665void ParseMethodDescriptor(const std::string& desc, size_t* p) {
1666 Expect(desc, p, '(');
1667 while (desc[*p] != ')') {
1668 ExtractClassNames(desc, p);
1669 }
1670
1671 Expect(desc, p, ')');
1672 ExtractClassNames(desc, p);
1673}
1674
1675void ParseFormalTypeParameters(const std::string& desc, size_t* p) {
1676 Expect(desc, p, '<');
1677 while (desc[*p] != '>') {
1678 ParseIdentifier(desc, p);
1679 Expect(desc, p, ':');
1680 if (desc[*p] != ':' && desc[*p] != '>') {
1681 ExtractClassNames(desc, p);
1682 }
1683
1684 while (desc[*p] == ':') {
1685 Expect(desc, p, ':');
1686 ExtractClassNames(desc, p);
1687 }
1688 }
1689
1690 Expect(desc, p, '>');
1691}
1692
1693void ExtractClassNames(const std::string& desc, size_t* p) {
1694 switch (desc[*p]) {
1695 case '<':
1696 ParseFormalTypeParameters(desc, p);
1697 ExtractClassNames(desc, p);
1698 break;
1699
1700 case 'L':
1701 ParseClassTypeSignature(desc, p);
1702 break;
1703
1704 case '[':
1705 *p += 1;
1706 ExtractClassNames(desc, p);
1707 break;
1708
1709 case 'T':
1710 *p += 1;
1711 ParseIdentifier(desc, p);
1712 Expect(desc, p, ';');
1713 break;
1714
1715 case '(':
1716 ParseMethodDescriptor(desc, p);
1717 break;
1718
1719 case 'B':
1720 case 'C':
1721 case 'D':
1722 case 'F':
1723 case 'I':
1724 case 'J':
1725 case 'S':
1726 case 'Z':
1727 case 'V':
1728 *p += 1;
1729 break;
1730
1731 default:
1732 fprintf(stderr, "Invalid signature %s\n", desc.substr(*p).c_str());
1733 }
1734}
1735
1736void ClassFile::WriteClass(u1 *&p) {
1737 used_class_names.clear();
1738 std::vector<Member *> members;
1739 members.insert(members.end(), fields.begin(), fields.end());
1740 members.insert(members.end(), methods.begin(), methods.end());
1741 ExtractClassNames();
Shinichiro Hamaji8f2968f2015-12-01 16:43:24 +09001742 for (size_t i = 0; i < members.size(); i++) {
Shinichiro Hamaji89b255a2015-11-09 16:47:42 +09001743 Member *member = members[i];
1744 size_t idx = 0;
1745 devtools_ijar::ExtractClassNames(member->descriptor->Display(), &idx);
1746 member->ExtractClassNames();
1747 }
1748
1749 // We have to write the body out before the header in order to reference
1750 // the essential constants and populate the output constant pool:
1751 u1 *body = new u1[length];
1752 u1 *q = body;
1753 WriteBody(q); // advances q
1754 u4 body_length = q - body;
1755
1756 WriteHeader(p); // advances p
1757 put_n(p, body, body_length);
1758 delete[] body;
1759}
1760
1761
1762void StripClass(u1 *&classdata_out, const u1 *classdata_in, size_t in_length) {
1763 ClassFile *clazz = ReadClass(classdata_in, in_length);
1764 if (clazz == NULL) {
1765 // Class is invalid. Simply copy it to the output and call it a day.
1766 put_n(classdata_out, classdata_in, in_length);
1767 } else {
1768
1769 // Constant pool item zero is a dummy entry. Setting it marks the
1770 // beginning of the output phase; calls to Constant::slot() will
1771 // fail if called prior to this.
1772 const_pool_out.push_back(NULL);
1773 clazz->WriteClass(classdata_out);
1774
1775 delete clazz;
1776 }
1777
1778 // Now clean up all the mess we left behind.
1779
1780 for (size_t i = 0; i < const_pool_in.size(); i++) {
1781 delete const_pool_in[i];
1782 }
1783
1784 const_pool_in.clear();
1785 const_pool_out.clear();
1786}
1787
1788} // namespace devtools_ijar