From 261b502c782b2a9564f25a8243294fbf64680d8a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 7 May 2009 01:16:42 -0400 Subject: [PATCH] ld-elf2flt: convert to C Due to shell portability issues (which is to say shell scripts are not portable -- think Windows), convert elf2flt to C code. I've updated this code base to the latest elf2flt tree and actually done some basic tests -- building the three Blackfin tuples (ELF, FLAT, FDPIC) and running programs on my Blackfin boards. This process found errors in the original implementation as well as some of the cleanups I did. If this continues to be stable on my systems, I'll be merging it into the Blackfin tree. I'd hold off on merging this into the uClinux tree until that point, but I'm just "posting early and often" to get more review ahead of time. Signed-off-by: Nathan Sidwell Signed-off-by: Mike Frysinger --- .gitignore | 6 + Makefile.in | 52 ++- compress.c | 13 +- configure | 1515 ++++++++++++++++++++++++++++++++++++++++----------------- configure.in | 27 +- elf2flt.c | 179 ++------ flthdr.c | 29 +- ld-elf2flt.c | 571 ++++++++++++++++++++++ ld-elf2flt.in | 239 --------- stubs.c | 124 +++++- stubs.h | 75 +++ 11 files changed, 1945 insertions(+), 885 deletions(-) create mode 100644 ld-elf2flt.c delete mode 100644 ld-elf2flt.in create mode 100644 stubs.h diff --git a/.gitignore b/.gitignore index 12b560b..92ff5f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,15 @@ # standard patterns +*.a *.o *~ *.orig *.rej *.patch +.deps + +a.out +*.gdb +*.exe # autotool files autom4te.cache diff --git a/Makefile.in b/Makefile.in index 1b192c4..3b997c6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -10,29 +10,36 @@ includedir = @includedir@ CC = @CC@ CPU = @target_cpu@ TARGET = @target_alias@ +SYMBOL_PREFIX = @SYMBOL_PREFIX@ CFLAGS = @CFLAGS@ INCLUDES = @bfd_include_dir@ @binutils_include_dir@ @zlib_include_dir@ -CPPFLAGS = @CPPFLAGS@ +CPPFLAGS = @CPPFLAGS@ $(DEFS) $(INCLUDES) LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ +LDLIBS = @LIBS@ INSTALL = @INSTALL@ -DEFS = @DEFS@ -DTARGET_$(CPU) +DEFS = @DEFS@ \ + -DTARGET_$(CPU) \ + -DTARGET_CPU=\"$(CPU)\" \ + -DSYMBOL_PREFIX=\"$(SYMBOL_PREFIX)\" \ + -DBINUTILS_LDSCRIPTDIR=\"@binutils_ldscript_dir@\" \ + -DTARGET_ALIAS=\"$(TARGET)\" \ + -DNO_GOT_CHECK=@got_check@ \ + -DUSE_EMIT_RELOCS=@emit_relocs@ \ + -DEMIT_CTOR_DTOR=@emit_ctor_dtor@ EXEEXT = @EXEEXT@ OBJEXT = @OBJEXT@ HOST = @host_alias@ ifneq (,$(findstring mingw32,$(HOST))) - LIBS := $(LIBS) -lws2_32 + LDLIBS += -lws2_32 endif # force link order under cygwin to avoid getopts / libiberty clash ifneq ($(strip $(shell gcc -v 2>&1 | grep "cygwin")),) - LIBS := -lcygwin $(LIBS) + LDLIBS := -lcygwin $(LDLIBS) endif -CCFLAGS = $(CFLAGS) $(DEFS) $(INCLUDES) - LDFILE= elf2flt.ld ifeq ($(strip $(CPU)),e1) SRC_LDFILE= $(srcdir)/$(CPU)-elf2flt.ld @@ -46,18 +53,23 @@ target_libdir = $(prefix)/$(TARGET)/lib PROG_ELF2FLT = elf2flt$(EXEEXT) PROG_FLTHDR = flthdr$(EXEEXT) -PROGS = $(PROG_ELF2FLT) $(PROG_FLTHDR) +PROG_LD_ELF2FLT = ld-elf2flt$(EXEEXT) +PROGS = $(PROG_ELF2FLT) $(PROG_FLTHDR) $(PROG_LD_ELF2FLT) -all: $(PROGS) ld-elf2flt +all: $(PROGS) -$(PROG_ELF2FLT): $(srcdir)/elf2flt.c compress.o $(srcdir)/stubs.c - $(CC) $(CCFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) +# We need to declare the link explicitly because make only provides +# implicit rules when EXEEXT is set to nothing +link = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) -$(PROG_FLTHDR): $(srcdir)/flthdr.c compress.o - $(CC) $(CCFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) +$(PROG_ELF2FLT): elf2flt.o stubs.o compress.o + $(link) -ld-elf2flt: $(srcdir)/ld-elf2flt.in - ./config.status $@ +$(PROG_FLTHDR): flthdr.o stubs.o compress.o + $(link) + +$(PROG_LD_ELF2FLT): ld-elf2flt.o stubs.o + $(link) Makefile: $(srcdir)/Makefile.in ./config.status $@ @@ -66,7 +78,7 @@ clean: -rm -f $(PROGS) *.$(OBJEXT) distclean: clean - -rm -f Makefile config.log config.status config.cache ld-elf2flt + -rm -f Makefile config.log config.status config.cache install: $(INSTALL) -d $(bindir) @@ -80,8 +92,10 @@ install: mv $(bindir)/$(TARGET)-ld$(EXEEXT) $(bindir)/$(TARGET)-ld.real$(EXEEXT) [ -f $(target_bindir)/ld.real$(EXEEXT) ] || \ mv $(target_bindir)/ld$(EXEEXT) $(target_bindir)/ld.real$(EXEEXT) - $(INSTALL) -m 755 ld-elf2flt $(bindir)/$(TARGET)-ld - $(INSTALL) -m 755 ld-elf2flt $(target_bindir)/ld + $(INSTALL) -m 755 $(PROG_LD_ELF2FLT) $(bindir)/$(TARGET)-ld$(EXEEXT) + $(INSTALL) -m 755 $(PROG_LD_ELF2FLT) $(target_bindir)/ld$(EXEEXT) $(INSTALL) -m 644 $(SRC_LDFILE) $(target_libdir)/$(LDFILE) - +sinclude .deps +.deps: + $(CC) -MM $(CPPFLAGS) *.c > .deps diff --git a/compress.c b/compress.c index e5d4f17..144c96f 100644 --- a/compress.c +++ b/compress.c @@ -13,6 +13,7 @@ #include #include "compress.h" +#include "stubs.h" /* Open an (uncompressed) file as a stream. Return 0 on success, 1 on error. @@ -187,15 +188,11 @@ transfer(stream *ifp, stream *ofp, int count) n = fread_stream(cmd, 1, num, ifp); if (n == 0) break; - if (fwrite_stream(cmd, n, 1, ofp) != 1) { - fprintf(stderr, "Write failed :-(\n"); - exit(1); - } + if (fwrite_stream(cmd, n, 1, ofp) != 1) + fatal_perror("Write failed :-(\n"); if (count != -1) count -= n; } - if (count > 0) { - fprintf(stderr, "Failed to transfer %d bytes\n", count); - exit(1); - } + if (count > 0) + fatal("Failed to transfer %d bytes\n", count); } diff --git a/configure b/configure index bcd26ae..f154eaf 100755 --- a/configure +++ b/configure @@ -645,12 +645,14 @@ binutils_ldscript_dir zlib_include_dir binutils_include_dir bfd_include_dir -EGREP -GREP -CPP INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM +RANLIB +AR +EGREP +GREP +CPP OBJEXT EXEEXT ac_ct_CC @@ -1889,6 +1891,14 @@ else fi +var_yn_to_10() { + if eval test \"\$$1\" = yes ; then + eval $1=1 + else + eval $1=0 + fi +} + # Check whether --enable-got-check was given. if test "${enable_got_check+set}" = set; then enableval=$enable_got_check; got_check=$enableval @@ -1897,6 +1907,7 @@ else fi +var_yn_to_10 got_check # Check whether --enable-emit-relocs was given. if test "${enable_emit_relocs+set}" = set; then @@ -1906,6 +1917,7 @@ else fi +var_yn_to_10 emit_relocs # Check whether --enable-emit-ctor-dtor was given. if test "${enable_emit_ctor_dtor+set}" = set; then @@ -1915,6 +1927,7 @@ else fi +var_yn_to_10 emit_ctor_dtor ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -3007,6 +3020,1042 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + if test "${ac_cv_header_minix_config_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 +$as_echo_n "checking for minix/config.h... " >&6; } +if test "${ac_cv_header_minix_config_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 +$as_echo "$ac_cv_header_minix_config_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking minix/config.h usability" >&5 +$as_echo_n "checking minix/config.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking minix/config.h presence" >&5 +$as_echo_n "checking minix/config.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 +$as_echo_n "checking for minix/config.h... " >&6; } +if test "${ac_cv_header_minix_config_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_minix_config_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 +$as_echo "$ac_cv_header_minix_config_h" >&6; } + +fi +if test "x$ac_cv_header_minix_config_h" = x""yes; then + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_SOURCE 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_1_SOURCE 2 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _MINIX 1 +_ACEOF + + fi + + + + { $as_echo "$as_me:$LINENO: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if test "${ac_cv_safe_to_define___extensions__+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_safe_to_define___extensions__=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_safe_to_define___extensions__=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + cat >>confdefs.h <<\_ACEOF +#define __EXTENSIONS__ 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define _ALL_SOURCE 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define _GNU_SOURCE 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define _POSIX_PTHREAD_SEMANTICS 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define _TANDEM_SOURCE 1 +_ACEOF + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:$LINENO: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: @@ -3110,7 +4159,6 @@ fi if test "$ac_libiberty" = "NONE"; then - { $as_echo "$as_me:$LINENO: checking for objalloc_create in -liberty" >&5 $as_echo_n "checking for objalloc_create in -liberty... " >&6; } if test "${ac_cv_lib_iberty_objalloc_create+set}" = set; then @@ -3495,377 +4543,6 @@ if test "x$ac_cv_lib_c_malloc" = x""yes; then fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - : -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done -done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done -done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then @@ -4044,79 +4721,6 @@ _ACEOF fi -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 -$as_echo_n "checking for $ac_header... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - $as_echo_n "(cached) " >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" -$as_echo "$ac_try_echo") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - eval "$as_ac_Header=yes" -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -as_val=`eval 'as_val=${'$as_ac_Header'} - $as_echo "$as_val"'` - if test "x$as_val" = x""yes; then - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - @@ -4572,7 +5176,14 @@ done -for ac_func in dcgettext libintl_dgettext + + +for ac_func in \ + dcgettext \ + getline \ + libintl_dgettext \ + strsignal \ + do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -4673,6 +5284,7 @@ fi done +test "$GCC" = yes && CFLAGS="-Wall $CFLAGS" @@ -4687,7 +5299,8 @@ done -ac_config_files="$ac_config_files Makefile ld-elf2flt elf2flt.ld" + +ac_config_files="$ac_config_files Makefile elf2flt.ld" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -5299,7 +5912,6 @@ for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "ld-elf2flt") CONFIG_FILES="$CONFIG_FILES ld-elf2flt" ;; "elf2flt.ld") CONFIG_FILES="$CONFIG_FILES elf2flt.ld" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 @@ -5807,4 +6419,3 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi - diff --git a/configure.in b/configure.in index eb9733f..46b41d2 100644 --- a/configure.in +++ b/configure.in @@ -43,29 +43,42 @@ AC_ARG_WITH(binutils-build-dir, [ ac_binutils_build_dir=NONE ] ) +dnl convert a yes/no variable to 1/0 for C code +var_yn_to_10() { + if eval test \"\$$1\" = yes ; then + eval $1=1 + else + eval $1=0 + fi +} + AC_ARG_ENABLE(got-check, [ --disable-got-check - disable check for GOT (needed on H8) ], [ got_check=$enableval ], [ got_check=yes ] ) +var_yn_to_10 got_check AC_ARG_ENABLE(emit-relocs, [ --disable-emit-relocs - don't use the --emit-relocs (-q) linker option ], [ emit_relocs=$enableval ], [ emit_relocs=yes ] ) +var_yn_to_10 emit_relocs AC_ARG_ENABLE(emit-ctor-dtor, AS_HELP_STRING([--enable-emit-ctor-dtor], [manually create ctor/dtor list]), [ emit_ctor_dtor=$enableval ], [ emit_ctor_dtor=no ] ) +var_yn_to_10 emit_ctor_dtor AC_CANONICAL_HOST AC_CANONICAL_TARGET dnl Checks for programs. AC_PROG_CC +AC_USE_SYSTEM_EXTENSIONS AC_PROG_INSTALL if test "$ac_binutils_build_dir" != "NONE"; then @@ -143,7 +156,7 @@ fi SYMBOL_PREFIX= case $target in - bfin*) + h8300|bfin*) SYMBOL_PREFIX=_ ;; esac @@ -165,7 +178,14 @@ AC_C_CONST dnl Checks for library functions. AC_FUNC_VPRINTF -AC_CHECK_FUNCS(dcgettext libintl_dgettext) +AC_CHECK_FUNCS([ \ + dcgettext \ + getline \ + libintl_dgettext \ + strsignal \ +]) + +test "$GCC" = yes && CFLAGS="-Wall $CFLAGS" dnl Subsitute values AC_SUBST(target) @@ -182,5 +202,4 @@ AC_SUBST(emit_relocs) AC_SUBST(emit_ctor_dtor) AC_SUBST(SYMBOL_PREFIX) -AC_OUTPUT(Makefile ld-elf2flt elf2flt.ld) - +AC_OUTPUT(Makefile elf2flt.ld) diff --git a/elf2flt.c b/elf2flt.c index 0e17f73..a0d5c17 100644 --- a/elf2flt.c +++ b/elf2flt.c @@ -44,18 +44,14 @@ #include /* Userland prototypes of the Unix std system calls */ #include /* Flag value for file handling functions */ #include -#ifndef WIN32 -#include /* Consts and structs defined by the internet system */ -#define BINARY_FILE_OPTS -#else -#include -#define BINARY_FILE_OPTS "b" -#endif /* from $(INSTALLDIR)/include */ #include /* Main header file for the BFD library */ #include +#include "stubs.h" +const char *elf2flt_progname; + #if defined(TARGET_h8300) #include /* TARGET_* ELF support for the BFD library */ #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2) @@ -153,75 +149,6 @@ int use_resolved = 0; /* If true, get the value of symbol references from */ /* Set if the text section contains any relocations. If it does, we must set the load_to_ram flag. */ int text_has_relocs = 0; -const char *progname, *filename; -int lineno; - -int nerrors = 0; -int nwarnings = 0; - -static char where[200]; - -enum { - /* Use exactly one of these: */ - E_NOFILE = 0, /* "progname: " */ - E_FILE = 1, /* "filename: " */ - E_FILELINE = 2, /* "filename:lineno: " */ - E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */ - - /* Add in any of these with |': */ - E_WARNING = 0x10, - E_PERROR = 0x20 -}; - -void ewhere (const char *format, ...); -void einfo (int type, const char *format, ...); - - -void -ewhere (const char *format, ...) { - va_list args; - va_start (args, format); - vsprintf (where, format, args); - va_end (args); -} - - -void -einfo (int type, const char *format, ...) { - va_list args; - - switch (type & 0x0f) { - case E_NOFILE: - fprintf (stderr, "%s: ", progname); - break; - case E_FILE: - fprintf (stderr, "%s: ", filename); - break; - case E_FILELINE: - ewhere ("%d", lineno); - /* fall-through */ - case E_FILEWHERE: - fprintf (stderr, "%s:%s: ", filename, where); - break; - } - - if (type & E_WARNING) { - fprintf (stderr, "warning: "); - nwarnings++; - } else { - nerrors++; - } - - va_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - - if (type & E_PERROR) - perror (""); - else - fprintf (stderr, "\n"); -} - asymbol** get_symbols (bfd *abfd, long *num) @@ -443,11 +370,9 @@ dump_symbols(symbols, number_of_symbols); printf("GOT table contains %d entries (%d bytes)\n", got_size/sizeof(uint32_t), got_size); #ifdef TARGET_m68k - if (got_size > GOT_LIMIT) { - fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n", - got_size, GOT_LIMIT); - exit(1); - } + if (got_size > GOT_LIMIT) + fatal("GOT too large: %d bytes (limit = %d bytes)", + got_size, GOT_LIMIT); #endif } @@ -1645,10 +1570,8 @@ printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n", -static char * program; - static void usage(void) -{ +{ fprintf(stderr, "Usage: %s [vrzd] [-p ] [-s stack-size] " "[-o ] \n\n" " -v : verbose operation\n" @@ -1663,7 +1586,7 @@ static void usage(void) " -p abs-pic-file : GOT/PIC processing with files\n" " -s stacksize : set application stack size\n" " -o output-file : output file name\n\n", - program); + elf2flt_progname); fprintf(stderr, "Compiled for " ARCH " architecture\n\n"); exit(2); } @@ -1716,23 +1639,20 @@ int main(int argc, char *argv[]) void *text; void *data; uint32_t *reloc; - + struct flat_hdr hdr; - program = argv[0]; - progname = argv[0]; - xmalloc_set_program_name(program); + elf2flt_progname = argv[0]; + xmalloc_set_program_name(elf2flt_progname); if (argc < 2) usage(); - - if (sizeof(hdr) != 64) { - fprintf(stderr, + + if (sizeof(hdr) != 64) + fatal( "Potential flat header incompatibility detected\n" - "header size should be 64 but is %d\n", + "header size should be 64 but is %d", sizeof(hdr)); - exit(64); - } #ifndef TARGET_e1 stack = 4096; @@ -1789,7 +1709,7 @@ int main(int argc, char *argv[]) if (!load_to_ram && !pfile) load_to_ram = 1; - filename = fname = argv[argc-1]; + fname = argv[argc-1]; if (pfile) { pic_with_got = 1; @@ -1800,43 +1720,30 @@ int main(int argc, char *argv[]) if (! rel_file) rel_file = fname; - if (!(rel_bfd = bfd_openr(rel_file, 0))) { - fprintf(stderr, "Can't open %s\n", rel_file); - exit(1); - } + if (!(rel_bfd = bfd_openr(rel_file, 0))) + fatal_perror("Can't open '%s'", rel_file); - if (bfd_check_format (rel_bfd, bfd_object) == 0) { - fprintf(stderr, "File is not an object file\n"); - exit(2); - } + if (bfd_check_format (rel_bfd, bfd_object) == 0) + fatal("File is not an object file"); if (abs_file == rel_file) abs_bfd = rel_bfd; /* one file does all */ else { - if (!(abs_bfd = bfd_openr(abs_file, 0))) { - fprintf(stderr, "Can't open %s\n", abs_file); - exit(1); - } + if (!(abs_bfd = bfd_openr(abs_file, 0))) + fatal_perror("Can't open '%s'", abs_file); - if (bfd_check_format (abs_bfd, bfd_object) == 0) { - fprintf(stderr, "File is not an object file\n"); - exit(2); - } + if (bfd_check_format (abs_bfd, bfd_object) == 0) + fatal("File is not an object file"); } - if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) { - fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file); - exit (2); - } + if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) + fatal("%s: Input file contains no relocation info", rel_file); - if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) { + if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) /* `Absolute' file is not absolute, so neither are address contained therein. */ - fprintf (stderr, - "%s: `-a' option specified with non-fully-resolved input file\n", + fatal("%s: `-a' option specified with non-fully-resolved input file", bfd_get_filename (abs_bfd)); - exit (2); - } symbol_table = get_symbols(abs_bfd, &number_of_symbols); @@ -1871,10 +1778,8 @@ int main(int argc, char *argv[]) *len = sec_vma + sec_size - *vma; } - if (text_len == 0) { - fprintf (stderr, "%s: no .text section", abs_file); - exit (2); - } + if (text_len == 0) + fatal("%s: no .text section", abs_file); text = xmalloc(text_len); @@ -1888,14 +1793,11 @@ int main(int argc, char *argv[]) text + (s->vma - text_vma), 0, bfd_section_size(abs_bfd, s))) { - fprintf(stderr, "read error section %s\n", s->name); - exit(2); + fatal("read error section %s", s->name); } - if (data_len == 0) { - fprintf (stderr, "%s: no .data section", abs_file); - exit (2); - } + if (data_len == 0) + fatal("%s: no .data section", abs_file); data = xmalloc(data_len); if (verbose) @@ -1919,8 +1821,7 @@ int main(int argc, char *argv[]) data + (s->vma - data_vma), 0, bfd_section_size(abs_bfd, s))) { - fprintf(stderr, "read error section %s\n", s->name); - exit(2); + fatal("read error section %s", s->name); } if (bss_vma == ~0) @@ -1988,18 +1889,14 @@ int main(int argc, char *argv[]) strcat(ofile, ".bflt"); } - if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) { - fprintf (stderr, "Can't open output file %s\n", ofile); - exit(4); - } + if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0) + fatal_perror("Can't open output file %s", ofile); write(fd, &hdr, sizeof(hdr)); close(fd); - if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS)) { - fprintf(stderr, "Can't open file %s for writing\n", ofile); - exit(4); - } + if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS)) + fatal_perror("Can't open file %s for writing", ofile); if (docompress == 1) reopen_stream_compressed(&gf); diff --git a/flthdr.c b/flthdr.c index 90f9aa3..0485107 100644 --- a/flthdr.c +++ b/flthdr.c @@ -18,18 +18,12 @@ #include #include -/* macros for conversion between host and (internet) network byte order */ -#ifndef WIN32 -#include /* Consts and structs defined by the internet system */ -#define BINARY_FILE_OPTS -#else -#include -#define BINARY_FILE_OPTS "b" -#endif - #include "compress.h" #include +#include "stubs.h" +const char *elf2flt_progname; + /* from uClinux-x.x.x/include/linux */ #include "flat.h" /* Binary flat header description */ @@ -48,8 +42,6 @@ /****************************************************************************/ -char *program_name; - static int print = 0, print_relocs = 0, docompress = 0, ramload = 0, stacksize = 0, ktrace = 0, l1stack = 0; @@ -239,16 +231,14 @@ process_file(char *ifile, char *ofile) tfile = make_temp_file("flthdr"); if (fopen_stream_u(&ofp, tfile, "w" BINARY_FILE_OPTS)) { - fprintf(stderr, "Failed to open %s for writing\n", tfile); unlink(tfile); - exit(1); + fatal("Failed to open %s for writing\n", tfile); } /* Copy header (always uncompressed). */ if (fwrite_stream(&new_hdr, sizeof(new_hdr), 1, &ofp) != 1) { - fprintf(stderr, "Failed to write to %s\n", tfile); unlink(tfile); - exit(1); + fatal("Failed to write to %s\n", tfile); } /* Whole input file (including text) is compressed: start decompressing @@ -283,11 +273,10 @@ process_file(char *ifile, char *ofile) output_error = ferror_stream(&ofp); if (input_error || output_error) { - fprintf(stderr, "Error on file pointer%s%s\n", + unlink(tfile); + fatal("Error on file pointer%s%s\n", input_error ? " input" : "", output_error ? " output" : ""); - unlink(tfile); - exit(1); } fclose_stream(&ifp); @@ -313,7 +302,7 @@ usage(char *s) { if (s) fprintf(stderr, "%s\n", s); - fprintf(stderr, "usage: %s [options] flat-file\n", program_name); + fprintf(stderr, "usage: %s [options] flat-file\n", elf2flt_progname); fprintf(stderr, " Allows you to change an existing flat file\n\n"); fprintf(stderr, " -p : print current settings\n"); fprintf(stderr, " -P : print relocations\n"); @@ -340,7 +329,7 @@ main(int argc, char *argv[]) int c; char *ofile = NULL, *ifile; - program_name = argv[0]; + elf2flt_progname = argv[0]; while ((c = getopt(argc, argv, "pPdzZrRuUkKs:o:")) != EOF) { switch (c) { diff --git a/ld-elf2flt.c b/ld-elf2flt.c new file mode 100644 index 0000000..01f9c4a --- /dev/null +++ b/ld-elf2flt.c @@ -0,0 +1,571 @@ +/* + * Wrapper for the real linker and the elf2flt converter. This was + * originally a simple shell script, but that doesn't work on a + * Windows host without cygwin. + * The proper long term solution is to add FLT as a BFD output format. + * + * Converted from ld-elf2flt.in by Nathan Sidwell, nathan@codesourcery.com. + * Updated to latest elf2flt code by Mike Frysinger, vapier@gentoo.org. + * + * This is Free Software, under the GNU General Public License V2 or greater. + * + * Copyright (C) 2006, CodeSourcery Inc. + * Copyright (C) 2009, Analog Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stubs.h" +const char *elf2flt_progname; + +static int flag_verbose = 0, flag_final = 1, have_elf2flt_options = 0, + flag_move_data = 0, want_shared = 0; +static const char *shared_lib_id = NULL; +static const char *output_file = "a.out"; +static const char *linker_script = NULL; +static const char *emulation = NULL; +static const char *tmp_file = NULL; +static const char *output_gdb = NULL; +static const char *output_elf = NULL; +static const char *output_flt = NULL; +static options_t search_dirs, all_options, other_options, flt_options; + +static const char *linker = NULL; +static const char *elf2flt = NULL; +static const char *nm = NULL; +static const char *objdump = NULL; +static const char *objcopy = NULL; +static const char *tooldir = "."; +static const char *ldscriptpath = BINUTILS_LDSCRIPTDIR; + +/* A list of sed commands */ +typedef struct { + options_t *pattern; /* '^' for start of line match, everything else verbatim */ + options_t *replacement; /* Delete line, if NULL */ +} sed_commands_t; + +/* Initialize a sed structure */ +#define init_sed(DST) ( \ + (DST)->pattern = xmalloc(sizeof(*(DST)->pattern)), \ + (DST)->replacement = xmalloc(sizeof(*(DST)->replacement)), \ + init_options((DST)->pattern), \ + init_options((DST)->replacement) \ +) +#define free_sed(DST) (free((DST)->pattern), free((DST)->replacement)) + +/* Append a slot for a new sed command. */ +static void append_sed(sed_commands_t *dst, const char *pattern, + const char *replacement) +{ + debug1("adding pattern '%s' with replacement '%s'\n", + pattern, replacement); + append_option(dst->pattern, pattern); + append_option(dst->replacement, replacement); +} + +/* Execute an external program COMMAND. Write its stdout to OUTPUT, + unless that is NULL. Pass the trailing NULL terminated list of + options, followed by all those in OPTIONS, if that is non-NULL. */ +static int +execute(const char *command, const char *output, const options_t *options, ...) +{ + struct pex_obj *pex; + const char *errmsg; + int err; + int status; + va_list args; + const char *opt; + options_t opts; + + debug("command=%s\n", command); + + init_options(&opts); + append_option(&opts, command); + va_start(args, options); + while ((opt = va_arg(args, const char *))) + append_option(&opts, opt); + va_end(args); + if (options) + append_options(&opts, options); + append_option(&opts, NULL); + + fflush(stdout); + fflush(stderr); + + pex = pex_init(0, elf2flt_progname, NULL); + if (pex == NULL) + fatal_perror("pex_init failed"); + + if (flag_verbose) { + unsigned ix; + + fprintf(stderr, "Invoking:"); + for (ix = 0; ix != opts.num - 1; ix++) + fprintf(stderr, " '%s'", opts.options[ix]); + fprintf(stderr, "\n"); + } + + errmsg = pex_run(pex, PEX_LAST | PEX_SEARCH, command, + (char *const *)opts.options, output, NULL, &err); + if (errmsg != NULL) { + if (err != 0) { + errno = err; + fatal_perror(errmsg); + } else + fatal(errmsg); + } + + if (!pex_get_status(pex, 1, &status)) + fatal_perror("can't get program status"); + pex_free(pex); + + if (status) { + if (WIFSIGNALED(status)) { + int sig = WTERMSIG(status); + + fatal("%s terminated with signal %d [%s]%s", + command, sig, strsignal(sig), + WCOREDUMP(status) ? ", core dumped" : ""); + } + + if (WIFEXITED(status)) + return WEXITSTATUS(status); + } + return 0; +} +/* Auto NULL terminate */ +#define execute(...) execute(__VA_ARGS__, NULL) + +/* Apply the sed commands in SED to file NAME_IN producing file NAME_OUT */ +static void +do_sed(const sed_commands_t *sed, const char *name_in, const char *name_out) +{ + FILE *in, *out; + size_t alloc = 0; + char *line = NULL; + ssize_t len; + const char *pattern, *replacement; + int ix; + + if (flag_verbose) { + fprintf(stderr, "emulating: sed \\\n"); + for (ix = 0; ix != sed->pattern->num; ix++) { + pattern = sed->pattern->options[ix]; + replacement = sed->replacement->options[ix]; + if (replacement) + fprintf(stderr, "\t-e 's/%s/%s/' \\\n", pattern, replacement); + else + fprintf(stderr, "\t-e 'd/%s/' \\\n", pattern); + } + fprintf(stderr, "\t%s > %s\n", name_in, name_out); + } + + in = xfopen(name_in, "r"); + out = xfopen(name_out, "w"); + + while ((len = getline(&line, &alloc, in)) > 0) { + debug2("len=%2zi line=%s", len, line); + + for (ix = 0; ix != sed->pattern->num; ix++) { + const char *ptr; + int bol; + size_t pat_len; + + pattern = sed->pattern->options[ix]; + replacement = sed->replacement->options[ix]; + ptr = line; + bol = pattern[0] == '^'; + + pattern += bol; + pat_len = strlen(pattern); + + if (!bol) { + do { + ptr = strchr(ptr, pattern[0]); + if (!ptr) ; + else if (!strncmp(ptr, pattern, pat_len)) + goto found; + else + ptr++; + } + while (ptr); + } else if (!strncmp(ptr, pattern, pat_len)) { + found: + if (replacement) { + debug2(" [modified]\n"); + fwrite(line, 1, ptr - line, out); + fwrite(replacement, 1, strlen(replacement), out); + fwrite(ptr + pat_len, 1, + len - pat_len - (ptr - line), + out); + } else + debug2(" {dropped}\n"); + goto next_line; + } + } + + debug2("(untouched)\n"); + fwrite(line, 1, len, out); + next_line: + ; + } + fclose(in); + if (fclose(out)) + fatal_perror("error writing temporary script '%s'", name_out); + free(line); +} + +/* Generate the flt binary along with any other necessary pieces. */ +#define exec_or_ret(...) \ + do { \ + int status = execute(__VA_ARGS__); \ + if (status) return status; \ + } while (0) +static int do_final_link(void) +{ + sed_commands_t sed; + struct stat buf; + const char *script; + const char *rel_output; + int have_got = 0; + FILE *in; + char *line = NULL; + size_t alloc = 0; + ssize_t len; + + init_sed(&sed); + + if (flag_move_data) { + FILE *in; + + /* See if the .rodata section contains any relocations. */ + if (!output_flt) + output_flt = make_temp_file(NULL); + exec_or_ret(linker, NULL, &other_options, "-r", "-d", "-o", output_flt); + exec_or_ret(objdump, tmp_file, NULL, "-h", output_flt); + + in = xfopen(tmp_file, "r"); + while ((len = getline(&line, &alloc, in)) > 0) { + const char *ptr = line; + + while (1) { + ptr = strchr(ptr, '.'); + if (!ptr) + break; + if (streqn(ptr, ".rodata")) { + getline(&line, &alloc, in); + ptr = line; + while (1) { + ptr = strchr(ptr, 'R'); + if (!ptr) + break; + if (streqn(ptr, "RELOC")) { + flag_move_data = 0; + fprintf(stderr, "warning: .rodata section contains relocations"); + break; + } else + ptr++; + } + break; + } else + ptr++; + } + } + fclose(in); + } + append_sed(&sed, "^R_RODAT", flag_move_data ? NULL : ""); + append_sed(&sed, "^W_RODAT", flag_move_data ? "" : NULL); + append_sed(&sed, "^SINGLE_LINK:", USE_EMIT_RELOCS ? "" : NULL); + append_sed(&sed, "^TOR:", EMIT_CTOR_DTOR ? "" : NULL); + + if (shared_lib_id) { + const char *got_offset; + int adj, id = strtol(shared_lib_id, NULL, 0); + char buf[30]; + + /* Replace addresses using the shared object id. */ + sprintf(buf, "%.2X", id); + append_sed(&sed, "ORIGIN = 0x0,", concat("ORIGIN = 0x", buf, "000000,", NULL)); + append_sed(&sed, ".text 0x0 :", concat(".text 0x0", buf, "000000 :", NULL)); + if (id) + append_sed(&sed, "ENTRY (" SYMBOL_PREFIX "_start)", "ENTRY (lib_main)"); + + /* Provide the symbol specifying the library's data segment + pointer offset. */ + adj = 4; + if (streq(TARGET_CPU, "h8300")) + got_offset = "__current_shared_library_er5_offset_"; + else if (streq(TARGET_CPU, "bfin")) + got_offset = "_current_shared_library_p5_offset_", adj = 1; + else + got_offset = "_current_shared_library_a5_offset_"; + append_option(&other_options, "-defsym"); + sprintf(buf, "%d", id * -adj - adj); + append_option(&other_options, concat(got_offset, "=", buf, NULL)); + } + + /* Locate the default linker script, if we don't have one provided. */ + if (!linker_script) + linker_script = concat(ldscriptpath, "/elf2flt.ld", NULL); + + /* Try and locate the linker script. */ + script = linker_script; + if (stat(script, &buf) || !S_ISREG(buf.st_mode)) { + script = concat(ldscriptpath, "/", linker_script, NULL); + if (stat(script, &buf) || !S_ISREG(buf.st_mode)) { + script = concat(ldscriptpath, "/ldscripts/", linker_script, NULL); + if (stat(script, &buf) || !S_ISREG(buf.st_mode)) + script = NULL; + } + } + /* And process it if we can -- if we can't find it, the user must + know what they are doing. */ + if (script) { + do_sed(&sed, linker_script, tmp_file); + linker_script = tmp_file; + } + free_sed(&sed); + + if (USE_EMIT_RELOCS) { + + exec_or_ret(linker, NULL, &other_options, + "-T", linker_script, "-q", "-o", output_gdb, emulation); + + append_option(&flt_options, "-a"); + rel_output = output_gdb; + + } else if (NO_GOT_CHECK) { + + output_elf = make_temp_file(NULL); + + exec_or_ret(linker, NULL, &other_options, + "-T", linker_script, "-Ur", "-d", "-o", output_elf, emulation); + exec_or_ret(linker, NULL, &other_options, + "-T", linker_script, "-o", output_gdb, emulation); + + rel_output = output_elf; + + } else { + + output_flt = make_temp_file(NULL); + exec_or_ret(linker, NULL, &other_options, + "-r", "-d", "-o", output_flt, emulation); + + output_elf = make_temp_file(NULL); + exec_or_ret(linker, NULL, &search_dirs, + "-T", linker_script, "-Ur", "-o", output_elf, output_flt, emulation); + + exec_or_ret(linker, NULL, &search_dirs, + "-T", linker_script, "-o", output_gdb, output_flt, emulation); + + rel_output = output_elf; + + } + + if (shared_lib_id && strtol(shared_lib_id, NULL, 0) != 0) + exec_or_ret(objcopy, NULL, NULL, "--localize-hidden", "--weaken", output_gdb); + + exec_or_ret(nm, tmp_file, NULL, "-p", output_gdb); + in = xfopen(tmp_file, "r"); + while ((len = getline(&line, &alloc, in)) > 0) { + const char *ptr = strchr(line, '_'); + if (ptr && streqn(ptr, "_GLOBAL_OFFSET_TABLE")) { + have_got = 1; + break; + } + } + fclose(in); + if (have_got) + exec_or_ret(elf2flt, NULL, &flt_options, + "-o", output_file, "-p", output_gdb, rel_output); + else + exec_or_ret(elf2flt, NULL, &flt_options, + "-o", output_file, "-r", rel_output); + + return 0; +} + +/* parse all the arguments provided to us */ +static void parse_args(int argc, char **argv) +{ + char *fltflags; + int argno; + + for (argno = 1; argno < argc; argno++) { + char const *arg = argv[argno]; + int to_all = argno; + + if (streq(arg, "-elf2flt")) { + have_elf2flt_options = 1; + to_all++; + } else if (streqn(arg, "-elf2flt=")) { + have_elf2flt_options = 1; + append_option_str(&flt_options, &arg[9], "\t "); + to_all++; + } else if (streq(arg, "-move-rodata")) { + flag_move_data = 1; + } else if (streq(arg, "-shared-lib-id")) { + shared_lib_id = argv[++argno]; + } else if (streq(arg, "-shared") || streq(arg, "-G")) { + want_shared = 1; + } else if (streqn(arg, "-o")) { + output_file = arg[2] ? &arg[2] : argv[++argno]; + } else if (streqn(arg, "-T")) { + linker_script = arg[2] ? &arg[2] : argv[++argno]; + } else if (streq(arg, "-c")) { + linker_script = argv[++argno]; + } else if (streqn(arg, "-L")) { + const char *merged = + (arg[2] ? arg : concat("-L", argv[++argno], NULL)); + append_option(&other_options, merged); + append_option(&search_dirs, merged); + } else if (streq(arg, "-EB")) { + append_option(&other_options, arg); + append_option(&search_dirs, arg); + } else if (streq(arg, "-relax")) { + ; + } else if (streq(arg, "-s") || streq(arg, "--strip-all") || + streq(arg, "-S") || streq(arg, "--strip-debug")) { + /* Ignore these strip options for links involving elf2flt. + The final flat output will be stripped by definition, and we + don't want to strip the .gdb helper file. The strip options + are also incompatible with -r and --emit-relocs. */ + ; + } else if (streq(arg, "-r") || streq(arg, "-Ur")) { + flag_final = 0; + append_option(&other_options, arg); + } else if (streq(arg, "-v") || streq(arg, "--verbose")) { + flag_verbose = 1; + append_option(&other_options, arg); + } else if (streqn(arg, "-m")) { + emulation = arg[2] ? arg : concat("-m", argv[++argno], NULL); + } else + append_option(&other_options, arg); + + while (to_all <= argno) + append_option(&all_options, argv[to_all++]); + } + + fltflags = getenv("FLTFLAGS"); + if (fltflags) + append_option_str(&flt_options, fltflags, "\t "); +} + +int main(int argc, char *argv[]) +{ + const char *ptr; + char *tmp; + const char *argv0 = argv[0]; + size_t len; + struct stat buf; + const char *have_exe = NULL; + int status; + + len = strlen(argv0); +#ifdef __WIN32 + /* Remove the .exe extension, if it's there. */ + if (len > 4 && streq(&argv0[len - 4], ".exe")) { + have_exe = ".exe"; + len -= 4; + argv0 = tmp = xstrdup(argv0); + tmp[len] = 0; + } +#endif + elf2flt_progname = argv0; + for (ptr = elf2flt_progname + len; ptr != elf2flt_progname; ptr--) + if (IS_DIR_SEPARATOR(ptr[-1])) { + tooldir = tmp = xmalloc(len); + memcpy(tmp, argv0, len); + tmp[ptr - elf2flt_progname - 1] = 0; + elf2flt_progname = ptr; + /* The standard binutils tool layout has: + + bin/-foo + lib/ + /bin/foo + /lib + + It's / that we want here: files in lib/ are for + the host while those in /lib are for the target. */ + if (streqn(elf2flt_progname, TARGET_ALIAS)) { + tmp = concat(tooldir, "/../" TARGET_ALIAS "/bin", NULL); + if (stat(tmp, &buf) == 0 && S_ISDIR(buf.st_mode)) + tooldir = tmp; + } + break; + } + /* Typically ld-elf2flt is invoked as `ld` which means error + * messages from it will look like "ld: " which is completely + * confusing. So append an identifier to keep things clear. + */ + elf2flt_progname = concat(elf2flt_progname, " (ld-elf2flt)", NULL); + + xmalloc_set_program_name(elf2flt_progname); + + tmp = xmalloc(len + 16); + memcpy(tmp, argv0, len); + while (len && tmp[len - 1] != '-' && !IS_DIR_SEPARATOR(tmp[len - 1])) + len--; + tmp[len] = 0; + + linker = concat(tmp, "ld.real", have_exe, NULL); + elf2flt = concat(tmp, "elf2flt", have_exe, NULL); + nm = concat(tmp, "nm", have_exe, NULL); + objdump = concat(tooldir, "/../../bin/", TARGET_ALIAS, "-objdump", have_exe, NULL); + objcopy = concat(tooldir, "/../../bin/", TARGET_ALIAS, "-objcopy", have_exe, NULL); + + if (stat(ldscriptpath, &buf) || !S_ISDIR(buf.st_mode)) + ldscriptpath = concat(tooldir, "/../lib", NULL); + + parse_args(argc, argv); + + if (flag_verbose) { + fprintf(stderr, "argv[0] = '%s'\n", argv[0]); + fprintf(stderr, "tooldir = '%s'\n", tooldir); + fprintf(stderr, "linker = '%s'\n", linker); + fprintf(stderr, "elf2flt = '%s'\n", elf2flt); + fprintf(stderr, "nm = '%s'\n", nm); + fprintf(stderr, "objdump = '%s'\n", objdump); + fprintf(stderr, "objcopy = '%s'\n", objcopy); + fprintf(stderr, "ldscriptpath = '%s'\n", ldscriptpath); + } + + /* Pass off to regular linker, if there's nothing elf2flt-like */ + if (!have_elf2flt_options) + return execute(linker, NULL, &all_options); + + /* Pass off to regular linker, minus the elf2flt options, if it's + not the final link. */ + if (!flag_final) + return execute(linker, NULL, &other_options, "-o", output_file); + + if (want_shared && !shared_lib_id) + fatal("-shared used without passing a shared library ID"); + + /* Otherwise link & convert to flt. */ + output_gdb = concat(output_file, ".gdb", NULL); + tmp_file = make_temp_file(NULL); + status = do_final_link(); + if (!flag_verbose) { + unlink(tmp_file); + unlink(output_flt); + unlink(output_elf); + } else { + fprintf(stderr, + "leaving elf2flt temp files behind:\n" + "tmp_file = %s\n" + "output_flt = %s\n" + "output_elf = %s\n", + tmp_file, output_flt, output_elf); + } + return status; +} diff --git a/ld-elf2flt.in b/ld-elf2flt.in deleted file mode 100644 index 91e1ccb..0000000 --- a/ld-elf2flt.in +++ /dev/null @@ -1,239 +0,0 @@ -#!/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 "$@" diff --git a/stubs.c b/stubs.c index 59760a3..696ed3b 100644 --- a/stubs.c +++ b/stubs.c @@ -1,13 +1,133 @@ +#include +#include +#include +#include +#include + +#include "libiberty.h" + +#include "stubs.h" + #ifndef HAVE_DCGETTEXT -const char *dcgettext (const char *domain, const char *msg, int category) +const char *dcgettext(const char *domain, const char *msg, int category) { return msg; } #endif /* !HAVE_DCGETTEXT */ #ifndef HAVE_LIBINTL_DGETTEXT -const char *libintl_dgettext (const char *domain, const char *msg) +const char *libintl_dgettext(const char *domain, const char *msg) { return msg; } #endif /* !HAVE_LIBINTL_DGETTEXT */ + +#ifndef HAVE_GETLINE +/* Read a line from IN. LINE points to a malloc'd buffer that is extended as + necessary. ALLOC points to the allocated length of LINE. Returns + the length of the string read (including any trailing \n) */ + +ssize_t getline(char **line, size_t *alloc, FILE *in) +{ + size_t len = 0; + + if (!*alloc) { + *alloc = 200; + *line = xmalloc(*alloc); + } + + while (1) { + if (!fgets(*line + len, *alloc - len, in)) + return 0; + len += strlen(*line + len); + if (len && (*line)[len - 1] == '\n') + return len; + + *alloc *= 2; + *line = xrealloc(*line, *alloc); + } +} +#endif + +/* fatal error & exit */ +void fatal(const char *format, ...) +{ + va_list args; + + va_start(args, format); + fprintf(stderr, "%s: ", elf2flt_progname); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + va_end(args); + exit(1); +} + +/* fatal error, perror & exit */ +void fatal_perror(const char *format, ...) +{ + int e = errno; + va_list args; + + va_start(args, format); + fprintf(stderr, "%s: ", elf2flt_progname); + vfprintf(stderr, format, args); + fprintf(stderr, ": %s\n", strerror(e)); + va_end(args); + exit(1); +} + +/* open a file or fail */ +FILE *xfopen(const char *path, const char *mode) +{ + FILE *ret = fopen(path, mode); + if (!ret) + fatal_perror("Unable to open '%s'", path); + return ret; +} + +/* Append a string SRC to an options array DST */ +void append_option(options_t *dst, const char *src) +{ + if (dst->alloc == dst->num) { + size_t a = (dst->num + 2) * 2; + void *o = xmalloc(sizeof(*dst->options) * a); + + memcpy(o, dst->options, sizeof(*dst->options) * dst->num); + free(dst->options); + dst->options = o; + dst->alloc = a; + } + + dst->options[dst->num] = src; + dst->num++; +} + +/* Split and append a string SRC to an options array DST */ +void append_option_str(options_t *dst, const char *src, const char *delim) +{ + char *tok_src = xstrdup(src); + char *tok = strtok(tok_src, delim); + while (tok) { + append_option(dst, tok); + tok = strtok(NULL, delim); + } + /* don't free tok_src since options_t now points to it */ +} + +/* Append an options array SRC to another options array DST */ +void append_options(options_t *dst, const options_t *src) +{ + if (dst->alloc < dst->num + src->num) { + size_t a = (dst->num + src->num + 2) * 2; + void *o = xmalloc(sizeof(*dst->options) * a); + + memcpy(o, dst->options, sizeof(*dst->options) * dst->num); + free(dst->options); + dst->options = o; + dst->alloc = a; + } + + memcpy(&dst->options[dst->num], &src->options[0], + sizeof(*dst->options) * src->num); + dst->num += src->num; +} diff --git a/stubs.h b/stubs.h new file mode 100644 index 0000000..7e5308d --- /dev/null +++ b/stubs.h @@ -0,0 +1,75 @@ +/* macros for conversion between host and (internet) network byte order */ +#ifndef WIN32 +# include /* Consts and structs defined by the internet system */ +# define BINARY_FILE_OPTS +#else +# include +# define BINARY_FILE_OPTS "b" +#endif + +#ifndef __WIN32 +# include +#endif +#ifndef WIFSIGNALED +# define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f) +#endif +#ifndef WTERMSIG +# define WTERMSIG(S) ((S) & 0x7f) +#endif +#ifndef WIFEXITED +# define WIFEXITED(S) (((S) & 0xff) == 0) +#endif +#ifndef WEXITSTATUS +# define WEXITSTATUS(S) (((S) & 0xff00) >> 8) +#endif +#ifndef WCOREDUMP +# define WCOREDUMP(S) ((S) & WCOREFLG) +#endif +#ifndef WCOREFLG +# define WCOREFLG 0200 +#endif +#ifndef HAVE_STRSIGNAL +# define strsignal(sig) "SIG???" +#endif + +#define streq(str1, str2) (strcmp(str1, str2) == 0) +#define streqn(str1, str2) (strncmp(str1, str2, strlen(str2)) == 0) + +#ifndef DEBUG +# define DEBUG -1 +#endif +#define _debug(lvl, fmt, args...) \ + do { \ + if (lvl <= DEBUG) { \ + fprintf(stderr, "%s:%i: " fmt, __func__, __LINE__, ## args); \ + fflush(stderr); \ + } \ + } while (0) +#define debug2(...) _debug(2, __VA_ARGS__) +#define debug1(...) _debug(1, __VA_ARGS__) +#define debug0(...) _debug(0, __VA_ARGS__) +#define debug(...) debug0(__VA_ARGS__) + +#ifndef HAVE_GETLINE +ssize_t getline(char **line, size_t *alloc, FILE *in); +#endif + +extern const char *elf2flt_progname; + +void fatal(const char *, ...); +void fatal_perror(const char *, ...); + +FILE *xfopen(const char *path, const char *mode); + +/* Structure to hold a list of options */ +typedef struct +{ + const char **options; + size_t num; + size_t alloc; +} options_t; +/* Initialize an options structure */ +#define init_options(DST) ((DST)->options = NULL, (DST)->num = (DST)->alloc = 0) +void append_options(options_t *dst, const options_t *src); +void append_option(options_t *dst, const char *src); +void append_option_str(options_t *dst, const char *src, const char *delim); -- 1.6.3.3