Subject: mixing thumb and arm?
To: None <tech-toolchain@netbsd.org>
From: Bucky Katz <bucky@picovex.com>
List: tech-toolchain
Date: 07/07/2006 14:29:33
I'm porting an application to NetBSD for an arm system. Some C files
are intended to be compiled for thumb and some for arm, then the whole
thing is meant to compile into a single executable.

Below I've attached a shar file with a simple example, that I'm
currently trying to compile native on an arm development board.
Basically, it has a main function in m.c that calls a helloworld
function in h.c that simply prints "hello" and exits.

Right now I'm compiling it with the commands:

ts7250a# make
gcc -c -mthumb -mthumb-interwork -Wa,-mthumb h.c
gcc -c -mthumb-interwork m.c
gcc -mthumb-interwork -o hm h.o m.o

which produces hm with the messages:

ld: Warning: h.o supports interworking, whereas hm does not
ld: Warning: m.o supports interworking, whereas hm does not

And for hm we see:

ts7250a# file hm
hm: ELF 32-bit LSB executable, ARM, version 1 (ARM), for NetBSD
3.99.19, dynamically linked (uses shared libs), for NetBSD 3.99.19,
not stripped

If I try to run this hm, 'hello' is printed infinitely.

Any advice on which compiler flags I should use would be appreciated.

----- here's a shar of the files ----

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.6.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `#!/bin/sh' line above, then type `sh FILE'.
#
lock_dir=_sh31124
# Made on 2006-07-07 14:21 PDT by <bucky@katz.picovex.com>.
# Source directory was `/nfs/ts7200/home/bucky'.
#
# Existing files will *not* be overwritten, unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#     60 -rw-r--r-- h.c
#     72 -rw-r--r-- m.c
#    261 -rw-r--r-- Makefile
#
MD5SUM=${MD5SUM-md5sum}
f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
test -n "${f}" && md5check=true || md5check=false
${md5check} || \
  echo 'Note: not verifying md5sums.  Consider installing GNU coreutils.'
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    case `$dir/gettext --version 2>&1 | sed 1q` in
      *GNU*) gettext_dir=$dir ;;
    esac
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
then if (echo -n test; echo 1,2,3) | grep n >/dev/null
     then shar_n= shar_c='
'
     else shar_n=-n shar_c= ; fi
else shar_n= shar_c='\c' ; fi
f=shar-touch.$$
st1=200112312359.59
st2=123123592001.59
st2tr=123123592001.5 # old SysV 14-char limit
st3=1231235901

if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
   test ! -f ${st1} && test -f ${f}; then
  shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'

elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
   test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
  shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'

elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
   test ! -f ${st3} && test -f ${f}; then
  shar_touch='touch -am $3$4$5$6$2 "$8"'

else
  shar_touch=:
  echo
  ${echo} 'WARNING: not restoring timestamps.  Consider getting and'
  ${echo} 'installing GNU `touch'\'', distributed in GNU File Utilities...'
  echo
fi
rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
#
if test ! -d ${lock_dir}
then : ; else ${echo} 'lock directory '${lock_dir}' exists'
  exit 1
fi
if mkdir ${lock_dir}
then ${echo} 'x - created lock directory `'${lock_dir}\''.'
else ${echo} 'x - failed to create lock directory `'${lock_dir}\''.'
  exit 1
fi
# ============= h.c ==============
if test -f 'h.c' && test "$first_param" != -c; then
  ${echo} 'x -SKIPPING h.c (file already exists)'
else
${echo} 'x - extracting h.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'h.c' &&
#include <stdio.h>
X
int foo() { return printf("hello\n"); }
SHAR_EOF
  (set 20 06 07 07 14 14 06 'h.c'; eval "$shar_touch") &&
  chmod 0644 'h.c'
if test $? -ne 0
then ${echo} 'restore of h.c failed'
fi
  if ${md5check}
  then (
       ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'h.c: MD5 check failed'
       ) << SHAR_EOF
73f7cd4a14f82f9ff12a6b562c4e28b4  h.c
SHAR_EOF
  else
test `LC_ALL=C wc -c < 'h.c'` -ne 60 && \
  ${echo} 'restoration warning:  size of h.c is not 60'
  fi
fi
# ============= m.c ==============
if test -f 'm.c' && test "$first_param" != -c; then
  ${echo} 'x -SKIPPING m.c (file already exists)'
else
${echo} 'x - extracting m.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'm.c' &&
#include <stdlib.h>
extern int foo(void);
X
int main() { return foo(); }
SHAR_EOF
  (set 20 06 07 07 14 19 06 'm.c'; eval "$shar_touch") &&
  chmod 0644 'm.c'
if test $? -ne 0
then ${echo} 'restore of m.c failed'
fi
  if ${md5check}
  then (
       ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'm.c: MD5 check failed'
       ) << SHAR_EOF
0abf35485850dcd9979da9352ca930ac  m.c
SHAR_EOF
  else
test `LC_ALL=C wc -c < 'm.c'` -ne 72 && \
  ${echo} 'restoration warning:  size of m.c is not 72'
  fi
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
  ${echo} 'x -SKIPPING Makefile (file already exists)'
else
${echo} 'x - extracting Makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
# link h.o and m.o as a mixed thumb and arm executable
hm:	h.o m.o
X	gcc -mthumb-interwork -o hm h.o m.o
X
# compile h.c as a thumb routine
h.o:
X	gcc -c -mthumb -mthumb-interwork -Wa,-mthumb h.c
X
# compile m.c as an arm routine
m.o:
X	gcc -c -mthumb-interwork m.c
SHAR_EOF
  (set 20 06 07 07 14 18 30 'Makefile'; eval "$shar_touch") &&
  chmod 0644 'Makefile'
if test $? -ne 0
then ${echo} 'restore of Makefile failed'
fi
  if ${md5check}
  then (
       ${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'Makefile: MD5 check failed'
       ) << SHAR_EOF
7f2b1d4f6e04bb41984ec2a5836c3dc7  Makefile
SHAR_EOF
  else
test `LC_ALL=C wc -c < 'Makefile'` -ne 261 && \
  ${echo} 'restoration warning:  size of Makefile is not 261'
  fi
fi
if rm -fr ${lock_dir}
then ${echo} 'x - removed lock directory `'${lock_dir}\''.'
else ${echo} 'x - failed to remove lock directory `'${lock_dir}\''.'
  exit 1
fi
exit 0