Fix: Stop opteesp environment using default libc

The opteesp environment uses the libc implementation part of the
SPDEV-KIT. Projects targeting the opteesp environment shall be
configured to stop using the standard library and its header files
part of the compiler package.
This patch:
  - adds the missing compiler and linker options
  - adds header files missing from SPDEV-KITs libc implementation
  - extends the external component cmake files to align build options
    with the main project
  - moves environment specific mandatory flags to a common file
  - fixes the supported C standard from gnuc99 to c99

The following files where forked from TF-A
 (https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git; SHA: 7737fdf0ed):
- stdarg.h
- stdbool.h
- stddef.h
- stddef_.h

Signed-off-by: Andrew Beggs <andrew.beggs@arm.com>
Signed-off-by: Gyorgy Szing <Gyorgy.Szing@arm.com>
Change-Id: I3890453a29b003c60c8f44dfd19d553e96b1796c
diff --git a/deployments/attestation/opteesp/CMakeLists.txt b/deployments/attestation/opteesp/CMakeLists.txt
index 6852950..cd54450 100644
--- a/deployments/attestation/opteesp/CMakeLists.txt
+++ b/deployments/attestation/opteesp/CMakeLists.txt
@@ -85,16 +85,19 @@
 set(MBEDTLS_USER_CONFIG_FILE
 	"${TS_ROOT}/components/service/crypto/client/cpp/config_mbedtls_user.h"
 	CACHE STRING "Configuration file for mbedcrypto")
+list(APPEND MBEDTLS_EXTRA_INCLUDES ${SP_DEV_KIT_INCLUDE_DIR})
 
 # Mbed TLS provides libmbedcrypto
 include(../../../external/MbedTLS/MbedTLS.cmake)
 target_link_libraries(attestation PRIVATE mbedcrypto)
 
 # Qcbor
+set (QCBOR_EXTERNAL_INCLUDE_PATHS ${SP_DEV_KIT_INCLUDE_DIR})
 include(${TS_ROOT}/external/qcbor/qcbor.cmake)
 target_link_libraries(attestation PRIVATE qcbor)
 
 # t_cose
+set (TCOSE_EXTERNAL_INCLUDE_PATHS ${SP_DEV_KIT_INCLUDE_DIR})
 include(${TS_ROOT}/external/t_cose/t_cose.cmake)
 target_link_libraries(attestation PRIVATE t_cose)
 
@@ -117,19 +120,14 @@
 if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
 	target_compile_options(attestation PRIVATE
 		-fdiagnostics-show-option
-		-fpic
 		-gdwarf-2
 		-mstrict-align
 		-O0
-		-std=gnu99
+		-std=c99
 	)
 
 	# Options for GCC that control linking
 	target_link_options(attestation PRIVATE
-		-e __sp_entry
-		-fno-lto
-		-nostdlib
-		-pie
 		-zmax-page-size=4096
 	)
 	# Options directly for LD, these are not understood by GCC
diff --git a/deployments/crypto/opteesp/CMakeLists.txt b/deployments/crypto/opteesp/CMakeLists.txt
index 4eb1a51..8a857b8 100644
--- a/deployments/crypto/opteesp/CMakeLists.txt
+++ b/deployments/crypto/opteesp/CMakeLists.txt
@@ -81,11 +81,15 @@
 #-------------------------------------------------------------------------------
 
 # Nanopb
+list(APPEND NANOPB_EXTERNAL_INCLUDE_PATHS ${SP_DEV_KIT_INCLUDE_DIR})
 include(../../../external/nanopb/nanopb.cmake)
 target_link_libraries(crypto-sp PRIVATE nanopb::protobuf-nanopb-static)
 protobuf_generate_all(TGT "crypto-sp" NAMESPACE "protobuf" BASE_DIR "${TS_ROOT}/protocols")
 
 # Mbed TLS provides libmbedcrypto
+list(APPEND MBEDTLS_EXTRA_INCLUDES ${SP_DEV_KIT_INCLUDE_DIR})
+set(MBEDTLS_EXTRA_INCLUDES ${MBEDTLS_EXTRA_INCLUDES}
+	CACHE STRING "PSA ITS for Mbed TLS" FORCE)
 include(../../../external/MbedTLS/MbedTLS.cmake)
 target_link_libraries(crypto-sp PRIVATE mbedcrypto)
 
