Undefined reference to `sqrt` in Trusty [Jetson AGX Xavier]

Hi,
I am trying to implement programs in TEE on Trusty that applies to Jetson AGX Xavier series.
When I tried to use sqrt library function in TAs(including math.h), it returns error of Undefined reference to *sqrt*. How could I link with the math libraries to cross-compiler correctly for Trusty platform?

Thanks !

What I did is :
adding the source code e_sqrtf.c from trusty/lk/common/lib/libm into the makefile. While this is not a proper way of including all math library functions into Trusty. Is there another better way ?

Every use of a library requires the application be able to ask for the proper details. Use of the library has fewer requirements than compile since compile is when the specification are noted. That specification is the declaration of any function used.

The library is owned by the libc6 package (runtime use requirements), but declarations used in compile are only provided if you have the libc6-dev package (compile requirements). To add this:
sudo apt-get install libc6-dev

If you have man pages, then “man sqrt” will give some details. This is the requirement for including the signature in a “C” program:

#include <math.h>

Or for C++:

#include <cmath>

Hi,
Thanks for your reply, but I didn’t really get it from your answer. I would like to give you a full picture to understand my question.

I was compiling ATF(arm-trusted-firmware) and TOS(Trusted OS) from host, and compiling TAs(Trusted Applications) as well. Followings are the compiling commands.

compile.sh

export CROSS_COMPILE=/home/lgiori/l4t-gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
export CROSS_COMPILE_AARCH64=/home/lgiori/l4t-gcc/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
export CROSS_COMPILE_ARM=/home/lgiori/l4t-gcc/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-

## Compile ATF and TOS
cd /trusty/atf/arm-trusted-firmware
make BUILD_BASE=./t194ref CROSS_COMPILE="${CROSS_COMPILE_AARCH64}" DEBUG=0 LOG_LEVEL=20 PLAT=tegra SPD=trusty TARGET_SOC=t194 V=0

cd /trusty/trusty/trusty
make t186 PROJECT=t186 TARGET=t186 BUILDROOT=./t194ref \ TOOLCHAIN_PREFIX="${CROSS_COMPILE_AARCH64}" \ ARCH_arm_TOOLCHAIN_PREFIX="${CROSS_COMPILE_ARM}" \ ARCH_arm64_TOOLCHAIN_PREFIX="${CROSS_COMPILE_AARCH64}" \ DEBUG=0 DEBUG_LVL=0 DEFAULT_OTE_APP_DEBUGLEVEL=1 NOECHO=@ \ TRUSTY_VARIANT=l4t-public TRUSTY_MULTI_GUEST_CONFIGURATION= \ TARGET_SOC=t194
## Copy Generate files into 
cp /trusty/atf/arm-trusted-firmware/t194ref/tegra/t194/release/bl31.bin /home/lgiori/l4t-gcc/Linux_for_Tegra/nv_tegra/tos-scripts
cp /trusty/trusty/trusty/t194ref/build-t186/lk.bin /home/lgiori/l4t-gcc/Linux_for_Tegra/nv_tegra/tos-scripts

## Generate TOS image
cd /home/lgiori/l4t-gcc/Linux_for_Tegra/nv_tegra/tos-scripts
./gen_tos_part_img.py --monitor bl31.bin --os lk.bin tos_t194.img
## Replace the TOS image
cp tos_t194.img /home/lgiori/l4t-gcc/Linux_for_Tegra/bootloader/

makefile for TOS

# the above include may override LKROOT and LKINC to allow external
# directories to be included in the build
-include lk_inc.mk

LKMAKEROOT ?= .
LKROOT ?= .
LKINC ?=
BUILDROOT ?= .
DEFAULT_PROJECT ?=
TOOLCHAIN_PREFIX ?=

# check if LKROOT is already a part of LKINC list and add it only if it is not
ifneq ($(findstring $(LKROOT),$(LKINC)), $(LKROOT))
LKINC := $(LKROOT) $(LKINC)
endif

export LKMAKEROOT
export LKROOT
export LKINC
export BUILDROOT
export DEFAULT_PROJECT
export TOOLCHAIN_PREFIX

# vaneer makefile that calls into the engine with lk as the build root
# if we're the top level invocation, call ourselves with additional args
$(MAKECMDGOALS) _top:
	@$(MAKE) -C $(LKMAKEROOT) -rR -f $(LKROOT)/engine.mk $(addprefix -I,$(LKINC)) $(MAKECMDGOALS)

.PHONY: _top

lk_inc.mk

LKROOT ?= lk/common

LKINC ?=  lk/trusty \
          lk/common \
          tegra/public \
          app \
          external \
          external/headers \
          lib \
          device/nvidia/t186

ifneq ($(wildcard tegra/partner),)
        LKINC +=  tegra/partner \
                  device/nvidia/t210
endif

ifneq ($(wildcard tegra/private),)
        LKINC +=  tegra/private
endif

# Build variants that use the ote-apps with an OTE-TIPC wrapper.
ifneq ($(filter embedded-v2% android% mods% sim% l4t-partner-ote, $(TRUSTY_VARIANT)),)
        OTEROOT ?= $(TEGRA_TOP)/ote
        LKINC += $(OTEROOT)
endif

Check the source in LKROOT = lk/common, there is math.h and its source code:

tianchi@securitylab:$ ls /trusty/trusty/trusty/lk/common/lib/libm/
e_acos.c   e_asinf.c  e_fmod.c  e_powf.c       e_sqrt.c   k_cos.c       k_sin.c   k_tanf.c        s_atan.c      s_copysignf.c  s_fabs.c   s_round.c    s_sin.c   s_tanf.c
e_acosf.c  e_atan2.c  e_log.c   e_rem_pio2.c   e_sqrtf.c  k_cosf.c      k_sinf.c  math_private.h  s_ceil.c      s_cos.c        s_fabsf.c  s_scalbn.c   s_sinf.c  s_trunc.c
e_asin.c   e_exp.c    e_pow.c   e_rem_pio2f.c  include    k_rem_pio2.c  k_tan.c   rules.mk        s_copysign.c  s_cosf.c       s_floor.c  s_scalbnf.c  s_tan.c

Here is a simplified version of rule.mk for my programs:

LOCAL_DIR := $(GET_LOCAL_DIR)

MODULE := $(LOCAL_DIR)

MODULE_INCLUDES += \
	$(LOCAL_DIR)/include 

MODULE_SRCS += \
	$(LOCAL_DIR)/ipc.c \
        #( Other source codes here) ...
	$(LOCAL_DIR)/utils.c \
	$(LOCAL_DIR)/main.c \
	$(LOCAL_DIR)/manifest.c \
	/trusty/trusty/trusty/lk/common/lib/libm/e_sqrtf.c # without this line, the included math.h would not offer a refrence to *sqrtf*.


MODULE_DEPS += \
	app/trusty \
	lib/libc-trusty

include make/module.mk

Without /trusty/trusty/trusty/lk/common/lib/libm/e_sqrtf.c in MODULE_SRCS , sqrtf won’t be referenced correctly. Here is what I don’t understand.

Since we have linked lib/common in makefile, why sqrtf or sqrt or other library functions cannot be referenced directly ? Why do we need add /trusty/trusty/trusty/lk/common/lib/libm/e_sqrtf.c in makefile, or do I miss something about the link of math library ?

Thanks

Keep in mind when you read this that I have not tried to compile the specific software you are talking about, and this is more or less just a general reply (now updating for cross compile).

Cross compile changes what libraries (and library search path) are available. So it isn’t a simple matter of including the header and getting it to work since you must also link with the libc6 of a different architecture. I don’t see where your library linking is set up, but could attach a full build log? Example to log:
make 2>&1 | tee log_make.txt

Much of the cross compile you see in the forum is for “bare metal”, which means no linker is used, and no library would be consulted. Instead of just needing the cross tools you need a cross linker and also the actual library files to be linked. You obviously have most of this set up, but apparently it is not finding the libc6 library which defines “sqrt(double)”, so I am assuming it is a case of needing to add the ability of the cross linker to find that library. Logs might hint where that would be.

Then again, I have been assuming you just needed to link the system’s version of sqrt. It is possible that if you have sqrt of your own design, e.g., somewhere in “/trusty/trusty/trusty/lk/common/lib/libm/e_sqrtf.c”, then linking would not be required. The system version requires a library to link to, but if the local definition of sqrt exists, then combining the different “.o” object files would fulfill this requirement.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.