|  | #!/usr/bin/env bash | 
|  | # | 
|  | # Copyright (c) 2023, Arm Limited. All rights reserved. | 
|  | # | 
|  | # SPDX-License-Identifier: BSD-3-Clause | 
|  | # | 
|  |  | 
|  | # Include variables and functions to be used by these scripts | 
|  | source "$CI_ROOT/utils.sh" | 
|  | ################################################################################ | 
|  | # CI VARIABLES: | 
|  | # workspace, warehouse, artefacts | 
|  | # GLOBAL VARIABLES: | 
|  | # OUTDIR, PROJECT, FALLBACK_PLUGIN_URL, FALLBACK_FILES, PLUGIN_BINARY | 
|  | ################################################################################ | 
|  | # Defining constants | 
|  | GERRIT_URL=${GERRIT_URL:-https://gerrit.oss.arm.com} | 
|  | QA_REPO_USER=jenkins_auto | 
|  | QA_REPO_INTERNAL=${QA_REPO_INTERNAL:-https://${QA_REPO_USER}:${QA_REPO_TOKEN}@git.gitlab.arm.com/tooling/qa-tools-internal.git} | 
|  | QA_REPO_PUBLIC=${QA_REPO_PUBLIC:-https://git.gitlab.arm.com/tooling/qa-tools.git} | 
|  | QA_REPO_NAME=qa-tools | 
|  | # Internal globals | 
|  | CODE_COVERAGE_FOLDER="${OUTDIR:-$workspace}/qa-code-coverage" | 
|  | DEBUG_FOLDER=${artefacts}/debug | 
|  | RELEASE_FOLDER=${artefacts}/release | 
|  | TRACE_FILE_PREFIX=covtrace | 
|  | CONFIG_JSON=${CODE_COVERAGE_FOLDER}/configuration_file.json | 
|  | INTERMEDIATE_LAYER_FILE=${CODE_COVERAGE_FOLDER}/intermediate_layer.json | 
|  | INFO_FILE=${CODE_COVERAGE_FOLDER}/coverage.info | 
|  | REPORT_FOLDER=${CODE_COVERAGE_FOLDER}/lcov | 
|  |  | 
|  | QA_REPO=${QA_TOOLS_REPO:-$QA_REPO_PUBLIC} | 
|  | QA_REFSPEC=${QA_TOOLS_BRANCH:-$TEST_DEFINITIONS_TAG} | 
|  | QA_REFSPEC=${QA_REFSPEC:-stable} | 
|  |  | 
|  |  | 
|  | ################################################################################ | 
|  | # Deploy qa-tools into the current directory | 
|  | # GLOBALS: | 
|  | #   QA_REPO, QA_REPO_NAME, QA_REFSPEC | 
|  | # ARGUMENTS: | 
|  | #   None | 
|  | # OUTPUTS: | 
|  | #   Clones the qa-tools repo from the global variables with the given | 
|  | #   commit hash. | 
|  | # RETURN: | 
|  | #   0 if succeeds, non-zero on error. | 
|  | ################################################################################ | 
|  | deploy_qa_tools() { | 
|  | git clone "${QA_REPO}" ${QA_REPO_NAME} | 
|  | cd ${QA_REPO_NAME} && git checkout "${QA_REFSPEC}" && cd .. | 
|  | } | 
|  |  | 
|  |  | 
|  | ################################################################################ | 
|  | # Builds or downloads the QA Code Coverage Tool | 
|  | # GLOBALS: | 
|  | #   CODE_COVERAGE_FOLDER, QA_REPO, QA_REPO_NAME, QA_REFSPEC, FALLBACK_PLUGIN_URL | 
|  | # ARGUMENTS: | 
|  | #   None | 
|  | # OUTPUTS: | 
|  | #   Creates coverage folder and builds/downloads there the plugin binaries. | 
|  | #   It exports the binary plugin location to coverage_trace_plugin. | 
|  | # RETURN: | 
|  | #   0 if succeeds, non-zero on error. | 
|  | ################################################################################ | 
|  | build_tool() { | 
|  | echo "Building QA Code coverage tool..." | 
|  | PLUGIN_BINARY="${FALLBACK_FILES%%,*}" # The first in the list of the binary files | 
|  | local PVLIB_HOME="warehouse/SysGen/PVModelLib/$model_version/$model_build/external" | 
|  | local LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CODE_COVERAGE_FOLDER | 
|  | mkdir -p ${CODE_COVERAGE_FOLDER} | 
|  | pushd "${CODE_COVERAGE_FOLDER}" | 
|  | deploy_qa_tools | 
|  | local cc_source=$(find . -type f -name 'coverage_trace.cc') | 
|  | local fallback="wget -q ${FALLBACK_PLUGIN_URL}/{$FALLBACK_FILES}" | 
|  | echo "Warehouse=${warehouse}" | 
|  | eval "$fallback" | 
|  | ls -al | 
|  | export coverage_trace_plugin="${CODE_COVERAGE_FOLDER}/${PLUGIN_BINARY}" | 
|  | popd | 
|  | } | 
|  |  | 
|  | ################################################################################ | 
|  | # Creates configuration file for intermediate layer generation | 
|  | # GLOBALS: | 
|  | #   PROJECT, CONFIG_JSON, INTERMEDIATE_LAYER_FILE, CODE_COVERAGE_FOLDER | 
|  | # ARGUMENTS: | 
|  | #   $1 Folder where are the elf/axf files. | 
|  | #   $2 List of elf/axf file names. | 
|  | #   $3 Path for trace files. | 
|  | #   $4 Root folder name where all the repos are cloned. | 
|  | # OUTPUTS: | 
|  | #   Creates coverage folder and builds/downloads there the plugin binaries. | 
|  | # RETURN: | 
|  | #   0 if succeeds, non-zero on error. | 
|  | ################################################################################ | 
|  | create_config_json() { | 
|  | set +e | 
|  | if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] | 
|  | then | 
|  | cat << END | 
|  | Missing argument at '${FUNCNAME[0]}'. | 
|  | USAGE: | 
|  | create_config_json ' Glob binaries' 'Glob trace files' 'Repos root folder name' | 
|  | Example: | 
|  | create_config_json 'bl1.elf bl2.elf' 'tf' | 
|  | END | 
|  | exit 1 | 
|  | fi | 
|  | local ELF_FOLDER=$1 | 
|  | local dwarf_array=($2) | 
|  | local TRACE_FOLDER=$3 | 
|  | local root_repos_foolder="${4:-$workspace}" | 
|  | local scm_sources="" | 
|  |  | 
|  | # Obtaining binaries from array | 
|  | bin_section="" | 
|  | for index in "${!dwarf_array[@]}" | 
|  | do | 
|  | local elf_file="${ELF_FOLDER}/${dwarf_array[$index]}" | 
|  | cp "$elf_file" ${CODE_COVERAGE_FOLDER}/. | 
|  | read -r -d '' bin_section << EOM | 
|  | ${bin_section} | 
|  | { | 
|  | "name": "$elf_file", | 
|  | "traces": [ | 
|  | "${TRACE_FOLDER}/${TRACE_FILE_PREFIX:-covtrace}-*.log" | 
|  | ] | 
|  | } | 
|  | EOM | 
|  | if [ $index -lt $((${#dwarf_array[@]} - 1)) ];then | 
|  | bin_section="${bin_section}," | 
|  | fi | 
|  | done | 
|  |  | 
|  | if [ "$PROJECT" = "SCP" ]; then | 
|  | read -r -d '' scm_sources << EOM | 
|  | [ | 
|  | { | 
|  | "type": "git", | 
|  | "URL":  "$CC_SCP_URL", | 
|  | "COMMIT": "$CC_SCP_COMMIT", | 
|  | "REFSPEC": "$CC_SCP_REFSPEC", | 
|  | "LOCATION": "scp" | 
|  | }, | 
|  | { | 
|  | "type": "git", | 
|  | "URL":  "$CC_CMSIS_URL", | 
|  | "COMMIT": "$CC_CMSIS_COMMIT", | 
|  | "REFSPEC": "$CC_CMSIS_REFSPEC", | 
|  | "LOCATION": "scp/contrib/cmsis/git" | 
|  | } | 
|  | ] | 
|  | EOM | 
|  | elif [ "$PROJECT" = "TF-A" ]; then | 
|  | read -r -d '' scm_sources << EOM | 
|  | [ | 
|  | { | 
|  | "type": "git", | 
|  | "URL":  "$CC_TRUSTED_FIRMWARE_URL", | 
|  | "COMMIT": "$CC_TRUSTED_FIRMWARE_COMMIT", | 
|  | "REFSPEC": "$CC_TRUSTED_FIRMWARE_REFSPEC", | 
|  | "LOCATION": "trusted_firmware" | 
|  | }, | 
|  | { | 
|  | "type": "http", | 
|  | "URL":  "$mbedtls_archive", | 
|  | "COMPRESSION": "xz", | 
|  | "EXTRA_PARAMS": "--strip-components=1", | 
|  | "LOCATION": "mbedtls" | 
|  | } | 
|  | ] | 
|  | EOM | 
|  | elif [ "$PROJECT" = "HAFNIUM" ]; then | 
|  | read -r -d '' scm_sources << EOM | 
|  | [ | 
|  | { | 
|  | "type": "git", | 
|  | "URL":  "$CC_TRUSTED_FIRMWARE_URL", | 
|  | "COMMIT": "$CC_TRUSTED_FIRMWARE_COMMIT", | 
|  | "REFSPEC": "$CC_TRUSTED_FIRMWARE_REFSPEC", | 
|  | "LOCATION": "trusted_firmware" | 
|  | }, | 
|  | { | 
|  | "type": "git", | 
|  | "URL":  "$CC_SPM_URL", | 
|  | "COMMIT": "$CC_SPM_COMMIT", | 
|  | "REFSPEC": "$CC_SPM_REFSPEC", | 
|  | "LOCATION": "spm" | 
|  | } | 
|  | ] | 
|  | EOM | 
|  | else | 
|  | echo "SCM sources not provided for project '${PROJECT}'" | 
|  | exit 1 | 
|  | fi | 
|  | local metadata="\"BUILD_CONFIG\": \"${BUILD_CONFIG}\", \"RUN_CONFIG\": \"${RUN_CONFIG}\"" | 
|  | cat <<EOF > "${CONFIG_JSON}" | 
|  | { | 
|  | "configuration": | 
|  | { | 
|  | "remove_workspace": true, | 
|  | "include_assembly": true | 
|  | }, | 
|  | "parameters": | 
|  | { | 
|  | "objdump": "${OBJDUMP}", | 
|  | "readelf": "${READELF}", | 
|  | "sources": $scm_sources, | 
|  | "workspace": "${root_repos_foolder}", | 
|  | "output_file": "${INTERMEDIATE_LAYER_FILE}", | 
|  | "metadata": {$metadata} | 
|  | }, | 
|  | "elfs": [ | 
|  | ${bin_section} | 
|  | ] | 
|  | } | 
|  | EOF | 
|  |  | 
|  | } | 
|  |  | 
|  | ################################################################################ | 
|  | # Creates intermediate layer json file with trace coverage data. | 
|  | # | 
|  | # Creates a configuration JSON file to be the input for the intermediate | 
|  | # layer file creation. | 
|  | # GLOBALS: | 
|  | #   TRACE_FILE_PREFIX, CODE_COVERAGE_FOLDER | 
|  | # ARGUMENTS: | 
|  | #   $1 Location of trace files. | 
|  | #   $2 Location of elf/axf files. | 
|  | #   $3 List of binaries to be checked the traces. | 
|  | #   $4 Root folder name where all the repos are cloned. | 
|  | # OUTPUTS: | 
|  | #   A configuration JSON file. | 
|  | #   An intermediate layer JSON  file. | 
|  | # RETURN: | 
|  | #   0 if succeeds, non-zero on error. | 
|  | ################################################################################ | 
|  | create_intermediate_layer() { | 
|  | local TRACE_FOLDER="$1" | 
|  | local ELF_FOLDER="$2" | 
|  | local LIST_OF_BINARIES="$3" | 
|  | local root_repos_foolder="$4" | 
|  |  | 
|  | # Copying trace files into the qa-tools executables folder | 
|  | if [ $(ls -1 ${TRACE_FOLDER}/${TRACE_FILE_PREFIX}-* 2>/dev/null | wc -l) != 0 ]; then | 
|  | cp ${TRACE_FOLDER}/${TRACE_FILE_PREFIX}-* ${CODE_COVERAGE_FOLDER}/. | 
|  | else | 
|  | echo "Trace files not present, aborting reports..." | 
|  | ls -al ${TRACE_FOLDER} | 
|  | exit -1 | 
|  | fi | 
|  | create_config_json "${ELF_FOLDER}" "${LIST_OF_BINARIES}" "${TRACE_FOLDER}" "$root_repos_foolder" | 
|  | python3 ${CODE_COVERAGE_FOLDER}/qa-tools/coverage-tool/coverage-reporting/intermediate_layer.py \ | 
|  | --config-json ${CONFIG_JSON} | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | ################################################################################ | 
|  | # Creates LCOV coverage report. | 
|  | # GLOBALS: | 
|  | #   CODE_COVERAGE_FOLDER, workspace, INTERMEDIATE_LAYER_FILE, INFO_FILE, | 
|  | #   REPORT_FOLDER | 
|  | # ARGUMENTS: | 
|  | #   None | 
|  | # OUTPUTS: | 
|  | #   A coverage info file. | 
|  | #   LCOV HTML coverage report. | 
|  | # RETURN: | 
|  | #   0 if succeeds, non-zero on error. | 
|  | ################################################################################ | 
|  | create_coverage_report() { | 
|  | python3 ${CODE_COVERAGE_FOLDER}/qa-tools/coverage-tool/coverage-reporting/generate_info_file.py \ | 
|  | --workspace ${workspace} --json ${INTERMEDIATE_LAYER_FILE} --info ${INFO_FILE} | 
|  | genhtml --branch-coverage ${INFO_FILE} --output-directory ${REPORT_FOLDER} | 
|  | } |