From 8a0ecedcdd9154d25173a78efad5a31fb37443ed Mon Sep 17 00:00:00 2001 From: Prateek Maloo Date: Sat, 3 Sep 2022 00:36:16 +0000 Subject: [PATCH 1/2] Update Dockerfile to patch and recompile rt.jar --- openjdk8/src/main/docker/ConstantPool.java | 347 ++++++++ openjdk8/src/main/docker/ConstantPoolGen.java | 763 ++++++++++++++++++ openjdk8/src/main/docker/Dockerfile | 31 + 3 files changed, 1141 insertions(+) create mode 100644 openjdk8/src/main/docker/ConstantPool.java create mode 100644 openjdk8/src/main/docker/ConstantPoolGen.java diff --git a/openjdk8/src/main/docker/ConstantPool.java b/openjdk8/src/main/docker/ConstantPool.java new file mode 100644 index 00000000..c8ea26d2 --- /dev/null +++ b/openjdk8/src/main/docker/ConstantPool.java @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.classfile; + + +import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import java.io.*; + +/** + * This class represents the constant pool, i.e., a table of constants, of + * a parsed classfile. It may contain null references, due to the JVM + * specification that skips an entry after an 8-byte constant (double, + * long) entry. Those interested in generating constant pools + * programatically should see + * ConstantPoolGen. + + * @see Constant + * @see com.sun.org.apache.bcel.internal.generic.ConstantPoolGen + * @author M. Dahm + * @LastModified: May 2022 + */ +public class ConstantPool implements Cloneable, Node, Serializable { + private int constant_pool_count; + private Constant[] constant_pool; + + /** + * @param constant_pool Array of constants + */ + public ConstantPool(Constant[] constant_pool) + { + setConstantPool(constant_pool); + } + + /** + * Read constants from given file stream. + * + * @param file Input stream + * @throws IOException + * @throws ClassFormatException + */ + ConstantPool(DataInputStream file) throws IOException, ClassFormatException + { + byte tag; + + constant_pool_count = file.readUnsignedShort(); + constant_pool = new Constant[constant_pool_count]; + + /* constant_pool[0] is unused by the compiler and may be used freely + * by the implementation. + */ + for(int i=1; i < constant_pool_count; i++) { + constant_pool[i] = Constant.readConstant(file); + + /* Quote from the JVM specification: + * "All eight byte constants take up two spots in the constant pool. + * If this is the n'th byte in the constant pool, then the next item + * will be numbered n+2" + * + * Thus we have to increment the index counter. + */ + tag = constant_pool[i].getTag(); + if((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) + i++; + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantPool(this); + } + + /** + * Resolve constant to a string representation. + * + * @param constant Constant to be printed + * @return String representation + */ + public String constantToString(Constant c) + throws ClassFormatException + { + String str; + int i; + byte tag = c.getTag(); + + switch(tag) { + case Constants.CONSTANT_Class: + i = ((ConstantClass)c).getNameIndex(); + c = getConstant(i, Constants.CONSTANT_Utf8); + str = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false); + break; + + case Constants.CONSTANT_String: + i = ((ConstantString)c).getStringIndex(); + c = getConstant(i, Constants.CONSTANT_Utf8); + str = "\"" + escape(((ConstantUtf8)c).getBytes()) + "\""; + break; + + case Constants.CONSTANT_Utf8: str = ((ConstantUtf8)c).getBytes(); break; + case Constants.CONSTANT_Double: str = "" + ((ConstantDouble)c).getBytes(); break; + case Constants.CONSTANT_Float: str = "" + ((ConstantFloat)c).getBytes(); break; + case Constants.CONSTANT_Long: str = "" + ((ConstantLong)c).getBytes(); break; + case Constants.CONSTANT_Integer: str = "" + ((ConstantInteger)c).getBytes(); break; + + case Constants.CONSTANT_NameAndType: + str = (constantToString(((ConstantNameAndType)c).getNameIndex(), + Constants.CONSTANT_Utf8) + " " + + constantToString(((ConstantNameAndType)c).getSignatureIndex(), + Constants.CONSTANT_Utf8)); + break; + + case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref: + case Constants.CONSTANT_Fieldref: + str = (constantToString(((ConstantCP)c).getClassIndex(), + Constants.CONSTANT_Class) + "." + + constantToString(((ConstantCP)c).getNameAndTypeIndex(), + Constants.CONSTANT_NameAndType)); + break; + + default: // Never reached + throw new RuntimeException("Unknown constant type " + tag); + } + + return str; + } + + private static final String escape(String str) { + int len = str.length(); + StringBuffer buf = new StringBuffer(len + 5); + char[] ch = str.toCharArray(); + + for(int i=0; i < len; i++) { + switch(ch[i]) { + case '\n' : buf.append("\\n"); break; + case '\r' : buf.append("\\r"); break; + case '\t' : buf.append("\\t"); break; + case '\b' : buf.append("\\b"); break; + case '"' : buf.append("\\\""); break; + default: buf.append(ch[i]); + } + } + + return buf.toString(); + } + + + /** + * Retrieve constant at `index' from constant pool and resolve it to + * a string representation. + * + * @param index of constant in constant pool + * @param tag expected type + * @return String representation + */ + public String constantToString(int index, byte tag) + throws ClassFormatException + { + Constant c = getConstant(index, tag); + return constantToString(c); + } + + /** + * Dump constant pool to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public void dump(DataOutputStream file) throws IOException + { + /* + * Constants over the size of the constant pool shall not be written out. + * This is a redundant measure as the ConstantPoolGen should have already + * reported an error back in the situation. + */ + int size = constant_pool_count < ConstantPoolGen.CONSTANT_POOL_SIZE - 1 ? + constant_pool_count : ConstantPoolGen.CONSTANT_POOL_SIZE - 1; + + file.writeShort(size); + for(int i=1; i < size; i++) + if(constant_pool[i] != null) + constant_pool[i].dump(file); + } + + /** + * Get constant from constant pool. + * + * @param index Index in constant pool + * @return Constant value + * @see Constant + */ + public Constant getConstant(int index) { + if (index >= constant_pool.length || index < 0) + throw new ClassFormatException("Invalid constant pool reference: " + + index + ". Constant pool size is: " + + constant_pool.length); + return constant_pool[index]; + } + + /** + * Get constant from constant pool and check whether it has the + * expected type. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, i.e., its type + * @return Constant value + * @see Constant + * @throws ClassFormatException + */ + public Constant getConstant(int index, byte tag) + throws ClassFormatException + { + Constant c; + + c = getConstant(index); + + if(c == null) + throw new ClassFormatException("Constant pool at index " + index + " is null."); + + if(c.getTag() == tag) + return c; + else + throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag] + + "' at index " + index + " and got " + c); + } + + /** + * @return Array of constants. + * @see Constant + */ + public Constant[] getConstantPool() { return constant_pool; } + /** + * Get string from constant pool and bypass the indirection of + * `ConstantClass' and `ConstantString' objects. I.e. these classes have + * an index field that points to another entry of the constant pool of + * type `ConstantUtf8' which contains the real data. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, either ConstantClass or ConstantString + * @return Contents of string reference + * @see ConstantClass + * @see ConstantString + * @throws ClassFormatException + */ + public String getConstantString(int index, byte tag) + throws ClassFormatException + { + Constant c; + int i; + + c = getConstant(index, tag); + + /* This switch() is not that elegant, since the two classes have the + * same contents, they just differ in the name of the index + * field variable. + * But we want to stick to the JVM naming conventions closely though + * we could have solved these more elegantly by using the same + * variable name or by subclassing. + */ + switch(tag) { + case Constants.CONSTANT_Class: i = ((ConstantClass)c).getNameIndex(); break; + case Constants.CONSTANT_String: i = ((ConstantString)c).getStringIndex(); break; + default: + throw new RuntimeException("getConstantString called with illegal tag " + tag); + } + + // Finally get the string from the constant pool + c = getConstant(i, Constants.CONSTANT_Utf8); + return ((ConstantUtf8)c).getBytes(); + } + /** + * @return Length of constant pool. + */ + public int getLength() + { + return constant_pool_count; + } + + /** + * @param constant Constant to set + */ + public void setConstant(int index, Constant constant) { + constant_pool[index] = constant; + } + + /** + * @param constant_pool + */ + public void setConstantPool(Constant[] constant_pool) { + this.constant_pool = constant_pool; + constant_pool_count = (constant_pool == null)? 0 : constant_pool.length; + } + /** + * @return String representation. + */ + public String toString() { + StringBuffer buf = new StringBuffer(); + + for(int i=1; i < constant_pool_count; i++) + buf.append(i + ")" + constant_pool[i] + "\n"); + + return buf.toString(); + } + + /** + * @return deep copy of this constant pool + */ + public ConstantPool copy() { + ConstantPool c = null; + + try { + c = (ConstantPool)clone(); + } catch(CloneNotSupportedException e) {} + + c.constant_pool = new Constant[constant_pool_count]; + + for(int i=1; i < constant_pool_count; i++) { + if(constant_pool[i] != null) + c.constant_pool[i] = constant_pool[i].copy(); + } + + return c; + } +} diff --git a/openjdk8/src/main/docker/ConstantPoolGen.java b/openjdk8/src/main/docker/ConstantPoolGen.java new file mode 100644 index 00000000..bdd25a64 --- /dev/null +++ b/openjdk8/src/main/docker/ConstantPoolGen.java @@ -0,0 +1,763 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.bcel.internal.generic; + + +import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.classfile.*; +import java.util.HashMap; + +/** + * This class is used to build up a constant pool. The user adds + * constants via `addXXX' methods, `addString', `addClass', + * etc.. These methods return an index into the constant + * pool. Finally, `getFinalConstantPool()' returns the constant pool + * built up. Intermediate versions of the constant pool can be + * obtained with `getConstantPool()'. A constant pool has capacity for + * Constants.MAX_SHORT entries. Note that the first (0) is used by the + * JVM and that Double and Long constants need two slots. + * + * @author M. Dahm + * @see Constant + * @LastModified: May 2022 + */ +public class ConstantPoolGen implements java.io.Serializable { + public static final int CONSTANT_POOL_SIZE = 65536; + protected int size = 1024; // Inital size, sufficient in most cases + protected Constant[] constants = new Constant[size]; + protected int index = 1; // First entry (0) used by JVM + + private static final String METHODREF_DELIM = ":"; + private static final String IMETHODREF_DELIM = "#"; + private static final String FIELDREF_DELIM = "&"; + private static final String NAT_DELIM = "%"; + + private static class Index implements java.io.Serializable { + int index; + Index(int i) { index = i; } + } + + /** + * Initialize with given array of constants. + * + * @param c array of given constants, new ones will be appended + */ + public ConstantPoolGen(Constant[] cs) { + if(cs.length > size) { + size = Math.min(cs.length, CONSTANT_POOL_SIZE); + constants = new Constant[size]; + } + + System.arraycopy(cs, 0, constants, 0, cs.length); + + if(cs.length > 0) + index = cs.length; + + for(int i=1; i < index; i++) { + Constant c = constants[i]; + + if(c instanceof ConstantString) { + ConstantString s = (ConstantString)c; + ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; + + string_table.put(u8.getBytes(), new Index(i)); + } else if(c instanceof ConstantClass) { + ConstantClass s = (ConstantClass)c; + ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; + + class_table.put(u8.getBytes(), new Index(i)); + } else if(c instanceof ConstantNameAndType) { + ConstantNameAndType n = (ConstantNameAndType)c; + ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; + ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; + + n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i)); + } else if(c instanceof ConstantUtf8) { + ConstantUtf8 u = (ConstantUtf8)c; + + utf8_table.put(u.getBytes(), new Index(i)); + } else if(c instanceof ConstantCP) { + ConstantCP m = (ConstantCP)c; + ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; + ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; + + ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; + String class_name = u8.getBytes().replace('/', '.'); + + u8 = (ConstantUtf8)constants[n.getNameIndex()]; + String method_name = u8.getBytes(); + + u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; + String signature = u8.getBytes(); + + String delim = METHODREF_DELIM; + + if(c instanceof ConstantInterfaceMethodref) + delim = IMETHODREF_DELIM; + else if(c instanceof ConstantFieldref) + delim = FIELDREF_DELIM; + + cp_table.put(class_name + delim + method_name + delim + signature, new Index(i)); + } + } + } + + /** + * Initialize with given constant pool. + */ + public ConstantPoolGen(ConstantPool cp) { + this(cp.getConstantPool()); + } + + /** + * Create empty constant pool. + */ + public ConstantPoolGen() {} + + /** Resize internal array of constants. + */ + protected void adjustSize() { + // 3 extra spaces are needed as some entries may take 3 slots + if (index + 3 >= CONSTANT_POOL_SIZE) { + throw new RuntimeException("The number of constants " + (index + 3) + + " is over the size of the constant pool: " + + (CONSTANT_POOL_SIZE - 1)); + } + + if(index + 3 >= size) { + Constant[] cs = constants; + + size *= 2; + // the constant array shall not exceed the size of the constant pool + size = Math.min(size, CONSTANT_POOL_SIZE); + constants = new Constant[size]; + System.arraycopy(cs, 0, constants, 0, index); + } + } + + private HashMap string_table = new HashMap(); + + /** + * Look for ConstantString in ConstantPool containing String `str'. + * + * @param str String to search for + * @return index on success, -1 otherwise + */ + public int lookupString(String str) { + Index index = (Index)string_table.get(str); + return (index != null)? index.index : -1; + } + + /** + * Add a new String constant to the ConstantPool, if it is not already in there. + * + * @param str String to add + * @return index of entry + */ + public int addString(String str) { + int ret; + + if((ret = lookupString(str)) != -1) + return ret; // Already in CP + + int utf8 = addUtf8(str); + + adjustSize(); + + ConstantString s = new ConstantString(utf8); + + ret = index; + constants[index++] = s; + + string_table.put(str, new Index(ret)); + + return ret; + } + + private HashMap class_table = new HashMap(); + + /** + * Look for ConstantClass in ConstantPool named `str'. + * + * @param str String to search for + * @return index on success, -1 otherwise + */ + public int lookupClass(String str) { + Index index = (Index)class_table.get(str.replace('.', '/')); + return (index != null)? index.index : -1; + } + + private int addClass_(String clazz) { + int ret; + + if((ret = lookupClass(clazz)) != -1) + return ret; // Already in CP + + adjustSize(); + + ConstantClass c = new ConstantClass(addUtf8(clazz)); + + ret = index; + constants[index++] = c; + + class_table.put(clazz, new Index(ret)); + + return ret; + } + + /** + * Add a new Class reference to the ConstantPool, if it is not already in there. + * + * @param str Class to add + * @return index of entry + */ + public int addClass(String str) { + return addClass_(str.replace('.', '/')); + } + + /** + * Add a new Class reference to the ConstantPool for a given type. + * + * @param str Class to add + * @return index of entry + */ + public int addClass(ObjectType type) { + return addClass(type.getClassName()); + } + + /** + * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY + * instruction, e.g. to the ConstantPool. + * + * @param type type of array class + * @return index of entry + */ + public int addArrayClass(ArrayType type) { + return addClass_(type.getSignature()); + } + + /** + * Look for ConstantInteger in ConstantPool. + * + * @param n integer number to look for + * @return index on success, -1 otherwise + */ + public int lookupInteger(int n) { + for(int i=1; i < index; i++) { + if(constants[i] instanceof ConstantInteger) { + ConstantInteger c = (ConstantInteger)constants[i]; + + if(c.getBytes() == n) + return i; + } + } + + return -1; + } + + /** + * Add a new Integer constant to the ConstantPool, if it is not already in there. + * + * @param n integer number to add + * @return index of entry + */ + public int addInteger(int n) { + int ret; + + if((ret = lookupInteger(n)) != -1) + return ret; // Already in CP + + adjustSize(); + + ret = index; + constants[index++] = new ConstantInteger(n); + + return ret; + } + + /** + * Look for ConstantFloat in ConstantPool. + * + * @param n Float number to look for + * @return index on success, -1 otherwise + */ + public int lookupFloat(float n) { + int bits = Float.floatToIntBits(n); + + for(int i=1; i < index; i++) { + if(constants[i] instanceof ConstantFloat) { + ConstantFloat c = (ConstantFloat)constants[i]; + + if(Float.floatToIntBits(c.getBytes()) == bits) + return i; + } + } + + return -1; + } + + /** + * Add a new Float constant to the ConstantPool, if it is not already in there. + * + * @param n Float number to add + * @return index of entry + */ + public int addFloat(float n) { + int ret; + + if((ret = lookupFloat(n)) != -1) + return ret; // Already in CP + + adjustSize(); + + ret = index; + constants[index++] = new ConstantFloat(n); + + return ret; + } + + private HashMap utf8_table = new HashMap(); + + /** + * Look for ConstantUtf8 in ConstantPool. + * + * @param n Utf8 string to look for + * @return index on success, -1 otherwise + */ + public int lookupUtf8(String n) { + Index index = (Index)utf8_table.get(n); + + return (index != null)? index.index : -1; + } + + /** + * Add a new Utf8 constant to the ConstantPool, if it is not already in there. + * + * @param n Utf8 string to add + * @return index of entry + */ + public int addUtf8(String n) { + int ret; + + if((ret = lookupUtf8(n)) != -1) + return ret; // Already in CP + + adjustSize(); + + ret = index; + constants[index++] = new ConstantUtf8(n); + + utf8_table.put(n, new Index(ret)); + + return ret; + } + + /** + * Look for ConstantLong in ConstantPool. + * + * @param n Long number to look for + * @return index on success, -1 otherwise + */ + public int lookupLong(long n) { + for(int i=1; i < index; i++) { + if(constants[i] instanceof ConstantLong) { + ConstantLong c = (ConstantLong)constants[i]; + + if(c.getBytes() == n) + return i; + } + } + + return -1; + } + + /** + * Add a new long constant to the ConstantPool, if it is not already in there. + * + * @param n Long number to add + * @return index of entry + */ + public int addLong(long n) { + int ret; + + if((ret = lookupLong(n)) != -1) + return ret; // Already in CP + + adjustSize(); + + ret = index; + constants[index] = new ConstantLong(n); + index += 2; // Wastes one entry according to spec + + return ret; + } + + /** + * Look for ConstantDouble in ConstantPool. + * + * @param n Double number to look for + * @return index on success, -1 otherwise + */ + public int lookupDouble(double n) { + long bits = Double.doubleToLongBits(n); + + for(int i=1; i < index; i++) { + if(constants[i] instanceof ConstantDouble) { + ConstantDouble c = (ConstantDouble)constants[i]; + + if(Double.doubleToLongBits(c.getBytes()) == bits) + return i; + } + } + + return -1; + } + + /** + * Add a new double constant to the ConstantPool, if it is not already in there. + * + * @param n Double number to add + * @return index of entry + */ + public int addDouble(double n) { + int ret; + + if((ret = lookupDouble(n)) != -1) + return ret; // Already in CP + + adjustSize(); + + ret = index; + constants[index] = new ConstantDouble(n); + index += 2; // Wastes one entry according to spec + + return ret; + } + + private HashMap n_a_t_table = new HashMap(); + + /** + * Look for ConstantNameAndType in ConstantPool. + * + * @param name of variable/method + * @param signature of variable/method + * @return index on success, -1 otherwise + */ + public int lookupNameAndType(String name, String signature) { + Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature); + return (index != null)? index.index : -1; + } + + /** + * Add a new NameAndType constant to the ConstantPool if it is not already + * in there. + * + * @param n NameAndType string to add + * @return index of entry + */ + public int addNameAndType(String name, String signature) { + int ret; + int name_index, signature_index; + + if((ret = lookupNameAndType(name, signature)) != -1) + return ret; // Already in CP + + adjustSize(); + + name_index = addUtf8(name); + signature_index = addUtf8(signature); + ret = index; + constants[index++] = new ConstantNameAndType(name_index, signature_index); + + n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret)); + return ret; + } + + private HashMap cp_table = new HashMap(); + + /** + * Look for ConstantMethodref in ConstantPool. + * + * @param class_name Where to find method + * @param method_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupMethodref(String class_name, String method_name, String signature) { + Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name + + METHODREF_DELIM + signature); + return (index != null)? index.index : -1; + } + + public int lookupMethodref(MethodGen method) { + return lookupMethodref(method.getClassName(), method.getName(), + method.getSignature()); + } + + /** + * Add a new Methodref constant to the ConstantPool, if it is not already + * in there. + * + * @param n Methodref string to add + * @return index of entry + */ + public int addMethodref(String class_name, String method_name, String signature) { + int ret, class_index, name_and_type_index; + + if((ret = lookupMethodref(class_name, method_name, signature)) != -1) + return ret; // Already in CP + + adjustSize(); + + name_and_type_index = addNameAndType(method_name, signature); + class_index = addClass(class_name); + ret = index; + constants[index++] = new ConstantMethodref(class_index, name_and_type_index); + + cp_table.put(class_name + METHODREF_DELIM + method_name + + METHODREF_DELIM + signature, new Index(ret)); + + return ret; + } + + public int addMethodref(MethodGen method) { + return addMethodref(method.getClassName(), method.getName(), + method.getSignature()); + } + + /** + * Look for ConstantInterfaceMethodref in ConstantPool. + * + * @param class_name Where to find method + * @param method_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupInterfaceMethodref(String class_name, String method_name, String signature) { + Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name + + IMETHODREF_DELIM + signature); + return (index != null)? index.index : -1; + } + + public int lookupInterfaceMethodref(MethodGen method) { + return lookupInterfaceMethodref(method.getClassName(), method.getName(), + method.getSignature()); + } + + /** + * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already + * in there. + * + * @param n InterfaceMethodref string to add + * @return index of entry + */ + public int addInterfaceMethodref(String class_name, String method_name, String signature) { + int ret, class_index, name_and_type_index; + + if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) + return ret; // Already in CP + + adjustSize(); + + class_index = addClass(class_name); + name_and_type_index = addNameAndType(method_name, signature); + ret = index; + constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); + + cp_table.put(class_name + IMETHODREF_DELIM + method_name + + IMETHODREF_DELIM + signature, new Index(ret)); + + return ret; + } + + public int addInterfaceMethodref(MethodGen method) { + return addInterfaceMethodref(method.getClassName(), method.getName(), + method.getSignature()); + } + + /** + * Look for ConstantFieldref in ConstantPool. + * + * @param class_name Where to find method + * @param field_name Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise + */ + public int lookupFieldref(String class_name, String field_name, String signature) { + Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name + + FIELDREF_DELIM + signature); + return (index != null)? index.index : -1; + } + + /** + * Add a new Fieldref constant to the ConstantPool, if it is not already + * in there. + * + * @param n Fieldref string to add + * @return index of entry + */ + public int addFieldref(String class_name, String field_name, String signature) { + int ret; + int class_index, name_and_type_index; + + if((ret = lookupFieldref(class_name, field_name, signature)) != -1) + return ret; // Already in CP + + adjustSize(); + + class_index = addClass(class_name); + name_and_type_index = addNameAndType(field_name, signature); + ret = index; + constants[index++] = new ConstantFieldref(class_index, name_and_type_index); + + cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret)); + + return ret; + } + + /** + * @param i index in constant pool + * @return constant pool entry at index i + */ + public Constant getConstant(int i) { return constants[i]; } + + /** + * Use with care! + * + * @param i index in constant pool + * @param c new constant pool entry at index i + */ + public void setConstant(int i, Constant c) { constants[i] = c; } + + /** + * @return intermediate constant pool + */ + public ConstantPool getConstantPool() { + return new ConstantPool(constants); + } + + /** + * @return current size of constant pool + */ + public int getSize() { + return index; + } + + /** + * @return constant pool with proper length + */ + public ConstantPool getFinalConstantPool() { + Constant[] cs = new Constant[index]; + + System.arraycopy(constants, 0, cs, 0, index); + + return new ConstantPool(cs); + } + + /** + * @return String representation. + */ + public String toString() { + StringBuffer buf = new StringBuffer(); + + for(int i=1; i < index; i++) + buf.append(i + ")" + constants[i] + "\n"); + + return buf.toString(); + } + + /** Import constant from another ConstantPool and return new index. + */ + public int addConstant(Constant c, ConstantPoolGen cp) { + Constant[] constants = cp.getConstantPool().getConstantPool(); + + switch(c.getTag()) { + case Constants.CONSTANT_String: { + ConstantString s = (ConstantString)c; + ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; + + return addString(u8.getBytes()); + } + + case Constants.CONSTANT_Class: { + ConstantClass s = (ConstantClass)c; + ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; + + return addClass(u8.getBytes()); + } + + case Constants.CONSTANT_NameAndType: { + ConstantNameAndType n = (ConstantNameAndType)c; + ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; + ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; + + return addNameAndType(u8.getBytes(), u8_2.getBytes()); + } + + case Constants.CONSTANT_Utf8: + return addUtf8(((ConstantUtf8)c).getBytes()); + + case Constants.CONSTANT_Double: + return addDouble(((ConstantDouble)c).getBytes()); + + case Constants.CONSTANT_Float: + return addFloat(((ConstantFloat)c).getBytes()); + + case Constants.CONSTANT_Long: + return addLong(((ConstantLong)c).getBytes()); + + case Constants.CONSTANT_Integer: + return addInteger(((ConstantInteger)c).getBytes()); + + case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref: + case Constants.CONSTANT_Fieldref: { + ConstantCP m = (ConstantCP)c; + ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()]; + ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; + ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; + String class_name = u8.getBytes().replace('/', '.'); + + u8 = (ConstantUtf8)constants[n.getNameIndex()]; + String name = u8.getBytes(); + + u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; + String signature = u8.getBytes(); + + switch(c.getTag()) { + case Constants.CONSTANT_InterfaceMethodref: + return addInterfaceMethodref(class_name, name, signature); + + case Constants.CONSTANT_Methodref: + return addMethodref(class_name, name, signature); + + case Constants.CONSTANT_Fieldref: + return addFieldref(class_name, name, signature); + + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } + } + + default: // Never reached + throw new RuntimeException("Unknown constant type " + c); + } + } +} diff --git a/openjdk8/src/main/docker/Dockerfile b/openjdk8/src/main/docker/Dockerfile index c8fee1ce..e2c338d2 100644 --- a/openjdk8/src/main/docker/Dockerfile +++ b/openjdk8/src/main/docker/Dockerfile @@ -37,6 +37,37 @@ RUN \ && apt-get clean \ && rm /var/lib/apt/lists/*_* +# Below code is a temporary fix to patch CVE-2022-34169 and address b/244448607. +# It should be removed once openjdk-8-8u342-b07-1 is promoted to stable (strech) debian package source. +ARG JAVA_PATCH_SRC=/tmp/java/src +ARG JAVA_PATCH_OUTPUT=/tmp/java/output +ARG JAVA_PATCH_BACKUP=/tmp/java/backup +ARG ORIG_RT_JAR_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar + +RUN mkdir -p $JAVA_PATCH_SRC \ + && mkdir -p $JAVA_PATCH_OUTPUT \ + && mkdir -p $JAVA_PATCH_BACKUP + +# COPY patched files +COPY ConstantPoolGen.java $JAVA_PATCH_SRC/com/sun/org/apache/bcel/internal/generic/ +COPY ConstantPool.java $JAVA_PATCH_SRC/com/sun/org/apache/bcel/internal/classfile/ + +# Build and Replace +RUN cp $ORIG_RT_JAR_PATH $JAVA_PATCH_BACKUP\original_rt.jar \ + # Unpack existing rt.jar to the output folder (used as the base drop folder) + && cd $JAVA_PATCH_OUTPUT \ + && jar xf /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar \ + # Compile the patched files and drop them in the output folder + && cd $JAVA_PATCH_SRC \ + && javac -d $JAVA_PATCH_OUTPUT -cp $ORIG_RT_JAR_PATH $(find * -name '*.java') \ + # Pack the output folder which now has the new patched classes + && cd $JAVA_PATCH_OUTPUT \ + && jar cvf $JAVA_PATCH_BACKUP/new_rt.jar . \ + # Replace the live rt.jar with the new rt.jar + && cp $JAVA_PATCH_BACKUP/new_rt.jar $ORIG_RT_JAR_PATH + ## clean-up + #&& rm -rf /tmp/java + # Add the Stackdriver Debugger libraries ADD https://storage.googleapis.com/cloud-debugger/appengine-java/current/cdbg_java_agent.tar.gz /opt/cdbg/ # Add the Stackdriver Profiler libraries From 538cf02b6e5e28b1be2d93cd9b5a300ffee3d709 Mon Sep 17 00:00:00 2001 From: pmaloogoogle Date: Sat, 3 Sep 2022 01:40:20 +0000 Subject: [PATCH 2/2] address comments --- openjdk8/src/main/docker/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openjdk8/src/main/docker/Dockerfile b/openjdk8/src/main/docker/Dockerfile index e2c338d2..69d67c59 100644 --- a/openjdk8/src/main/docker/Dockerfile +++ b/openjdk8/src/main/docker/Dockerfile @@ -37,8 +37,8 @@ RUN \ && apt-get clean \ && rm /var/lib/apt/lists/*_* -# Below code is a temporary fix to patch CVE-2022-34169 and address b/244448607. -# It should be removed once openjdk-8-8u342-b07-1 is promoted to stable (strech) debian package source. +# Below code is a temporary fix to patch a bug and address b/244448607. +# It should be removed once openjdk-8-8u342-b07-1 is promoted to stable (strech) debian package source. ARG JAVA_PATCH_SRC=/tmp/java/src ARG JAVA_PATCH_OUTPUT=/tmp/java/output ARG JAVA_PATCH_BACKUP=/tmp/java/backup @@ -46,14 +46,14 @@ ARG ORIG_RT_JAR_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar RUN mkdir -p $JAVA_PATCH_SRC \ && mkdir -p $JAVA_PATCH_OUTPUT \ - && mkdir -p $JAVA_PATCH_BACKUP + && mkdir -p $JAVA_PATCH_BACKUP # COPY patched files COPY ConstantPoolGen.java $JAVA_PATCH_SRC/com/sun/org/apache/bcel/internal/generic/ COPY ConstantPool.java $JAVA_PATCH_SRC/com/sun/org/apache/bcel/internal/classfile/ # Build and Replace -RUN cp $ORIG_RT_JAR_PATH $JAVA_PATCH_BACKUP\original_rt.jar \ +RUN cp $ORIG_RT_JAR_PATH $JAVA_PATCH_BACKUP/original_rt.jar \ # Unpack existing rt.jar to the output folder (used as the base drop folder) && cd $JAVA_PATCH_OUTPUT \ && jar xf /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar \