Open Source & Linux Lab

It's better when it's simple

User Tools

Site Tools


etc:users:jcmvbkbc:binutils-xtensa

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Next revisionBoth sides next revision
etc:users:jcmvbkbc:binutils-xtensa [2023/05/17 21:57] – created jcmvbkbcetc:users:jcmvbkbc:binutils-xtensa [2024/02/25 14:28] jcmvbkbc
Line 5: Line 5:
 ==== FDPIC support ==== ==== FDPIC support ====
  
-  * [-] static linking +  * [+] static linking 
-  * [-] PDE+  * [+] PDE
   * [+] PIE   * [+] PIE
-  * [-] PLT and lazy binding+  * [±] PLT and lazy binding
   * [-] TLS   * [-] TLS
 +
 +==== FDPIC instruction sequences ====
 +
 +=== Local call ====
 +
 +Default local call
 +<code>
 ++0:     movi    tmp, target@GOT
 ++3:     add     tmp, tmp, localGOTptr
 ++5:     l32i    tmp, tmp, 0
 ++7:     mov     GOTptr, localGOTptr
 ++9:     callx0  tmp
 +</code>
 +
 +No-GOT local call
 +<code>
 ++0:     movi    tmp1, target
 ++3:     l32i    tmp2, localGOTptr, TEXT_SEGMENT_OFFSET
 ++5:     add     tmp1, tmp1, tmp2
 ++7:     mov     GOTptr, localGOTptr
 ++9:     callx0  tmp1
 +</code>
 +
 +When call0 reaches the target it can be transformed to
 +<code>
 ++0:     mov     GOTptr, localGOTptr
 ++2:     call0   target
 +</code>
 +
 +In the j.l style it could probably be done like
 +<code>
 +        call0.l target, tmp1, tmp2, localGOTptr
 +</code>
 +
 +=== PLT call ====
 +
 +Obvious version:
 +<code>
 ++0:     movi    tmp, target@PLTGOT
 ++3:     add     tmp, tmp, localGOTptr
 ++5:     l32i    tmp, tmp, 0
 ++7:     l32i    GOTptr, tmp, 4
 ++9:     l32i    tmp, tmp, 0
 ++11:    callx0  tmp
 +</code>
 +<code>
 +target@PLT:
 ++0:     movi    a8, target@PLTGOT
 ++3:     add     a8, a8, GOTptr
 ++5:     movi    a9, target-symbol
 ++8:     l32i    a10, GOTptr, RESOLVER_FN
 ++10:    l32i    GOTptr, GOTptr, RESOLVER_GOT
 ++12:    jx0     a10
 +</code>
 +
 +The inline part calls the PLT part only once, after resolution the inline part calls the target directly.
 +The adjustment is done to a single GOT entry, so it's atomic.
 +The inline part can be reduced to a fixed direct call to the PLT:
 +<code>
 ++0:     mov     GOTptr, localGOTptr
 ++2:     call0   target@PLT
 +</code>
 +that reduces the inline part from 14 to 5 bytes, but adds two jumps to each call and some special logic to the resolver to avoid name resolution on each call.
 +
 +=== TLS General Dynamic ===
 +
 +<code>
 ++0:     movi    tmp1, x@GOTTLSDESC
 ++3:     add     arg0, tmp1, localGOTptr
 ++5:     l32i    tmp2, arg0, 0
 ++7:     l32i    GOTptr, tmp2, 4
 ++9:     l32i    tmp3, tmp2, 0
 ++11:    callx0  tmp3
 +</code>
 +
 +This TLSDESC is not the same as the descriptor of the default xtensa toolchain. It contains two pointers, one to the resolver function, the other to that other descriptor containing DTPOFF and module index in the dtv.
 +
 +=== TLS Local Dynamic ===
 +
 +<code>
 ++0:     l32i    arg0, localGOTptr, _TLS_MODULE_BASE_DESC_OFF
 ++2:     l32i    tmp1, arg0, 0
 ++4:     l32i    GOTptr, tmp1, 4
 ++6:     l32i    tmp2, tmp1, 0
 ++8:     callx0  tmp2
 +...
 ++m:     movi    tmp3, x@DTPOFF
 ++m+3:   add     res, tmp3, rv0
 +...
 +</code>
 +_TLS_MODULE_BASE_DESC_OFF is a small fixed offset (16?) from the GOT base where an entry with R_XTENSA_TLSDESC(_TLS_MODULE_BASE_) relocation against it is placed.
 +
 +=== TLS Initial Exec ===
 +
 +<code>
 ++0:     movi    tmp1, x@GOTTPOFF
 ++3:     add     tmp2, tmp1, localGOTptr
 ++5:     l32i    tmp3, tmp2, 0
 ++7:     rur     tmp4, THREADPTR
 ++10:    add     res, tmp3, tmp4
 +</code>
 +
 +=== TLS Local Exec ===
 +
 +<code>
 ++0:     movi    tmp1, x@TPOFF
 ++3:     rur     tmp2, THREADPTR
 ++6:     add     res, tmp1, tmp2
 +</code>
 +
 +==== Manual toolchain building script ====
 +
 +<code>
 +#! /bin/bash -ex
 +
 +target=${TARGET:-xtensa-linux-uclibcfdpic}
 +build_base=`pwd`/build
 +src_base=$(dirname $(readlink -f "$0"))
 +binutils_src=$HOME/ws/tensilica/binutils-gdb/binutils-gdb
 +gcc_src=$HOME/ws/tensilica/gcc/gcc
 +linux_src="$src_base/linux"
 +uclibc_src="$src_base/uclibc-ng"
 +uclibc_config_src="$src_base/uclibc-ng-config"
 +
 +prefix=`pwd`
 +sysroot="$prefix/$target/sysroot"
 +linux_headers="$sysroot/usr"
 +
 +_FLAGS_FOR_HOST=${FLAGS_FOR_HOST:--Og -g}
 +_FLAGS_FOR_TARGET=${FLAGS_FOR_TARGET:--mauto-litpools -mfdpic -Oz -g}
 +CROSS_COMPILE=${CROSS_COMPILE:-$prefix/bin/$target-}
 +TARGET_CFLAGS="$_FLAGS_FOR_TARGET -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64"
 +
 +if [ "$1" = "-r" ]; then
 +        reconfigure=1
 +fi
 +
 +mkdir -p .build
 +
 +mkdir .build/binutils && (
 +        cd .build/binutils
 +        "$binutils_src/configure" --prefix="$prefix" \
 +                --target=$target \
 +                --with-sysroot="$sysroot" \
 +                --disable-shared --disable-werror --disable-gdb --disable-gdbstub \
 +                CFLAGS="$_FLAGS_FOR_HOST"
 +
 +        make -j8
 +        make -j8 install
 +)
 +
 +mkdir .build/gcc-initial && (
 +        cd .build/gcc-initial
 +        "$gcc_src/configure" --prefix="$prefix" \
 +                --target=$target \
 +                --with-sysroot="$sysroot" \
 +                --enable-languages=c \
 +                --disable-shared \
 +                --enable-__cxa_atexit \
 +                --disable-tls --disable-threads \
 +                --without-headers --with-newlib \
 +                CFLAGS_FOR_TARGET="$_FLAGS_FOR_TARGET" \
 +                CXXFLAGS_FOR_TARGET="$_FLAGS_FOR_TARGET" \
 +                CFLAGS="$_FLAGS_FOR_HOST" \
 +                CXXFLAGS="$_FLAGS_FOR_HOST"
 +
 +        make -j8 all-gcc
 +        make -j8 all-target-libgcc
 +        make -j8 install-gcc
 +        make -j8 install-target-libgcc
 +)
 +
 +mkdir .build/linux && (
 +        cd .build/linux
 +        make -C "$linux_src" ARCH=xtensa \
 +                CROSS_COMPILE="$CROSS_COMPILE" O=`pwd` \
 +                defconfig   
 +        make -C "$linux_src" ARCH=xtensa \
 +                CROSS_COMPILE="$CROSS_COMPILE" O=`pwd` \
 +                INSTALL_HDR_PATH="$linux_headers" \
 +                -j8 headers_install
 +)
 +
 +mkdir .build/uclibc && (
 +        cd .build/uclibc
 +        cp "$uclibc_config_src/.config" .
 +        if [ -n "$reconfigure" ]; then
 +                make -C "$uclibc_src" ARCH=xtensa \
 +                        CROSS_COMPILE="$CROSS_COMPILE" \
 +                        O=`pwd` KERNEL_HEADERS="$linux_headers/include" \
 +                        UCLIBC_EXTRA_CFLAGS="${TARGET_CFLAGS}" \
 +                        menuconfig
 +                cp .config "$uclibc_config_src"
 +        fi
 +
 +        make -C "$uclibc_src" ARCH=xtensa \
 +                CROSS_COMPILE="$CROSS_COMPILE" \
 +                O=`pwd` KERNEL_HEADERS="$linux_headers/include" \
 +                UCLIBC_EXTRA_CFLAGS="${TARGET_CFLAGS}" \
 +                -j8 "$@"
 +        make -C "$uclibc_src" ARCH=xtensa \
 +                CROSS_COMPILE="$CROSS_COMPILE" \
 +                O=`pwd` KERNEL_HEADERS="$linux_headers/include" \
 +                UCLIBC_EXTRA_CFLAGS="${TARGET_CFLAGS}" \
 +                DESTDIR="$sysroot" \
 +                install
 +)
 +
 +mkdir .build/gcc-final && ( 
 +        cd .build/gcc-final 
 +        "$gcc_src/configure" --prefix="$prefix" \
 +                --target=$target \
 +                --with-sysroot="$sysroot" \
 +                --enable-languages=c,c++ \
 +                --disable-shared \
 +                --enable-__cxa_atexit \
 +                --disable-tls --disable-threads \
 +                --with-uclibc \
 +                CFLAGS_FOR_TARGET="$_FLAGS_FOR_TARGET" \
 +                CXXFLAGS_FOR_TARGET="$_FLAGS_FOR_TARGET" \
 +                CFLAGS="$_FLAGS_FOR_HOST" \
 +                CXXFLAGS="$_FLAGS_FOR_HOST"
 +
 +        make -j8 all
 +        make -j8 install
 +)
 +</code>
etc/users/jcmvbkbc/binutils-xtensa.txt · Last modified: 2024/03/18 14:47 by jcmvbkbc