@@ -108,19 +112,14 @@
 if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
 	target_compile_options(crypto-sp PRIVATE
 		-fdiagnostics-show-option
-		-fpic
 		-gdwarf-2
 		-mstrict-align
 		-O0
-		-std=gnu99
+		-std=c99
 	)
 
 	# Options for GCC that control linking
 	target_link_options(crypto-sp PRIVATE
-		-e __sp_entry
-		-fno-lto
-		-nostdlib
-		-pie
 		-zmax-page-size=4096
 	)
 	# Options directly for LD, these are not understood by GCC
diff --git a/deployments/env-test/env_test.cmake b/deployments/env-test/env_test.cmake
index 9c0926b..ee46eba 100644
--- a/deployments/env-test/env_test.cmake
+++ b/deployments/env-test/env_test.cmake
@@ -44,5 +44,8 @@
 #-------------------------------------------------------------------------------
 
 # Mbed TLS provides libmbedcrypto
+list(APPEND MBEDTLS_EXTRA_INCLUDES ${SP_DEV_KIT_INCLUDE_DIR})
+set(MBEDTLS_EXTRA_INCLUDES ${MBEDTLS_EXTRA_INCLUDES}
+	CACHE STRING "PSA ITS for Mbed TLS" FORCE)
 include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
 target_link_libraries(env-test PRIVATE mbedcrypto)
diff --git a/deployments/env-test/opteesp/CMakeLists.txt b/deployments/env-test/opteesp/CMakeLists.txt
index 044fae0..1ec681b 100644
--- a/deployments/env-test/opteesp/CMakeLists.txt
+++ b/deployments/env-test/opteesp/CMakeLists.txt
@@ -85,20 +85,15 @@
 if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
 	target_compile_options(env-test PRIVATE
 		-fdiagnostics-show-option
-		-fpic
 		-gdwarf-2
 		-mstrict-align
 		-O0
-		$<$<COMPILE_LANGUAGE:C>:-std=gnu99>
+		$<$<COMPILE_LANGUAGE:C>:-std=c99>
 		$<$<COMPILE_LANGUAGE:CXX>:-fno-use-cxa-atexit>
 	)
 
 	# Options for GCC that control linking
 	target_link_options(env-test PRIVATE
-		-e __sp_entry
-		-fno-lto
-		-nostdlib
-		-pie
 		-zmax-page-size=4096
 	)
 	# Options directly for LD, these are not understood by GCC
diff --git a/deployments/internal-trusted-storage/opteesp/CMakeLists.txt b/deployments/internal-trusted-storage/opteesp/CMakeLists.txt
index 5b3450a..c86dcc4 100644
--- a/deployments/internal-trusted-storage/opteesp/CMakeLists.txt
+++ b/deployments/internal-trusted-storage/opteesp/CMakeLists.txt
@@ -64,19 +64,14 @@
 if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
 	target_compile_options(internal-trusted-storage PRIVATE
 		-fdiagnostics-show-option
-		-fpic
 		-gdwarf-2
 		-mstrict-align
 		-O0
-		-std=gnu99
+		-std=c99
 	)
 
 	# Options for GCC that control linking
 	target_link_options(internal-trusted-storage PRIVATE
-		-e __sp_entry
-		-fno-lto
-		-nostdlib
-		-pie
 		-zmax-page-size=4096
 	)
 	# Options directly for LD, these are not understood by GCC
diff --git a/deployments/libsp/opteesp/CMakeLists.txt b/deployments/libsp/opteesp/CMakeLists.txt
index f65713b..6f3907f 100644
--- a/deployments/libsp/opteesp/CMakeLists.txt
+++ b/deployments/libsp/opteesp/CMakeLists.txt
@@ -38,6 +38,7 @@
 	COMPONENTS
 		components/messaging/ffa/libsp
 		components/common/utils
