undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,66 @@
#!/bin/bash
#
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
# Copyright 2015 Google, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
usage() {
(
echo "$0 DIR ..."
echo "Modifies in place all the java source files found"
echo "in the given directories so that all java language modifiers"
echo "are in the canonical order."
echo "Tries to get it right even within javadoc comments,"
echo "and even if the list of modifiers spans 2 lines."
echo
echo "See:"
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.1.1"
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.3.1"
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.4.3"
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.8.3"
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.1.1"
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.4"
echo
echo "Example:"
echo "$0 jdk/src/java.base jdk/test/java/{util,io,lang}"
) >&2
exit 1
}
set -eu
declare -ar dirs=("$@")
[[ "${#dirs[@]}" > 0 ]] || usage
for dir in "${dirs[@]}"; do [[ -d "$dir" ]] || usage; done
declare -ar modifiers=(
public protected private
abstract default static final sealed non-sealed transient
volatile synchronized native strictfp
)
declare -r SAVE_IFS="$IFS"
for ((i = 3; i < "${#modifiers[@]}"; i++)); do
IFS='|'; x="${modifiers[*]:0:i}" y="${modifiers[*]:i}"; IFS="$SAVE_IFS"
if [[ -n "$x" && -n "$y" ]]; then
find "${dirs[@]}" -name '*.java' -type f -print0 | \
xargs -0 perl -0777 -p -i -e \
"do {} while s/^([A-Za-z@* ]*)\b($y)(\s|(?:\s|\n\s+\*)*\s)($x)\b/\1\4\3\2/mg"
fi
done

103
bin/generate-symbol-data.sh Normal file
View file

@ -0,0 +1,103 @@
#!/bin/sh
#
# Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# This script allows to easily generate (add or update) "--release N" data for JDK N + 1.
# N must be 11 or greater. This script works on Linux. To create new data, or update existing
# data, it is necessary to:
# - download a binary build of OpenJDK N for Linux, API of which will be recorded. It is strongly recommended
# to use an official build, not a custom build, to avoid any chance of including unofficial changes.
# The binary build should never be a build newer than the GA for JDK N. Install the build. The installation
# directory will be denoted as "${JDK_N_INSTALL}" in the further text.
# - have a checkout the JDK to which the data should be added (or in which the data should be updated).
# The checkout directory will be denoted as "${JDK_CHECKOUT}" in the further text.
# The checkout must not have any local changes that could interfere with the new data. In particular,
# there must be absolutely no changed, new or removed files under the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols
# directory.
# - open a terminal program and run these commands:
# cd "${JDK_CHECKOUT}"/src/jdk.compiler/share/data/symbols
# bash ../../../../../bin/generate-symbol-data.sh "${JDK_N_INSTALL}"
# - this command will generate or update data for "--release N" into the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols
# directory, updating all registration necessary. If the goal was to update the data, and there are no
# new or changed files in the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols directory after running this script,
# there were no relevant changes and no further action is necessary. Note that version for N > 9 are encoded
# using capital letters, i.e. A represents version 10, B represents 11, and so on. The version numbers are in
# the names of the files in the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols directory, as well as in
# the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols/symbols file.
# - if there are any changed/new files in the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols directory after running this script,
# then all the changes in this directory, including any new files, need to be sent for review and eventually pushed.
# The commit message should specify which binary build was installed in the ${JDK_N_INSTALL} directory and also
# include the SCM state that was used to build it, which can be found in ${JDK_N_INSTALL}/release,
# in property "SOURCE".
source_path="$(dirname ${0})"
this_script_dir="$(cd -- "${source_path}" > /dev/null && pwd)"
if test -z "${this_script_dir}"; then
echo "Error: Could not determine location of this script"
exit 1
fi
symbols_dir="$(dirname $this_script_dir)/src/jdk.compiler/share/data/symbols"
if [ ! -d $symbols_dir ] ; then
echo "Cannot locate symbols directory: $symbols_dir" >&2
exit 1
fi
generator_dir="$(dirname $this_script_dir)/make/langtools/src/classes/build/tools/symbolgenerator"
if [ "$1x" = "x" ] ; then
echo "Must provide the target JDK as a parameter:" >&2
echo "$0 <target-jdk>" >&2
exit 1
fi;
if [ ! -d $1 ] ; then
echo "Target JDK argument is not a directory:" $1 >&2
exit 1
fi;
if [ ! -x $1/bin/java ] ; then
echo "Target JDK argument is not a valid JDK: $1" >&2
exit 1
fi;
cd $symbols_dir
if [ ! -f symbols ] ; then
echo "Must run inside the src/jdk.compiler/share/data/symbols directory" >&2
exit 1
fi;
if [ "`git status --porcelain=v1 .`x" != "x" ] ; then
echo "The src/jdk.compiler/share/data/symbols directory contains local changes!" >&2
exit 1
fi;
$1/bin/java --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
--add-modules jdk.jdeps \
$generator_dir/CreateSymbols.java \
build-description-incremental symbols include.list

268
bin/idea.sh Normal file
View file

@ -0,0 +1,268 @@
#!/bin/sh
#
# Copyright (c) 2009, 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# Shell script for generating an IDEA project from a given list of modules
usage() {
echo "usage: $0 [-h|--help] [-v|--verbose] [-o|--output <path>] [-c|--conf <conf_name>] [modules]+"
exit 1
}
SCRIPT_DIR=`dirname $0`
#assume TOP is the dir from which the script has been called
TOP=`pwd`
cd $SCRIPT_DIR; SCRIPT_DIR=`pwd`
cd $TOP;
IDEA_OUTPUT=$TOP/.idea
VERBOSE="false"
CONF_ARG=
while [ $# -gt 0 ]
do
case $1 in
-h | --help )
usage
;;
-v | --vebose )
VERBOSE="true"
;;
-o | --output )
IDEA_OUTPUT=$2/.idea
shift
;;
-c | --conf )
CONF_ARG="CONF_NAME=$2"
shift
;;
-*) # bad option
usage
;;
* ) # non option
break
;;
esac
shift
done
if [ -e $IDEA_OUTPUT ] ; then
rm -r $IDEA_OUTPUT
fi
mkdir -p $IDEA_OUTPUT || exit 1
cd $IDEA_OUTPUT; IDEA_OUTPUT=`pwd`
if [ "x$TOPLEVEL_DIR" = "x" ] ; then
cd $SCRIPT_DIR/..
TOPLEVEL_DIR=`pwd`
cd $IDEA_OUTPUT
fi
MAKE_DIR="$SCRIPT_DIR/../make"
IDEA_MAKE="$MAKE_DIR/ide/idea/jdk"
IDEA_TEMPLATE="$IDEA_MAKE/template"
cp -r "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT"
#override template
if [ -d "$TEMPLATES_OVERRIDE" ] ; then
for file in `ls -p "$TEMPLATES_OVERRIDE" | grep -v /`; do
cp "$TEMPLATES_OVERRIDE"/$file "$IDEA_OUTPUT"/
done
fi
if [ "$VERBOSE" = "true" ] ; then
echo "output dir: $IDEA_OUTPUT"
echo "idea template dir: $IDEA_TEMPLATE"
fi
cd $TOP ; make idea-gen-config ALLOW=IDEA_OUTPUT,MODULES IDEA_OUTPUT=$IDEA_OUTPUT MODULES="$*" $CONF_ARG || exit 1
cd $SCRIPT_DIR
. $IDEA_OUTPUT/env.cfg
# Expect MODULE_ROOTS, MODULE_NAMES, BOOT_JDK & SPEC to be set
if [ "x$MODULE_ROOTS" = "x" ] ; then
echo "FATAL: MODULE_ROOTS is empty" >&2; exit 1
fi
if [ "x$MODULE_NAMES" = "x" ] ; then
echo "FATAL: MODULE_NAMES is empty" >&2; exit 1
fi
if [ "x$BOOT_JDK" = "x" ] ; then
echo "FATAL: BOOT_JDK is empty" >&2; exit 1
fi
if [ "x$SPEC" = "x" ] ; then
echo "FATAL: SPEC is empty" >&2; exit 1
fi
if [ -d "$TOPLEVEL_DIR/.hg" ] ; then
VCS_TYPE="hg4idea"
fi
# Git worktrees use a '.git' file rather than directory, so test both.
if [ -d "$TOPLEVEL_DIR/.git" -o -f "$TOPLEVEL_DIR/.git" ] ; then
VCS_TYPE="Git"
fi
### Replace template variables
NUM_REPLACEMENTS=0
replace_template_file() {
for i in $(seq 1 $NUM_REPLACEMENTS); do
eval "sed \"s|\${FROM${i}}|\${TO${i}}|g\" $1 > $1.tmp"
mv $1.tmp $1
done
}
replace_template_dir() {
for f in `find $1 -type f` ; do
replace_template_file $f
done
}
add_replacement() {
NUM_REPLACEMENTS=`expr $NUM_REPLACEMENTS + 1`
eval FROM$NUM_REPLACEMENTS='$1'
eval TO$NUM_REPLACEMENTS='$2'
}
add_replacement "###MODULE_NAMES###" "$MODULE_NAMES"
add_replacement "###VCS_TYPE###" "$VCS_TYPE"
SPEC_DIR=`dirname $SPEC`
if [ "x$CYGPATH" != "x" ]; then
add_replacement "###BUILD_DIR###" "`$CYGPATH -am $SPEC_DIR`"
add_replacement "###IMAGES_DIR###" "`$CYGPATH -am $SPEC_DIR`/images/jdk"
add_replacement "###ROOT_DIR###" "`$CYGPATH -am $TOPLEVEL_DIR`"
add_replacement "###IDEA_DIR###" "`$CYGPATH -am $IDEA_OUTPUT`"
if [ "x$JT_HOME" = "x" ]; then
add_replacement "###JTREG_HOME###" ""
else
add_replacement "###JTREG_HOME###" "`$CYGPATH -am $JT_HOME`"
fi
elif [ "x$WSL_DISTRO_NAME" != "x" ]; then
add_replacement "###BUILD_DIR###" "`wslpath -am $SPEC_DIR`"
add_replacement "###IMAGES_DIR###" "`wslpath -am $SPEC_DIR`/images/jdk"
add_replacement "###ROOT_DIR###" "`wslpath -am $TOPLEVEL_DIR`"
add_replacement "###IDEA_DIR###" "`wslpath -am $IDEA_OUTPUT`"
if [ "x$JT_HOME" = "x" ]; then
add_replacement "###JTREG_HOME###" ""
else
add_replacement "###JTREG_HOME###" "`wslpath -am $JT_HOME`"
fi
else
add_replacement "###BUILD_DIR###" "$SPEC_DIR"
add_replacement "###JTREG_HOME###" "$JT_HOME"
add_replacement "###IMAGES_DIR###" "$SPEC_DIR/images/jdk"
add_replacement "###ROOT_DIR###" "$TOPLEVEL_DIR"
add_replacement "###IDEA_DIR###" "$IDEA_OUTPUT"
fi
SOURCE_PREFIX="<sourceFolder url=\"file://"
SOURCE_POSTFIX="\" isTestSource=\"false\" />"
for root in $MODULE_ROOTS; do
if [ "x$CYGPATH" != "x" ]; then
root=`$CYGPATH -am $root`
elif [ "x$WSL_DISTRO_NAME" != "x" ]; then
root=`wslpath -am $root`
fi
SOURCES=$SOURCES" $SOURCE_PREFIX""$root""$SOURCE_POSTFIX"
done
add_replacement "###SOURCE_ROOTS###" "$SOURCES"
replace_template_dir "$IDEA_OUTPUT"
### Compile the custom Logger
CLASSES=$IDEA_OUTPUT/classes
if [ "x$ANT_HOME" = "x" ] ; then
# try some common locations
if [ -f "/usr/share/ant/lib/ant.jar" ] ; then
ANT_HOME="/usr/share/ant"
else
try_ant=$(ls /opt/homebrew/Cellar/ant/*/libexec/lib/ant.jar 2> /dev/null | sort -r | head -n 1)
if [ "x$try_ant" != "x" ] ; then
ANT_HOME=$(cd $(dirname $try_ant)/.. && pwd)
else
try_ant=$(ls /usr/local/Cellar/ant/*/libexec/lib/ant.jar 2> /dev/null | sort -r | head -n 1)
if [ "x$try_ant" != "x" ] ; then
ANT_HOME=$(cd $(dirname $try_ant)/.. && pwd)
fi
fi
fi
else
if [ ! -f "$ANT_HOME/lib/ant.jar" ] ; then
echo "FATAL: ANT_HOME is incorrect. Try removing it and use autodetection, or fix the value" >&2; exit 1
fi
fi
if [ "x$ANT_HOME" = "x" ] ; then
echo "FATAL: cannot find ant. Try setting ANT_HOME." >&2; exit 1
fi
CP=$ANT_HOME/lib/ant.jar
rm -rf $CLASSES; mkdir $CLASSES
# If we have a Windows boot JDK, we need a .exe suffix
if [ -e "$BOOT_JDK/bin/java.exe" ] ; then
JAVAC=javac.exe
else
JAVAC=javac
fi
# If we are on WSL, the boot JDK might be either Windows or Linux,
# and we need to use realpath instead of CYGPATH to make javac work on both.
# We need to handle this case first since CYGPATH might be set on WSL.
if [ "x$WSL_DISTRO_NAME" != "x" ]; then
JAVAC_SOURCE_FILE=`realpath --relative-to=./ $IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java`
JAVAC_SOURCE_PATH=`realpath --relative-to=./ $IDEA_OUTPUT/src`
JAVAC_CLASSES=`realpath --relative-to=./ $CLASSES`
ANT_TEMP=`mktemp -d -p ./`
cp $ANT_HOME/lib/ant.jar $ANT_TEMP/ant.jar
JAVAC_CP=$ANT_TEMP/ant.jar
elif [ "x$CYGPATH" != "x" ] ; then ## CYGPATH may be set in env.cfg
JAVAC_SOURCE_FILE=`$CYGPATH -am $IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java`
JAVAC_SOURCE_PATH=`$CYGPATH -am $IDEA_OUTPUT/src`
JAVAC_CLASSES=`$CYGPATH -am $CLASSES`
JAVAC_CP=`$CYGPATH -am $CP`
else
JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java
JAVAC_SOURCE_PATH=$IDEA_OUTPUT/src
JAVAC_CLASSES=$CLASSES
JAVAC_CP=$CP
fi
$BOOT_JDK/bin/$JAVAC -d $JAVAC_CLASSES -sourcepath $JAVAC_SOURCE_PATH -cp $JAVAC_CP $JAVAC_SOURCE_FILE
if [ "x$WSL_DISTRO_NAME" != "x" ]; then
rm -rf $ANT_TEMP
fi

197
bin/jib.sh Normal file
View file

@ -0,0 +1,197 @@
#!/bin/bash
#
# Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# This script installs the JIB tool into it's own local repository and
# puts a wrapper scripts into <source-root>/.jib
mydir="$(dirname "${BASH_SOURCE[0]}")"
myname="$(basename "${BASH_SOURCE[0]}")"
installed_jib_script=${mydir}/../.jib/jib
install_data=${mydir}/../.jib/.data
setup_url() {
if [ -f ~/.config/jib/jib.conf ]; then
source ~/.config/jib/jib.conf
fi
jib_repository="jdk-virtual"
jib_organization="jpg/infra/builddeps"
jib_module="jib"
jib_revision="3.0-SNAPSHOT"
jib_ext="jib.sh.gz"
closed_script="${mydir}/../../closed/make/conf/jib-install.conf"
if [ -f "${closed_script}" ]; then
source "${closed_script}"
fi
if [ -n "${JIB_SERVER}" ]; then
jib_server="${JIB_SERVER}"
fi
if [ -n "${JIB_SERVER_MIRRORS}" ]; then
jib_server_mirrors="${JIB_SERVER_MIRRORS}"
fi
if [ -n "${JIB_REPOSITORY}" ]; then
jib_repository="${JIB_REPOSITORY}"
fi
if [ -n "${JIB_ORGANIZATION}" ]; then
jib_organization="${JIB_ORGANIZATION}"
fi
if [ -n "${JIB_MODULE}" ]; then
jib_module="${JIB_MODULE}"
fi
if [ -n "${JIB_REVISION}" ]; then
jib_revision="${JIB_REVISION}"
fi
if [ -n "${JIB_EXTENSION}" ]; then
jib_extension="${JIB_EXTENSION}"
fi
if [ -n "${JIB_URL}" ]; then
jib_url="${JIB_URL}"
data_string="${jib_url}"
else
jib_path="${jib_repository}/${jib_organization}/${jib_module}/${jib_revision}/${jib_module}-${jib_revision}.${jib_ext}"
data_string="${jib_path}"
jib_url="${jib_server}/${jib_path}"
fi
}
install_jib() {
if [ -z "${jib_server}" -a -z "${JIB_URL}" ]; then
echo "No jib server or URL provided, set either"
echo "JIB_SERVER=<base server address>"
echo "or"
echo "JIB_URL=<full path to install script>"
exit 1
fi
if command -v curl > /dev/null; then
getcmd="curl -s -L --retry 3 --retry-delay 5"
elif command -v wget > /dev/null; then
getcmd="wget --quiet -O -"
else
echo "Could not find either curl or wget"
exit 1
fi
if ! command -v gunzip > /dev/null; then
echo "Could not find gunzip"
exit 1
fi
echo "Downloading JIB bootstrap script"
mkdir -p "${installed_jib_script%/*}"
rm -f "${installed_jib_script}.gz"
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
if [ ! -s "${installed_jib_script}.gz" ]; then
echo "Failed to download ${jib_url}"
if [ -n "${jib_path}" -a -n "${jib_server_mirrors}" ]; then
OLD_IFS="${IFS}"
IFS=" ,"
for mirror in ${jib_server_mirrors}; do
echo "Trying mirror ${mirror}"
jib_url="${mirror}/${jib_path}"
${getcmd} ${jib_url} > "${installed_jib_script}.gz"
if [ -s "${installed_jib_script}.gz" ]; then
echo "Download from mirror successful"
break
else
echo "Failed to download ${jib_url}"
fi
done
IFS="${OLD_IFS}"
fi
if [ ! -s "${installed_jib_script}.gz" ]; then
exit 1
fi
fi
# Want to check the filetype using file, to see if we got served a HTML error page.
# This is sensitive to the filename containing a specific string, but good enough.
file "${installed_jib_script}.gz" | grep "gzip compressed data" > /dev/null
if [ $? -ne 0 ]; then
echo "Warning: ${installed_jib_script}.gz is not a gzip file."
echo "If you are behind a proxy you may need to configure exceptions using no_proxy."
echo "The download URL was: ${jib_url}"
exit 1
fi
echo "Extracting JIB bootstrap script"
rm -f "${installed_jib_script}"
gunzip "${installed_jib_script}.gz"
chmod +x "${installed_jib_script}"
echo "${data_string}" > "${install_data}"
}
# Returns a shell-escaped version of the argument given.
shell_quote() {
if [[ -n "$1" ]]; then
# Uses only shell-safe characters? No quoting needed.
# '=' is a zsh meta-character, but only in word-initial position.
if echo "$1" | grep '^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\.:,%/+=_-]\{1,\}$' > /dev/null \
&& ! echo "$1" | grep '^=' > /dev/null; then
quoted="$1"
else
if echo "$1" | grep "[\'!]" > /dev/null; then
# csh does history expansion within single quotes, but not
# when backslash-escaped!
local quoted_quote="'\\''" quoted_exclam="'\\!'"
word="${1//\'/${quoted_quote}}"
word="${1//\!/${quoted_exclam}}"
fi
quoted="'$1'"
fi
echo "$quoted"
fi
}
# Main body starts here
setup_url
if [ ! -x "${installed_jib_script}" ]; then
install_jib
elif [ ! -e "${install_data}" ] || [ "${data_string}" != "$(cat "${install_data}")" ]; then
echo "Install url changed since last time, reinstalling"
install_jib
fi
# Provide a reasonable default for the --src-dir parameter if run out of tree
if [ -z "${JIB_SRC_DIR}" ]; then
export JIB_SRC_DIR="${mydir}/../"
fi
# Save the original command line
conf_quoted_arguments=()
for conf_option; do
conf_quoted_arguments=("${conf_quoted_arguments[@]}" "$(shell_quote "$conf_option")")
done
export REAL_CONFIGURE_COMMAND_LINE="${conf_quoted_arguments[@]}"
myfulldir="$(cd "${mydir}" > /dev/null && pwd)"
export REAL_CONFIGURE_COMMAND_EXEC_FULL="$BASH $myfulldir/$myname"
export REAL_CONFIGURE_COMMAND_EXEC_SHORT="$myname"
${installed_jib_script} "$@"

224
bin/lic_check.sh Normal file
View file

@ -0,0 +1,224 @@
#! /bin/sh -f
#
# Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# This script checks a copyright notice.
#
# The script should be located in the main jdk repository under make/scripts.
# It works with the templates in the make/data/license-templates directory of the jdk source.
#
# Usage: "lic_check.sh [-gpl] or [-gplcp] or [-bsd] file(s)"
script_directory=`dirname $0`
script_name=`basename $0`
first_option=$1
# parse the first argument
case "$1" in
"-gpl")
header="gpl-header"
;;
"-gplcp")
header="gpl-cp-header"
;;
"-bsd")
header="bsd-header"
;;
*)
echo "Usage: $0 [-gpl] or [-gplcp] or [-bsd] file(s)" 1>&2
exit 1
;;
esac
shift
#initialize error status
error_status=0
# determine and set the absolute path for the script directory
D=`dirname "${script_directory}"`
B=`basename "${script_directory}"`
script_dir="`cd \"${D}\" 2>/dev/null && pwd || echo \"${D}\"`/${B}"
# set up a variable for the template directory
template_dir=${script_dir}/../make/data/license-templates
# Check existence of the template directory.
if [ ! -d ${template_dir} ] ; then
echo "ERROR: The template directory "${template_dir}" doesn't exist." 1>&2
exit 1
fi
# set the temporary file location
tmpfile=/tmp/source_file.$$
rm -f ${tmpfile}
# check number of lines in the template file
lines=`cat ${template_dir}/${header} | wc -l`
# the template file has one empty line at the end, we need to ignore it
lines=`expr ${lines} - 1`
# A loop through the all script parameters:
#
# 1. Given a set of source files and a license template header, read a file name of each source file.
# 2. Check if a given file exists. When a directory is encountered, dive in and process all sources in those directories.
# 3. Read each line of the given file and check it for a copyright string.
# 4. If a copyright string found, check the correctness of the years format in the string and replace years with %YEARS%.
# 5. Continue reading the file until the number of lines is equal to the length of the license template header ($lines) and remove a comment prefix for each line.
# 6. Store the result (the license header from a given file) into a temporary file.
# 7. If a temporary file is not empty, compare it with a template file to verify if the license text is the same as in a template.
# 8. Produce a error in case a temporary file is empty, it means we didn't find a copyright string, or it's not correct
#
while [ "$#" -gt "0" ] ; do
touch ${tmpfile}
# In case of the directory as a parameter check recursively every file inside.
if [ -d $1 ] ; then
curdir=`pwd`
cd $1
echo "*** Entering directory: "`pwd`
echo "***"
files=`ls .`
sh ${script_dir}/${script_name} ${first_option} ${files}
status=$?
if [ ${error_status} -ne 1 ] ; then
error_status=${status}
fi
cd ${curdir}
shift
continue
else
echo "### Checking copyright notice in the file: "$1
echo "###"
fi
# Check the existence of the source file.
if [ ! -f $1 ] ; then
echo "ERROR: The source file "$1" doesn't exist." 1>&2
error_status=1
shift
continue
fi
# read the source file and determine where the header starts, then get license header without prefix
counter=0
while read line ; do
# remove windows "line feed" character from the line (if any)
line=`echo "${line}" | tr -d '\r'`
# check if the given line contains copyright
check_copyright=`echo "${line}" | grep "Copyright (c) "`
if [ "${check_copyright}" != "" ] ; then
# determine the comment prefix
prefix=`echo "${line}" | cut -d "C" -f 1`
# remove prefix (we use "_" as a sed delimiter, since the prefix could be like //)
copyright_without_prefix=`echo "${line}" | sed s_"^${prefix}"__g`
# copyright years
year1=`echo "${copyright_without_prefix}" | cut -d " " -f 3`
year2=`echo "${copyright_without_prefix}" | cut -d " " -f 4`
# Processing the first year in the copyright string
length=`expr "${year1}" : '.*'`
if [ ${length} -ne 5 ] ; then
break
fi
check_year1=`echo ${year1} | egrep "19[0-9][0-9],|2[0-9][0-9][0-9],"`
if [ "${check_year1}" = "" ] ; then
break
fi
# Processing the second year in the copyright string
if [ "${year2}" != "Oracle" ] ; then
length=`expr "${year2}" : '.*'`
if [ ${length} -ne 5 ] ; then
break
else
check_year2=`echo ${year2} | egrep "19[0-9][0-9],|2[0-9][0-9][0-9],"`
if [ "${check_year2}" = "" ] ; then
break
fi
fi
fi
# copyright string without copyright years
no_years=`echo "${copyright_without_prefix}" | sed 's/[0-9,]*//g'`
# copyright string before years
before_years=`echo "${no_years}" | cut -d "O" -f 1`
# copyright string after years
after_years=`echo "${no_years}" | cut -d ")" -f 2`
# form a new copyright string with %YEARS%
new_copyright=`echo ${before_years}"%YEARS%"${after_years}`
# save the new copyright string to a file
echo "${new_copyright}" > ${tmpfile}
# start counting the lines
counter=1
# move to the next line
continue
fi
if [ ${counter} -ne 0 ] ; then
# this should be a license header line, hence increment counter
counter=`expr ${counter} + 1`
# record a string without a prefix to a file
newline=`echo "${line}" | sed s_"^${prefix}"__`
# we need to take care of the empty lines in the header, i.e. check the prefix without spaces
trimmed_prefix=`echo "${prefix}" | tr -d " "`
trimmed_line=`echo "${line}" | tr -d " "`
if [ "${trimmed_line}" = "${trimmed_prefix}" ] ; then
echo "" >> ${tmpfile}
else
echo "${newline}" >> ${tmpfile}
fi
fi
# stop reading lines when a license header ends and add an empty line to the end
if [ ${counter} -eq ${lines} ] ; then
echo "" >> ${tmpfile}
break
fi
done < $1
# compare the license header with a template file
if [ -s ${tmpfile} ] ; then
diff -c ${tmpfile} ${template_dir}/${header} 1>&2
if [ "$?" = "0" ] ; then
echo "SUCCESS: The license header for "`pwd`"/"$1" has been verified."
echo "###"
else
echo "ERROR: License header is not correct in "`pwd`"/"$1 1>&2
echo "See diffs above. " 1>&2
echo "###" 1>&2
echo "" 1>&2
error_status=1
fi
else
# If we don't have a temporary file, there is a problem with a copyright string (or no copyright string)
echo "ERROR: Copyright string is not correct or missing in "`pwd`"/"$1 1>&2
echo "###" 1>&2
echo "" 1>&2
error_status=1
fi
rm -f ${tmpfile}
shift
done
if [ ${error_status} -ne 0 ] ; then
exit 1
fi

