#!/bin/sh # # allow us to do flat processing if the flag -Wl,-elf2flt or -elf2flt to # the 'C' compiler or linker respectively # # uses the env. var FLTFLAGS as extra parameters to pass to elf2flt # arguments given like -Wl,-elf2flt="-b 10000 -v" are given before FLTFLAGS # # Copyright (C) 2002,2003 David McCullough # Copyright (C) 2000, Lineo. davidm@lineo.com # # This is Free Software, under the GNU Public Licence v2 or greater. # LINKER="$0.real" # the original renamed-linker ELF2FLT="`expr $0 : '\(.*\)ld'`elf2flt" NM="`expr $0 : '\(.*\)ld'`nm" TOOLDIR="`dirname $0`" # let gcc find the tools for us OBJCOPY="`expr $0 : '\(.*\)ld'`objcopy" [ -f "$OBJCOPY" ] || OBJCOPY="$TOOLDIR/../../bin/@target_alias@-objcopy" OBJDUMP="`expr $OBJCOPY : '\(.*\)objcopy'`objdump" LDSCRIPTPATH="@binutils_ldscript_dir@" # and the scripts SHARED_ID="" NEWLDSCRIPT="" WANT_SHARED="" # check TOOLDIR from prefix/bin/ or prefix/target-alias/bin/ [ -d "${LDSCRIPTPATH}" ] || LDSCRIPTPATH="${TOOLDIR}/../lib" # # if we have the elf2flt options, run it # if expr "$*" : ".*-elf2flt.*" > /dev/null then ARG1= ARG2= OFILE="a.out" PIC= SDIRS= LDSCRIPT= FINAL="yes" FINAL_ONLY= MOVDAT= VERBOSE= while [ $# -ne 0 ] do case "$1" in -elf2flt) ;; # we already know this -elf2flt*)FLTFLAGS="`expr \"$1\" : '-elf2flt=\(.*\)'` $FLTFLAGS";; -move-rodata) MOVDAT="y";; # Put rodata in ROM if possible -s) ;; # Ignore -s (strip) -shared-lib-id) shift; SHARED_ID="$1";; # Shared library ID -shared|-G) WANT_SHARED="y";; # Shared library -o) shift; OFILE="$1";; # the final outfile -o*) OFILE="`expr \"$1\" : '-o\(.*\)'`";; -T) shift; LDSCRIPT="$1";; # they have a linker script -c) shift; LDSCRIPT="$1";; -L) ARG1="$ARG1 $1" # remember search dirs shift; ARG1="$ARG1 $1" SDIRS="$SDIRS -L$1" ;; -L*) ARG1="$ARG1 $1"; SDIRS="$SDIRS $1";; -EB) ARG1="$ARG1 $1"; SDIRS="$SDIRS $1";; # arm big endian -relax) ;; # eat this for microblaze -r|-Ur) FINAL="" # this is not a final link ARG1="$ARG1 $1" ;; -v) ARG1="$ARG1 $1" VERBOSE="y" ;; -m) shift; EMUL="-m $1";; # ld emulations for h8300 -m*) EMUL=$1;; *) ARG1="$ARG1 $1" ;; esac shift done if [ "$WANT_SHARED" = "y" ] then if [ -z "$SHARED_ID" ] then echo "-shared used without passing a shared library ID" exit 1 fi fi if [ "$FINAL" = "yes" ] then [ "$VERBOSE" = "y" ] && set -x ARG1="$ARG1 $FINAL_ONLY" NEWLDSCRIPT=`mktemp /tmp/flt-XXXXXX` trap 'rm -f "$NEWLDSCRIPT"' EXIT SEDOP=" -e s/^R_RODAT// -e /^W_RODAT/d" OBJCOPYOP="" if [ "$MOVDAT" ] then $LINKER -r -d -o "$OFILE.elf2flt" $ARG1 || exit $? if [ "`$OBJDUMP -h "$OFILE.elf2flt" | \ egrep -A1 '[.]rodata' | grep RELOC`" ] then echo "warning: .rodata section contains relocations" else SEDOP="-e /^R_RODAT/d -e s/^W_RODAT//" fi fi if [ "$SHARED_ID" ] then # Massage the linker script into something useful. These # regexps are ugly due to some bizzare shell quoting rules. # SEDOP="$SEDOP -e \"s/ORIGIN = 0x0,/ORIGIN = 0x${SHARED_ID}000000,/\"" # SEDOP="$SEDOP -e \"s/.text 0x0 :/.text 0x${SHARED_ID}000000 :/\"" SEDOP="$SEDOP -e s/\\(ORIGIN.=.0\\)x0,/\\1x${SHARED_ID}000000,/" SEDOP="$SEDOP -e s/\\([.]text.0\\)x0[^0-9]:/\\1x${SHARED_ID}000000:/" if [ "$SHARED_ID" -gt 0 ] then # Non application modules enter via main not _start # SEDOP="$SEDOP -e 's/ENTRY (_start)/ENTRY (main)/'" SEDOP="$SEDOP -e s/\\(ENTRY.\\)(@SYMBOL_PREFIX@_start)/\1(lib_main)/" OBJCOPYOP="--localize-hidden --weaken" fi # Provide the magic parameter that defines the library data segment pointer offset GOT_ADJ=4 case "@target_cpu@" in bfin) GOT_OFFSET="_current_shared_library_p5_offset_" GOT_ADJ=1;; h8300) GOT_OFFSET="__current_shared_library_er5_offset_";; *) GOT_OFFSET="_current_shared_library_a5_offset_";; esac ARG1="$ARG1 -defsym $GOT_OFFSET=`expr ${SHARED_ID} '*' -${GOT_ADJ} - ${GOT_ADJ}`" fi if [ "@emit_relocs@" = "yes" ] then SEDOP="$SEDOP -e s/^SINGLE_LINK://" else SEDOP="$SEDOP -e /^SINGLE_LINK:/d" fi if [ "@emit_ctor_dtor@" = "yes" ] then SEDOP="$SEDOP -e s/^TOR://" else SEDOP="$SEDOP -e /^TOR:/d" fi # provide a default linker script, we usually need one [ -z "$LDSCRIPT" ] && LDSCRIPT="${LDSCRIPTPATH}/elf2flt.ld" # if we can find the linker script we preprocess it, otherwise # we assume the user knows what they are doing if [ -f "$LDSCRIPT" ]; then sed $SEDOP < "$LDSCRIPT" > "$NEWLDSCRIPT" LDSCRIPT="$NEWLDSCRIPT" elif [ -f "${LDSCRIPTPATH}/$LDSCRIPT" ]; then sed $SEDOP < "${LDSCRIPTPATH}/$LDSCRIPT" > "$NEWLDSCRIPT" LDSCRIPT="$NEWLDSCRIPT" elif [ -f "${LDSCRIPTPATH}/ldscripts/$LDSCRIPT" ]; then sed $SEDOP < "${LDSCRIPTPATH}/ldscripts/$LDSCRIPT" > "$NEWLDSCRIPT" LDSCRIPT="$NEWLDSCRIPT" fi if [ "@emit_relocs@" = "yes" ] then $LINKER $EMUL $SDIRS -T $LDSCRIPT -q -o "$OFILE.gdb" $ARG1 ||exit $? RFILE="$OFILE.gdb" FLTFLAGS="$FLTFLAGS -a" else if [ "@got_check@" = "no" ] then $LINKER $EMUL $SDIRS -T $LDSCRIPT -Ur -d -o "$OFILE.elf" $ARG1 ||exit $? $LINKER $EMUL $SDIRS -T $LDSCRIPT -o "$OFILE.gdb" $ARG1 ||exit $? else $LINKER $EMUL -r -d -o "$OFILE.elf2flt" $ARG1 ||exit $? $LINKER $EMUL $SDIRS -T $LDSCRIPT -Ur -o "$OFILE.elf" "$OFILE.elf2flt" ||exit $? $LINKER $EMUL $SDIRS -T $LDSCRIPT -o "$OFILE.gdb" "$OFILE.elf2flt" ||exit $? rm -f "$OFILE.elf2flt" fi RFILE="$OFILE.elf" fi if $NM "$OFILE.gdb" | grep _GLOBAL_OFFSET_TABLE_ > /dev/null then $ELF2FLT $FLTFLAGS -o "$OFILE" -p "$OFILE.gdb" "$RFILE" || exit $? else $ELF2FLT $FLTFLAGS -o "$OFILE" -r "$RFILE" || exit $? fi if [ "$OBJCOPYOP" ] then if $OBJCOPY $OBJCOPYOP --help > /dev/null 2>&1 then $OBJCOPY $OBJCOPYOP "$OFILE.gdb" ||exit $? else case " $OBJCOPYOP " in *" --localize-hidden "*) SYMS=`mktemp /tmp/flt-XXXXXX` $OBJDUMP --syms "$OFILE.gdb" > "$SYMS" ||exit $? sed -n 's/.*\(\.hidden\|\.internal\) \(.*\)/-L \2/p' < "$SYMS" > "$SYMS.hidden" ||exit $? if [ -s "$SYMS.hidden" ] then xargs ${VERBOSE:+-t} $OBJCOPY "$OFILE.gdb" < "$SYMS.hidden" ||exit $? fi rm -f "$SYMS" "$SYMS.hidden" ;; esac case " $OBJCOPYOP " in *" --weaken "*) $OBJCOPY --weaken "$OFILE.gdb" ||exit $? ;; esac fi fi [ "$RFILE" = "$OFILE.gdb" ] || rm -f "$RFILE" # not needed for any reason exit 0 fi exec $LINKER -o "$OFILE" $ARG1 fi # # otherwise pretend we aren't here # exec $LINKER "$@"