+		environments/opteesp
 )
 
 target_compile_definitions("sp" PRIVATE
@@ -47,11 +48,10 @@
 if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
 	target_compile_options("sp" PRIVATE
 		-fdiagnostics-show-option
-		-fpic
 		-gdwarf-2
 		-mstrict-align
 		-O0
-		-std=gnu99
+		-std=c99
 	)
 endif()
 
diff --git a/deployments/protected-storage/opteesp/CMakeLists.txt b/deployments/protected-storage/opteesp/CMakeLists.txt
index 7106a01..740553b 100644
--- a/deployments/protected-storage/opteesp/CMakeLists.txt
+++ b/deployments/protected-storage/opteesp/CMakeLists.txt
@@ -65,19 +65,14 @@
 if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
 	target_compile_options(protected-storage PRIVATE
 		-fdiagnostics-show-option
-		-fpic
 		-gdwarf-2
 		-mstrict-align
 		-O0
-		-std=gnu99
+		-std=c99
 	)
 
 	# Options for GCC that control linking
 	target_link_options(protected-storage PRIVATE
-		-e __sp_entry
-		-fno-lto
-		-nostdlib
-		-pie
 		-zmax-page-size=4096
 	)
 	# Options directly for LD, these are not understood by GCC
diff --git a/deployments/sfs-demo/opteesp/CMakeLists.txt b/deployments/sfs-demo/opteesp/CMakeLists.txt
index 0eaefd3..47f4e9a 100644
--- a/deployments/sfs-demo/opteesp/CMakeLists.txt
+++ b/deployments/sfs-demo/opteesp/CMakeLists.txt
@@ -60,19 +60,14 @@
 if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
 	target_compile_options(sfs-demo PRIVATE
 		-fdiagnostics-show-option
-		-fpic
 		-gdwarf-2
 		-mstrict-align
 		-O0
-		-std=gnu99
+		-std=c99
 	)
 
 	# Options for GCC that control linking
 	target_link_options(sfs-demo PRIVATE
-		-e __sp_entry
-		-fno-lto
-		-nostdlib
-		-pie
 		-zmax-page-size=4096
 	)
 	# Options directly for LD, these are not understood by GCC
diff --git a/environments/opteesp/component.cmake b/environments/opteesp/component.cmake
index d840249..f7e391f 100644
--- a/environments/opteesp/component.cmake
+++ b/environments/opteesp/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,3 +12,8 @@
 target_sources(${TGT} PRIVATE
 	"${CMAKE_CURRENT_LIST_DIR}/libsp_entry.c"
 	)
+
+target_include_directories(${TGT}
+         PUBLIC
+                "${CMAKE_CURRENT_LIST_DIR}/include"
+        )
diff --git a/environments/opteesp/default_toolchain_file.cmake b/environments/opteesp/default_toolchain_file.cmake
index 7cec0e4..c73345f 100644
--- a/environments/opteesp/default_toolchain_file.cmake
+++ b/environments/opteesp/default_toolchain_file.cmake
@@ -20,3 +20,19 @@
 #set(CMAKE_EXE_LINKER_FLAGS_INIT --specs=nosys.specs)
 
 include($ENV{TS_ROOT}/tools/cmake/compiler/GCC.cmake REQUIRED)
+
+# Set mandatory compiler and linker flags for this environment:
+#   - This environment uses a libc implementation from SPDEV-KIT. Disable standard
+#     include search paths, startup files and default libraries.
+string(APPEND CMAKE_C_FLAGS_INIT " -nostartfiles -nodefaultlibs -nostdinc -I ${CMAKE_CURRENT_LIST_DIR}/include")
+#   - Compile position independent code
+string(APPEND CMAKE_C_FLAGS_INIT " -fpic")
+#   -set entry point
+#   -disable link time optimization
+#   -link position independent executable
+string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " -e __sp_entry -fno-lto -pie")
+
+#   -link libgcc with full PATH to work around disabled linker search paths.
+gcc_get_lib_location("libgcc.a" _TMP_VAR)
+string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${_TMP_VAR} ")
+unset(_TMP_VAR)
diff --git a/environments/opteesp/include/stdarg.h b/environments/opteesp/include/stdarg.h
new file mode 100644
index 0000000..e260b9b
--- /dev/null
+++ b/environments/opteesp/include/stdarg.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDARG_H
+#define STDARG_H
+
+#define va_list __builtin_va_list
+#define va_start(ap, last) __builtin_va_start(ap, last)
+#define va_end(ap) __builtin_va_end(ap)
+#define va_copy(to, from) __builtin_va_copy(to, from)
+#define va_arg(to, type) __builtin_va_arg(to, type)
+
+#endif /* STDARG_H */
diff --git a/environments/opteesp/include/stdbool.h b/environments/opteesp/include/stdbool.h
new file mode 100644
index 0000000..b58334c
--- /dev/null
+++ b/environments/opteesp/include/stdbool.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STDBOOL_H
+#define STDBOOL_H
+
+#define bool	_Bool
+
+#define true	(0 < 1)
+#define false	(0 > 1)
+
+#define __bool_true_false_are_defined	1
+
+#endif /* STDBOOL_H */
diff --git a/environments/opteesp/include/stddef.h b/environments/opteesp/include/stddef.h
new file mode 100644
index 0000000..58a519e
--- /dev/null
+++ b/environments/opteesp/include/stddef.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDDEF_H
+#define STDDEF_H
+
+#include <stddef_.h>
+
+#ifndef _PTRDIFF_T
+typedef long ptrdiff_t;
+#define _PTRDIFF_T
+#endif
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define offsetof(st, m) __builtin_offsetof(st, m)
+
+#endif /* STDDEF_H */
diff --git a/environments/opteesp/include/stddef_.h b/environments/opteesp/include/stddef_.h
new file mode 100644
index 0000000..6ecc606
--- /dev/null
+++ b/environments/opteesp/include/stddef_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STDDEF__H
+#define STDDEF__H
+
+#ifndef SIZET_
+typedef unsigned long size_t;
+#define SIZET_
+#endif
+
+#endif /* STDDEF__H */
diff --git a/external/nanopb/nanopb.cmake b/external/nanopb/nanopb.cmake
index 195e741..e74edc2 100644
--- a/external/nanopb/nanopb.cmake
+++ b/external/nanopb/nanopb.cmake
@@ -58,6 +58,14 @@
 endif()
 
 #### Build the runtime and the generator.