206
bin/normalizer.pl Normal file
View file

@ -0,0 +1,206 @@
#!/usr/bin/perl
#
# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Parses java files:
# 1. Removes from the end of lines spaces and TABs
# 2. Replaces TABs by spaces
# 3. Replaces all NewLine separators by Unix NewLine separators
# 4. Makes one and only one empty line at the end of each file
if ($#ARGV < 0) {
&usage;
die;
}
use Cwd 'abs_path';
my @extensions = ("java");
# Read options
my $dirpos = 0;
while ($dirpos < $#ARGV) {
if ($ARGV[$dirpos] eq "-e") {
@extensions = split(/,/, $ARGV[$dirpos + 1]);
} else {
last;
}
$dirpos += 2;
}
if ($dirpos > $#ARGV) {
&usage;
die;
}
use Cwd;
my $currdir = getcwd;
my $allfiles = 0;
my $filecount = 0;
my @tabvalues;
# Init tabvalues
push (@tabvalues, " ");
for (my $i = 1; $i < 8; $i++) {
push(@tabvalues, $tabvalues[$i - 1] . " ");
}
open(FILELIST, ">$currdir/filelist") or die "Failed while open $currdir/filelist: $!\n";
while ($dirpos <= $#ARGV) {
use File::Find;
find(\&parse_file, abs_path($ARGV[$dirpos]));
$dirpos += 1;
}
close(FILELIST);
use Cwd 'chdir';
chdir $currdir;
print "Checked $allfiles file(s)\n";
print "Modified $filecount file(s)\n";
print "See results in the file $currdir/filelist\n";
sub parse_file {
my $filename = $File::Find::name;
# Skip directories
return if -d;
# Skip SCCS files
return if ($filename =~ /\/SCCS\//);
# Skip files with invalid extensions
my $accepted = 0;
foreach my $ext (@extensions) {
if ($_ =~ /\.$ext$/i) {
$accepted = 1;
last;
}
}
return if ($accepted == 0);
use File::Basename;
my $dirname = dirname($filename);
use Cwd 'chdir';
chdir $dirname;
open(FILE, $filename) or die "Failed while open $filename: $!\n";
# Read file
my @content;
my $line;
my $emptylinescount = 0;
my $modified = 0;
while ($line = <FILE>) {
my $originalline = $line;
# Process line
# Remove from the end of the line spaces and return character
while ($line =~ /\s$/) {
chop($line);
}
# Replace TABs
for (my $i = 0; $i < length($line); $i++) {
if (substr($line, $i, 1) =~ /\t/) {
$line = substr($line, 0, $i) . $tabvalues[7 - ($i % 8)] . substr($line, $i + 1);
}
}
if (length($line) == 0) {
$emptylinescount++;
} else {
while ($emptylinescount > 0) {
push(@content, "");
$emptylinescount--;
}
push(@content, $line);
}
if ($originalline ne ($line . "\n")) {
$modified = 1;
}
}
$allfiles++;
if ($emptylinescount > 0) {
$modified = 1;
}
close(FILE);
if ($modified != 0) {
# Write file
open(FILE, ">$filename") or die "Failed while open $filename: $!\n";
for (my $i = 0; $i <= $#content; $i++) {
print FILE "$content[$i]\n";
}
close(FILE);
# Print name from current dir
if (index($filename, $currdir) == 0) {
print FILELIST substr($filename, length($currdir) + 1);
} else {
print FILELIST $filename;
}
print FILELIST "\n";
$filecount++;
print "$filename: modified\n";
}
}
sub usage {
print "Usage:\n";
print " normalizer.pl [-options] <dir> [dir2 dir3 ...]\n";
print " Available options:\n";
print " -e comma separated files extensions. By default accepts only java files\n";
print "\n";
print "Examples:\n";
print " normalizer.pl -e c,cpp,h,hpp .\n";
}

View file

@ -0,0 +1,295 @@
#!/bin/bash -f
#
# Copyright (c) 2010, 2026, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# Script to update the Copyright YEAR range in Git sources.
# (Originally from xdono, Thanks!)
# To update Copyright years for changes in a specific branch,
# you use a command along these lines:
# $ git diff upstream/master...<branch-name> | lsdiff | cut -d '/' -f 2- | bash bin/update_copyright_year.sh -m -
#------------------------------------------------------------
copyright="Copyright"
copyright_symbol="(c)"
company="Oracle"
year=`date +%Y`
#------------------------------------------------------------
awk="awk"
# Stop on any error
set -e
# To allow total changes counting
shopt -s lastpipe
# Temp area
tmp=/tmp/`basename $0`.${USER}.$$
rm -f -r ${tmp}
mkdir -p ${tmp}
total=0
usage="Usage: `basename "$0"` [-c company] [-y year] [-m file] [-h|f]"
Help()
{
# Display Help
echo "Updates the Copyright year range in Git sources."
echo
echo "By default, the tool limits the processed changesets "
echo "to those in the current branch and the current year."
echo
echo "Note, cancelling the script will skip cleanup in /tmp."
echo
echo $usage
echo "options:"
echo "-c Specifies the company. Set to Oracle by default."
echo "-y Specifies the copyright year. Set to current year by default."
echo "-b Specifies the base reference for change set lookup."
echo "-f Updates the copyright for all change sets in a given year,"
echo " as specified by -y. Overrides -b flag."
echo "-m Read the list of modified files from the given file,"
echo " use - to read from stdin"
echo "-h Print this help."
echo
}
full_year=false
base_reference=master
modified_files_origin="";
# Process options
while getopts "b:c:fhm:y:" option; do
case $option in
b) # supplied base reference
base_reference=${OPTARG}
;;
c) # supplied company year
company=${OPTARG}
;;
f) # update all change sets in a full year
full_year=true
;;
h) # display help
Help
exit 0
;;
y) # supplied company year
year=${OPTARG}
;;
m) # modified files will be read from the given origin
modified_files_origin="${OPTARG}"
;;
\?) # illegal option
echo "$usage"
exit 1
;;
esac
done
# VCS check
git_installed=false
which git > /dev/null && git_installed=true
if [ "$git_installed" != "true" ]; then
echo "Error: This script requires git. Please install it."
exit 1
fi
git_found=false
git status &> /dev/null && git_found=true
if [ "$git_found" != "true" ]; then
echo "Error: Please execute script from within a JDK git repository."
exit 1
fi
echo "Using Git version control system"
# Return true if it makes sense to edit this file
saneFileToCheck()
{
if [ "$1" != "" -a -f $1 ] ; then
isText=`file "$1" | grep -i -E '(text|source)' | cat`
hasCopyright=`grep 'Copyright' "$1" | cat`
lastLineCount=`tail -1 "$1" | wc -l`
if [ "${isText}" != "" \
-a "${hasCopyright}" != "" \
-a ${lastLineCount} -eq 1 ] ; then
echo "true"
else
echo "false"
fi
else
echo "false"
fi
}
# Update the copyright year on a file
updateFile() # file
{
changed="false"
if [ `saneFileToCheck "$1"` = "true" ] ; then
rm -f $1.OLD
mv $1 $1.OLD
cat $1.OLD | \
sed -e "s@\(${copyright} \(${copyright_symbol} \)\{0,1\}[12][0-9][0-9][0-9],\) [12][0-9][0-9][0-9], ${company}@\1 ${year}, ${company}@" | \
sed -e "s@\(${copyright} \(${copyright_symbol} \)\{0,1\}[12][0-9][0-9][0-9],\) [12][0-9][0-9][0-9] ${company}@\1 ${year} ${company}@" | \
sed -e "s@\(${copyright} \(${copyright_symbol} \)\{0,1\}[12][0-9][0-9][0-9],\) ${company}@\1 ${year}, ${company}@" | \
sed -e "s@\(${copyright} \(${copyright_symbol} \)\{0,1\}[12][0-9][0-9][0-9],\) ${company}@\1, ${year}, ${company}@" | \
sed -e "s@\(${copyright} \(${copyright_symbol} \)\{0,1\}[12][0-9][0-9][0-9]\) ${company}@\1, ${year} ${company}@" | \
sed -e "s@${copyright} ${year}, ${year}, ${company}@${copyright} ${year}, ${company}@" | \
sed -e "s@${copyright} ${copyright_symbol} ${year}, ${year}, ${company}@${copyright} ${copyright_symbol} ${year}, ${company}@" \
> $1
if ! diff -b -w $1.OLD $1 > /dev/null ; then \
changed="true"
rm -f $1.OLD
else
rm -f $1
mv $1.OLD $1
fi
fi
echo "${changed}"
}
# Update the copyright year on files sent in stdin
updateFiles() # stdin: list of files to update
{
count=0
fcount=0
while read i; do
fcount=`expr ${fcount} '+' 1`
if [ `updateFile "${i}"` = "true" ] ; then
count=`expr ${count} '+' 1`
fi
done
if [ ${count} -gt 0 ] ; then
printf " UPDATED year on %d of %d files.\n" ${count} ${fcount}
total=`expr ${total} '+' ${count}`
else
printf " None of the %d files were changed.\n" ${fcount}
fi
}
# Update the copyright year on all files changed by this changeset
updateChangesetFiles() # changeset
{
count=0
files=${tmp}/files.$1
rm -f ${files}
"${vcs_changeset_files[@]}" "$1" | expand \
| ${awk} -F' ' '{for(i=1;i<=NF;i++)print $i}' \
> ${files}
if [ -f "${files}" -a -s "${files}" ] ; then
cat ${files} | updateFiles
else
printf " ERROR: No files changed in the changeset? Must be a mistake.\n"
set -x
ls -al ${files}
"${vcs_changeset_files[@]}" "$1"
"${vcs_changeset_files[@]}" "$1" | expand \
| ${awk} -F' ' '{for(i=1;i<=NF;i++)print $i}'
set +x
exit 1
fi
rm -f ${files}
}
# Check if repository is clean
vcs_status=(git ls-files -m)
previous=`"${vcs_status[@]}"|wc -l`
if [ ${previous} -ne 0 ] ; then
echo "WARNING: This repository contains previously edited working set files."
echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`"
fi
if [ "x$modified_files_origin" != "x" ]; then
cat $modified_files_origin | updateFiles
else
# Get all changesets this year
if [ "$full_year" = "true" ]; then
vcs_list_changesets=(git log --no-merges --since="${year}-01-01T00:00:00Z" --until="${year}-12-31T23:59:59Z" --pretty=tformat:"%H")
else
vcs_list_changesets=(git log --no-merges "${base_reference}..HEAD" --since="${year}-01-01T00:00:00Z" --until="${year}-12-31T23:59:59Z" --pretty=tformat:"%H")
fi
vcs_changeset_message=(git log -1 --pretty=tformat:"%B") # followed by ${changeset}
vcs_changeset_files=(git diff-tree --no-commit-id --name-only -r) # followed by ${changeset}
all_changesets=${tmp}/all_changesets
rm -f ${all_changesets}
"${vcs_list_changesets[@]}" > ${all_changesets}
# Check changeset to see if it is Copyright only changes, filter changesets
if [ -s ${all_changesets} ] ; then
echo "Changesets made in ${year}: `cat ${all_changesets} | wc -l`"
index=0
cat ${all_changesets} | while read changeset ; do
index=`expr ${index} '+' 1`
desc=${tmp}/desc.${changeset}
rm -f ${desc}
echo "------------------------------------------------"
"${vcs_changeset_message[@]}" "${changeset}" > ${desc}
printf "%d: %s\n%s\n" ${index} "${changeset}" "`cat ${desc}|head -1`"
if [ "${year}" = "2010" ] ; then
if cat ${desc} | grep -i -F "Added tag" > /dev/null ; then
printf " EXCLUDED tag changeset.\n"
elif cat ${desc} | grep -i -F rebrand > /dev/null ; then
printf " EXCLUDED rebrand changeset.\n"
elif cat ${desc} | grep -i -F copyright > /dev/null ; then
printf " EXCLUDED copyright changeset.\n"
else
updateChangesetFiles ${changeset}
fi
else
if cat ${desc} | grep -i -F "Added tag" > /dev/null ; then
printf " EXCLUDED tag changeset.\n"
elif cat ${desc} | grep -i -F "copyright year" > /dev/null ; then
printf " EXCLUDED copyright year changeset.\n"
else
updateChangesetFiles ${changeset}
fi
fi
rm -f ${desc}
done
fi
if [ ${total} -gt 0 ] ; then
echo "---------------------------------------------"
echo "Updated the copyright year on a total of ${total} files."
if [ ${previous} -eq 0 ] ; then
echo "This count should match the count of modified files in the repository: ${vcs_status[*]}"
else
echo "WARNING: This repository contained previously edited working set files."
fi
echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`"
else
echo "---------------------------------------------"
echo "No files were changed"
if [ ${previous} -ne 0 ] ; then
echo "WARNING: This repository contained previously edited working set files."
fi
echo " ${vcs_status[*]} | wc -l = `"${vcs_status[@]}" | wc -l`"
fi
fi
# Cleanup
rm -f -r ${tmp}
exit 0

