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