+
+# Pass extra include paths to nanopb build uning CFLAGS if needed
+if (NOT "${NANOPB_EXTERNAL_INCLUDE_PATHS}" STREQUAL "")
+	string(REPLACE ";" "-I " NANOPB_EXTERNAL_INCLUDE_PATHS "${NANOPB_EXTERNAL_INCLUDE_PATHS}")
+	set(_SAVED_CFLAGS $ENV{CFLAGS})
+	set(ENV{CFLAGS} "$ENV{CFLAGS} -I ${NANOPB_EXTERNAL_INCLUDE_PATHS}")
+endif()
+
 if( NOT CMAKE_CROSSCOMPILING)
 	execute_process(COMMAND
 		${CMAKE_COMMAND}
@@ -95,6 +103,12 @@
 	)
 endif()
 
+if (NOT "${NANOPB_EXTERNAL_INCLUDE_PATHS}" STREQUAL "")
+	set($ENV{CFLAGS} ${_SAVED_CFLAGS})
+	unset(_SAVED_CFLAGS)
+	unset(NANOPB_EXTERNAL_INCLUDE_PATHS)
+endif()
+
 if (_exec_error)
 	message(FATAL_ERROR "Configuration step of nanopb runtime failed with ${_exec_error}.")
 endif()
diff --git a/external/qcbor/qcbor.cmake b/external/qcbor/qcbor.cmake
index 7e001be..6d69d90 100644
--- a/external/qcbor/qcbor.cmake
+++ b/external/qcbor/qcbor.cmake
@@ -46,16 +46,26 @@
 endif()
 
 # Configure the qcbor library
+if (NOT "${QCBOR_EXTERNAL_INCLUDE_PATHS}" STREQUAL "")
+	string(REPLACE ";" "\\;" QCBOR_EXTERNAL_INCLUDE_PATHS "${QCBOR_EXTERNAL_INCLUDE_PATHS}")
+	set(QCBOR_EXTRA_OPTION -Dthirdparty_inc=${QCBOR_EXTERNAL_INCLUDE_PATHS})
+	unset(QCBOR_EXTERNAL_INCLUDE_PATHS)
+else()
+	set(QCBOR_EXTRA_OPTION "")
+endif()
+
 execute_process(COMMAND
-${CMAKE_COMMAND}
-	-DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
-	-GUnix\ Makefiles
-	-Dthirdparty_def=${_thirdparty_def}
-	-DCMAKE_INSTALL_PREFIX=${QCBOR_INSTALL_PATH}
-	${qcbor_SOURCE_DIR}
-WORKING_DIRECTORY
-	${qcbor_BINARY_DIR}
+	${CMAKE_COMMAND}
+		-DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE}
+		-GUnix\ Makefiles
+		-Dthirdparty_def=${_thirdparty_def}
+		-DCMAKE_INSTALL_PREFIX=${QCBOR_INSTALL_PATH}
+		${QCBOR_EXTRA_OPTION}
+		${qcbor_SOURCE_DIR}
+	WORKING_DIRECTORY
+		${qcbor_BINARY_DIR}
 )