111
bin/update_pch.sh Normal file
View file

@ -0,0 +1,111 @@
#!/bin/sh
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
# The output of this script may require some degree of human curation:
# - Redundant headers, e.g. both x.hpp, x.inline.hpp are included;
# - Headers relative to a non-default feature should be protected by an
# appropriate 'if' clause to make sure all variants can build without
# errors.
source_path="$(dirname ${0})"
this_script_dir="$(cd -- "${source_path}" > /dev/null && pwd)"
if test -z "${this_script_dir}"; then
echo "Error: Could not determine location of this script"
exit 1
fi
# Work in top directory
cd $this_script_dir/..
# Time threshold for header compilation, if the time exceeds the
# threshold the header will be precompiled.
if [ -z "$MIN_MS" ]; then
MIN_MS=100000
fi
if [ -z "$CLEAN" ]; then
CLEAN=true
elif [ "$CLEAN" != "true" ] && [ "$CLEAN" != "false" ]; then
echo "Expected either 'true' or 'false' for CLEAN"
fi
# CBA_PATH should point to a valid ClangBuildAnalyzer executable.
# Build steps:
# git clone --depth 1 git@github.com:aras-p/ClangBuildAnalyzer.git
# cd ClangBuildAnalyzer
# make -f projects/make/Makefile
if [ -z "$CBA_PATH" ]; then
CBA_PATH="./ClangBuildAnalyzer/build/ClangBuildAnalyzer"
fi
set -eux
PRECOMPILED_HPP="src/hotspot/share/precompiled/precompiled.hpp"
CBA_CONFIG="ClangBuildAnalyzer.ini"
TIMESTAMP="$(date +%Y%m%d-%H%M)"
RUN_NAME="pch_update_$TIMESTAMP"
CBA_OUTPUT="cba_out_$TIMESTAMP"
if [ "$CLEAN" = "true" ]; then
trap 'rm -rf "build/'"$RUN_NAME"'" "$CBA_OUTPUT" "$CBA_CONFIG"' EXIT
fi
sh configure --with-toolchain-type=clang \
--with-conf-name="$RUN_NAME" \
--disable-precompiled-headers \
--with-extra-cxxflags="-ftime-trace" \
--with-extra-cflags="-ftime-trace"
make clean CONF_NAME="$RUN_NAME"
make hotspot CONF_NAME="$RUN_NAME"
"$CBA_PATH" --all "./build/$RUN_NAME/hotspot/variant-server/libjvm/objs" \
"$CBA_OUTPUT"
# Preserve license and comments on top
cat "$PRECOMPILED_HPP" | awk '/^#include/ {exit} {print}' > "$PRECOMPILED_HPP.tmp"
if [ ! -f "$CBA_CONFIG" ]; then
cat <<EOF > "$CBA_CONFIG"
[counts]
header=100
headerChain=0
template=0
function=0
fileCodegen=0
fileParse=0
[misc]
onlyRootHeaders=true
EOF
fi
"$CBA_PATH" --analyze "$CBA_OUTPUT" | \
grep " ms: " | \
# Keep the headers more expensive than ${1}ms
awk -v x="$MIN_MS" '$1 < x { exit } { print $3 }' | \
# Filter away non-hotspot headers
grep hotspot/share | \
awk -F "hotspot/share/" '{ printf "#include \"%s\"\n", $2 }' \
>> "$PRECOMPILED_HPP.tmp"
mv "$PRECOMPILED_HPP.tmp" "$PRECOMPILED_HPP"
java test/hotspot/jtreg/sources/SortIncludes.java --update "$PRECOMPILED_HPP"