From 6ae8f1cc9abd2c25b3376a18f33fee00d9e771cf Mon Sep 17 00:00:00 2001 From: Alexey Neyman Date: Mon, 27 Feb 2017 01:20:10 -0800 Subject: [PATCH 1/2] When looking for binutils/BFD headers, create a local include dir ... and filter only those headers that elf2flt binaries are going to use, to minimize the chance of clashes with system headers. Signed-off-by: Alexey Neyman --- Makefile.in | 13 ++++++-- configure | 4 +-- configure.ac | 4 +-- mk-local-include.sh | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 7 deletions(-) create mode 100755 mk-local-include.sh diff --git a/Makefile.in b/Makefile.in index a6feea6..1e34bda 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,7 +14,9 @@ CPU = @target_cpu@ TARGET = @target_alias@ SYMBOL_PREFIX = @SYMBOL_PREFIX@ CFLAGS = @CFLAGS@ -INCLUDES = -I$(srcdir) @bfd_include_dir@ @binutils_include_dir@ @zlib_include_dir@ +INCLUDES = -I$(srcdir) -Ilocal-include @zlib_include_dir@ +BFD_INCLUDE_DIR = @bfd_include_dir@ +BINUTILS_INCLUDE_DIR = @binutils_include_dir@ CPPFLAGS = @CPPFLAGS@ $(DEFS) $(INCLUDES) LDFLAGS = @LDFLAGS@ LDLIBS = @LIBS@ @@ -101,7 +103,7 @@ check-flthdr: check: check-flthdr clean: - -rm -f $(PROGS) *.$(OBJEXT) .deps + -rm -f $(PROGS) *.$(OBJEXT) .deps local-include distclean: clean -rm -f Makefile config.log config.status config.cache ld-elf2flt @@ -121,5 +123,10 @@ install: $(INSTALL) -m 644 $(SRC_LDFILE) $(DESTDIR)$(target_libdir)/$(LDFILE) sinclude .deps -.deps: +.deps: local-include/.stamp $(CC) -MM $(CPPFLAGS) $(srcdir)/*.c > .deps + +local-include/.stamp: $(srcdir)/mk-local-include.sh + bash $(srcdir)/mk-local-include.sh local-include '$(CC)' \ + '$(BFD_INCLUDE_DIR)' '$(BINUTILS_INCLUDE_DIR)' $(DEFS) + touch $@ diff --git a/configure b/configure index 3a4e8d6..af64990 100755 --- a/configure +++ b/configure @@ -3931,12 +3931,12 @@ fi bfd_include_dir= if test "$ac_bfd_include_dir" != "NONE"; then - bfd_include_dir="-I$ac_bfd_include_dir" + bfd_include_dir="$ac_bfd_include_dir" fi binutils_include_dir= if test "$ac_binutils_include_dir" != "NONE"; then - binutils_include_dir="-I$ac_binutils_include_dir" + binutils_include_dir="$ac_binutils_include_dir" fi zlib_include_dir= diff --git a/configure.ac b/configure.ac index 6002894..b7fb790 100644 --- a/configure.ac +++ b/configure.ac @@ -135,12 +135,12 @@ fi bfd_include_dir= if test "$ac_bfd_include_dir" != "NONE"; then - bfd_include_dir="-I$ac_bfd_include_dir" + bfd_include_dir="$ac_bfd_include_dir" fi binutils_include_dir= if test "$ac_binutils_include_dir" != "NONE"; then - binutils_include_dir="-I$ac_binutils_include_dir" + binutils_include_dir="$ac_binutils_include_dir" fi zlib_include_dir= diff --git a/mk-local-include.sh b/mk-local-include.sh new file mode 100755 index 0000000..a6e8a63 --- /dev/null +++ b/mk-local-include.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# Binutils provide certain headers that are clashing with system-wide +# headers on Cygwin and MacOS. They do so in different manners, though, +# so it is not possible to just tweak the inclusion/library order. +# Hence, we prepare a filtered inclusion directory where we only place +# the headers that we need for BFD/binutils. To determine them, we'll +# need to preprocess a sample file including the headers that will be used, +# and have the compiler output the actual list of included headers for us. + +# Usage: +# mk-local-include.sh DIR CC BFD-INCLUDES BINUTILS-INCLUDES [DEFINES...] + +local_inc=$1 +cc=$2 +bfd_inc=$3 +binutils_inc=$4 +shift 4 +# What remains are defines to pass to GCC + +case "${local_inc}" in + */*) echo "Local include dir may only have one component" >&2; exit 1;; + .|..) echo "Local include dir may not be . or .." >&2; exit 1;; +esac + +# Re-create it from a clean slate +rm -rf "${local_inc}" +mkdir -p "${local_inc}" + +# Create a dummy source file that we'll preprocess +{ + echo "#include " + echo "#include " + echo "#include " +} > "${local_inc}/_dummy.c" + +$cc ${bfd_inc:+-I${bfd_inc}} ${binutils_inc:+-I${binutils_inc}} "$@" \ + -E -o /dev/null -H "${local_inc}/_dummy.c" 2>&1 | \ + sed -rn -e 's/^\.+ //p' > "${local_inc}/_hdr.list" +if [ $? != 0 ]; then + echo "Failed to locate libiberty.h/bfd.h headers" >&2 + exit 1 +fi + +# Now go over the list twice. First determine how the compiler printed +# the location of and . They themselves may be in +# a system include directory. We'll create a mess of symlinks in that case, +# but they'll still point to the system headers. +while read f; do + case "$f" in + */bfd.h) bfd_loc=${f%/bfd.h};; + */libiberty.h) binutils_loc=${f%/libiberty.h};; + esac +done < $local_inc/_hdr.list + +# Now symlink the headers that reside in the same directory as the headers +# we're looking for, or in any subdirectory thereof. +create_link() { + local f=$1 + local bd=$2 + local relpath lnkname bname src + + relpath=${f#${bd}/} + lnkname=${local_inc}/${relpath} + bname=${relpath##*/} + if [ "${bname}" != "${relpath}" ]; then + mkdir -p "${relpath%/*}" + fi + case "${f}" in + /*) src=${f};; + *) src=../${f};; # account for one extra path component (DIR) + esac + if [ ! -L "${lnkname}" ]; then + ln -s "${src}" "${lnkname}" + fi +} + +while read f; do + case "$f" in + ${bfd_loc}/*) create_link "$f" "${bfd_loc}";; + ${binutils_loc}/*) create_link "$f" "${binutils_loc}";; + esac +done < $local_inc/_hdr.list + +# Final bit of secret knowledge. We need ELF headers, and the exact headers +# depend on the selected target. Fortunately, they are all in the 'elf/' +# subdirectory of binutils include directory, which we get by searching for +# . +create_link "${binutils_loc}/elf" "${binutils_loc}" -- 2.9.3