+unset(QCBOR_EXTRA_OPTION)
 
 # Build the library
 execute_process(COMMAND
diff --git a/external/t_cose/t_cose.cmake b/external/t_cose/t_cose.cmake
index 3fd8061..cda7871 100644
--- a/external/t_cose/t_cose.cmake
+++ b/external/t_cose/t_cose.cmake
@@ -46,6 +46,11 @@
 	${_qcbor_inc}
 	${PSA_CRYPTO_API_INCLUDE})
 
+if (NOT TCOSE_EXTERNAL_INCLUDE_PATHS STREQUAL "")
+	list(APPEND _ext_inc_paths  "${TCOSE_EXTERNAL_INCLUDE_PATHS}")
+	unset(TCOSE_EXTERNAL_INCLUDE_PATHS)
+endif()
+
 string(REPLACE ";" "\\;" _ext_inc_paths "${_ext_inc_paths}")
 
 # Configure the t_cose library
diff --git a/tools/cmake/compiler/GCC.cmake b/tools/cmake/compiler/GCC.cmake
index d061d11..b250fe1 100644
--- a/tools/cmake/compiler/GCC.cmake
+++ b/tools/cmake/compiler/GCC.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2021, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -21,7 +21,7 @@
 include_guard(DIRECTORY)
 
 if(NOT CROSS_COMPILE AND NOT DEFINED ENV{CROSS_COMPILE})
-	message(FATAL_ERROR "'CROSS_COMPILE' is not defined. Set if to the gcc pferix triplet, ie. cmake <..>-DCROSS_COMPILE=aarch64-elf-")
+	message(FATAL_ERROR "'CROSS_COMPILE' is not defined. Set it to the gcc pferix triplet, ie. cmake <..>-DCROSS_COMPILE=aarch64-elf-")
 endif()
 
 set(CROSS_COMPILE $ENV{CROSS_COMPILE} CACHE STRING "Prefix of the cross-compiler commands")
@@ -155,8 +155,8 @@
 	add_custom_target("${_MY_PARAMS_TARGET}_ld" DEPENDS "${_dst}")
 	add_dependencies("${_MY_PARAMS_TARGET}" "${_MY_PARAMS_TARGET}_ld")
 
-	group_add(NAME "${_MY_PARAMS_TARGET}_linker_script" TYPE CONFIG KEY "LINK_DEPENDS" VAL "${_dst}")
-	group_add(NAME "${_MY_PARAMS_TARGET}_linker_script" TYPE LDFLAG KEY "-Wl,--script" VAL "${_dst}")
+	target_link_options(${_MY_PARAMS_TARGET} PRIVATE "-Wl,--script")
+	set_target_properties(${_MY_PARAMS_TARGET} PROPERTIES LINK_DEPENDS "${_dst}")
 endfunction()
 
 #[===[.rst:
@@ -238,3 +238,46 @@
 		set(${MY_RES} $<TARGET_FILE_DIR:${MY_TARGET}>/${MY_NAME} PARENT_SCOPE)
 	endif()
 endfunction()
+
+#[===[.rst:
+.. cmake:command:: gcc_get_lib_location
+
+  .. code-block:: cmake
+
+    gcc_get_lib_location(TARGET foo NAME foo.stripped.elf RES var)
+
+  Query the location of a specific library part of the GCC binary release. Can
+  be used to find built in libraryes like libgcc.a when i.w. -nostdlib option
+  is used.
+
+  Inputs:
+
+  ``LIBRARY_NAME``
+    Name of the library to search for.
+
+  Outputs:
+
+  ``RES``
+    Name of variable to store the full path of the library.
+
+#]===]
+function(gcc_get_lib_location)
+	set(options)
+	set(oneValueArgs LIBRARY_NAME RES)
+	set(multiValueArgs)
+	cmake_parse_arguments(MY "${options}" "${oneValueArgs}"
+						"${multiValueArgs}" ${ARGN} )
+	execute_process(
+		COMMAND ${CMAKE_C_COMPILER} "--print-file-name=${MY_LIBRARY_NAME}"
+		OUTPUT_VARIABLE _RES
+		RESULT_VARIABLE _GCC_ERROR_CODE
+		OUTPUT_STRIP_TRAILING_WHITESPACE
+		)
+
+	if(_GCC_ERROR_CODE GREATER 0)
+		message(WARNING "GCC (${CMAKE_C_COMPILER}) invocation failed, can not determine location of library ${MY_LIBRARY_NAME}.")
+		set(_RES "${LIBRARY_NAME}-NOTFOUND")
+	endif()
+
+	set(${MY_RES} ${_RES} PARENT_SCOPE)
+endfunction()