aboutsummaryrefslogtreecommitdiff
path: root/libctf
diff options
context:
space:
mode:
Diffstat (limited to 'libctf')
-rw-r--r--libctf/Makefile.in3
-rw-r--r--libctf/aclocal.m42
-rwxr-xr-xlibctf/configure405
-rw-r--r--libctf/ctf-decl.c7
-rw-r--r--libctf/ctf-dump.c8
-rw-r--r--libctf/ctf-types.c2
-rw-r--r--libctf/testsuite/lib/ctf-lib.exp43
-rw-r--r--libctf/testsuite/libctf-lookup/big-struct-corruption.c118
-rw-r--r--libctf/testsuite/libctf-lookup/big-struct-corruption.lk3
-rw-r--r--libctf/testsuite/libctf-lookup/big-struct-ctf.c72
-rw-r--r--libctf/testsuite/libctf-lookup/multidim-array-ctf.c3
-rw-r--r--libctf/testsuite/libctf-lookup/multidim-array.c71
-rw-r--r--libctf/testsuite/libctf-lookup/multidim-array.lk9
13 files changed, 718 insertions, 28 deletions
diff --git a/libctf/Makefile.in b/libctf/Makefile.in
index 5d95877..7c309b1 100644
--- a/libctf/Makefile.in
+++ b/libctf/Makefile.in
@@ -134,8 +134,10 @@ subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \
$(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/clang-plugin.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/enable.m4 \
+ $(top_srcdir)/../config/gcc-plugin.m4 \
$(top_srcdir)/../config/gettext-sister.m4 \
$(top_srcdir)/../config/gettext.m4 \
$(top_srcdir)/../config/iconv.m4 \
@@ -475,6 +477,7 @@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
+LLVM_CONFIG = @LLVM_CONFIG@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
diff --git a/libctf/aclocal.m4 b/libctf/aclocal.m4
index fc2b7d7..de7db77 100644
--- a/libctf/aclocal.m4
+++ b/libctf/aclocal.m4
@@ -1229,8 +1229,10 @@ AC_SUBST([am__untar])
m4_include([../bfd/acinclude.m4])
m4_include([../config/acx.m4])
+m4_include([../config/clang-plugin.m4])
m4_include([../config/depstand.m4])
m4_include([../config/enable.m4])
+m4_include([../config/gcc-plugin.m4])
m4_include([../config/gettext-sister.m4])
m4_include([../config/gettext.m4])
m4_include([../config/iconv.m4])
diff --git a/libctf/configure b/libctf/configure
index 89c99c2..becb131 100755
--- a/libctf/configure
+++ b/libctf/configure
@@ -669,6 +669,7 @@ OTOOL
LIPO
NMEDIT
DSYMUTIL
+LLVM_CONFIG
OBJDUMP
LN_S
NM
@@ -8643,8 +8644,266 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
-plugin_option=
+
+# Try CLANG_PLUGIN_FILE first since GCC_PLUGIN_OPTION may return the
+# wrong plugin_option with clang.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang" >&5
+$as_echo_n "checking for clang... " >&6; }
+if ${clang_cv_is_clang+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifdef __clang__
+ yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "yes" >/dev/null 2>&1; then :
+ clang_cv_is_clang=yes
+else
+ clang_cv_is_clang=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $clang_cv_is_clang" >&5
+$as_echo "$clang_cv_is_clang" >&6; }
+ plugin_file=
+ if test $clang_cv_is_clang = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang plugin file" >&5
+$as_echo_n "checking for clang plugin file... " >&6; }
+ plugin_names="LLVMgold.so"
+ for plugin in $plugin_names; do
+ plugin_file=`${CC} ${CFLAGS} --print-file-name $plugin`
+ if test x$plugin_file = x$plugin; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}llvm-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}llvm-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LLVM_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LLVM_CONFIG"; then
+ ac_cv_prog_LLVM_CONFIG="$LLVM_CONFIG" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LLVM_CONFIG="${ac_tool_prefix}llvm-config"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LLVM_CONFIG=$ac_cv_prog_LLVM_CONFIG
+if test -n "$LLVM_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_CONFIG" >&5
+$as_echo "$LLVM_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LLVM_CONFIG"; then
+ ac_ct_LLVM_CONFIG=$LLVM_CONFIG
+ # Extract the first word of "llvm-config", so it can be a program name with args.
+set dummy llvm-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LLVM_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LLVM_CONFIG"; then
+ ac_cv_prog_ac_ct_LLVM_CONFIG="$ac_ct_LLVM_CONFIG" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LLVM_CONFIG="llvm-config"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LLVM_CONFIG=$ac_cv_prog_ac_ct_LLVM_CONFIG
+if test -n "$ac_ct_LLVM_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LLVM_CONFIG" >&5
+$as_echo "$ac_ct_LLVM_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LLVM_CONFIG" = x; then
+ LLVM_CONFIG=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$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
+ LLVM_CONFIG=$ac_ct_LLVM_CONFIG
+ fi
+else
+ LLVM_CONFIG="$ac_cv_prog_LLVM_CONFIG"
+fi
+
+ if test "$?" != 0; then
+ as_fn_error $? "Required tool 'llvm-config' not found on PATH." "$LINENO" 5
+ fi
+ clang_lib_dir=`$LLVM_CONFIG --libdir`
+ if test -f $clang_lib_dir/$plugin; then
+ plugin_file=$clang_lib_dir/$plugin
+ fi
+ if test x$plugin_file != x$plugin; then
+ break;
+ fi
+ fi
+ done
+ if test -z $plugin_file; then
+ as_fn_error $? "Couldn't find clang plugin file for $CC." "$LINENO" 5
+ fi
+ 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:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$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 "${AR}" = "" ; then
+ as_fn_error $? "Required archive tool 'ar' not found on PATH." "$LINENO" 5
+ fi
+ plugin_option="--plugin $plugin_file"
+ touch conftest.c
+ ${AR} $plugin_option rc conftest.a conftest.c
+ if test "$?" != 0; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5
+$as_echo "$as_me: WARNING: Failed: $AR $plugin_option rc" >&2;}
+ plugin_file=
+ fi
+ rm -f conftest.*
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_file" >&5
+$as_echo "$plugin_file" >&6; }
+ fi
+ plugin_file="$plugin_file"
+
+if test -n "$plugin_file"; then
+ plugin_option="--plugin $plugin_file"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -plugin option" >&5
+$as_echo_n "checking for -plugin option... " >&6; }
+
plugin_names="liblto_plugin.so liblto_plugin-0.dll cyglto_plugin-0.dll"
+plugin_option=
for plugin in $plugin_names; do
plugin_so=`${CC} ${CFLAGS} --print-prog-name $plugin`
if test x$plugin_so = x$plugin; then
@@ -8655,7 +8914,119 @@ for plugin in $plugin_names; do
break
fi
done
+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:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$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:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$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:${as_lineno-$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 "${AR}" = "" ; then
+ as_fn_error $? "Required archive tool 'ar' not found on PATH." "$LINENO" 5
+fi
+touch conftest.c
+${AR} $plugin_option rc conftest.a conftest.c
+if test "$?" != 0; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5
+$as_echo "$as_me: WARNING: Failed: $AR $plugin_option rc" >&2;}
+ plugin_option=
+fi
+rm -f conftest.*
+if test -n "$plugin_option"; then
+ plugin_option="$plugin_option"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $plugin_option" >&5
+$as_echo "$plugin_option" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+fi
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
@@ -8750,17 +9121,15 @@ fi
test -z "$AR" && AR=ar
if test -n "$plugin_option"; then
- if $AR --help 2>&1 | grep -q "\--plugin"; then
- touch conftest.c
- $AR $plugin_option rc conftest.a conftest.c
- if test "$?" != 0; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Failed: $AR $plugin_option rc" >&5
-$as_echo "$as_me: WARNING: Failed: $AR $plugin_option rc" >&2;}
- else
+ case "$AR" in
+ *"$plugin_option"*)
+ ;;
+ *)
+ if $AR --help 2>&1 | grep -q "\--plugin"; then
AR="$AR $plugin_option"
fi
- rm -f conftest.*
- fi
+ ;;
+ esac
fi
test -z "$AR_FLAGS" && AR_FLAGS=cru
@@ -8967,9 +9336,15 @@ fi
test -z "$RANLIB" && RANLIB=:
if test -n "$plugin_option" && test "$RANLIB" != ":"; then
- if $RANLIB --help 2>&1 | grep -q "\--plugin"; then
- RANLIB="$RANLIB $plugin_option"
- fi
+ case "$RANLIB" in
+ *"$plugin_option"*)
+ ;;
+ *)
+ if $RANLIB --help 2>&1 | grep -q "\--plugin"; then
+ RANLIB="$RANLIB $plugin_option"
+ fi
+ ;;
+ esac
fi
@@ -13596,7 +13971,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 13599 "configure"
+#line 13974 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13702,7 +14077,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 13705 "configure"
+#line 14080 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/libctf/ctf-decl.c b/libctf/ctf-decl.c
index 9e11913..e5331b4 100644
--- a/libctf/ctf-decl.c
+++ b/libctf/ctf-decl.c
@@ -154,9 +154,12 @@ ctf_decl_push (ctf_decl_t *cd, ctf_dict_t *fp, ctf_id_t type)
cd->cd_qualp = prec;
/* By convention qualifiers of base types precede the type specifier (e.g.
- const int vs. int const) even though the two forms are equivalent. */
+ const int vs. int const) even though the two forms are equivalent.
+ As of gcc-14.2.0, arrays must also be prepended in order to dump with the
+ dimensions properly ordered. */
- if (is_qual && prec == CTF_PREC_BASE)
+ if ((is_qual && prec == CTF_PREC_BASE) || ((kind == CTF_K_ARRAY) &&
+ (fp->ctf_openflags & (CTF_F_ARRNELEMS))))
ctf_list_prepend (&cd->cd_nodes[prec], cdp);
else
ctf_list_append (&cd->cd_nodes[prec], cdp);
diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c
index 54febd6..57fbd64 100644
--- a/libctf/ctf-dump.c
+++ b/libctf/ctf-dump.c
@@ -326,7 +326,7 @@ ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
if (fp->ctf_openflags > 0)
{
- if (asprintf (&flagstr, "%s%s%s%s%s%s%s",
+ if (asprintf (&flagstr, "%s%s%s%s%s%s%s%s%s",
fp->ctf_openflags & CTF_F_COMPRESS
? "CTF_F_COMPRESS": "",
(fp->ctf_openflags & CTF_F_COMPRESS)
@@ -343,6 +343,12 @@ ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
&& (fp->ctf_openflags & ~(CTF_F_COMPRESS | CTF_F_NEWFUNCINFO
| CTF_F_IDXSORTED))
? ", " : "",
+ fp->ctf_openflags & CTF_F_ARRNELEMS
+ ? "CTF_F_ARRNELEMS" : "",
+ fp->ctf_openflags & (CTF_F_ARRNELEMS)
+ && (fp->ctf_openflags & ~(CTF_F_COMPRESS | CTF_F_NEWFUNCINFO
+ | CTF_F_IDXSORTED | CTF_F_ARRNELEMS))
+ ? ", " : "",
fp->ctf_openflags & CTF_F_DYNSTR
? "CTF_F_DYNSTR" : "") < 0)
goto err;
diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c
index 044a185..d08d454 100644
--- a/libctf/ctf-types.c
+++ b/libctf/ctf-types.c
@@ -45,7 +45,7 @@ ctf_struct_member (ctf_dict_t *fp, ctf_lmember_t *dst, const ctf_type_t *tp,
return -1; /* errno is set for us. */
/* Already large. */
- if (tp->ctt_size == CTF_LSIZE_SENT)
+ if (tp->ctt_size >= CTF_LSTRUCT_THRESH)
{
ctf_lmember_t *lmp = (ctf_lmember_t *) vlen;
diff --git a/libctf/testsuite/lib/ctf-lib.exp b/libctf/testsuite/lib/ctf-lib.exp
index 4df6619..7175e14 100644
--- a/libctf/testsuite/lib/ctf-lib.exp
+++ b/libctf/testsuite/lib/ctf-lib.exp
@@ -141,6 +141,8 @@ proc compile_link_one_host_cc { src output additional_args } {
#
# link:
# If set, link the SOURCE together even if only one file is specified.
+# If "objects", keep the input object files and pass them as additional
+# arguments to LOOKUP.
#
# link_flags:
# If set, extra flags to pass to the linker.
@@ -265,11 +267,14 @@ proc run_lookup_test { name } {
# Compile the inputs and posibly link them together.
set lookup_output ""
+ set objs {}
if { [llength $opts(source)] > 0 } {
set lookup_flags ""
+ set ld_flags ""
if { $run_ld } {
set lookup_output "tmpdir/out.so"
- set lookup_flags "-gctf -fPIC $shared $opts(link_flags)"
+ set lookup_flags "-gctf -fPIC"
+ set ld_flags "$shared $opts(link_flags)"
} else {
set lookup_output "tmpdir/out.o"
set lookup_flags "-gctf -fPIC -c"
@@ -280,19 +285,38 @@ proc run_lookup_test { name } {
if [board_info [target_info name] exists ldflags] {
append lookup_flags " [board_info [target_info name] ldflags]"
}
- set src {}
+ set objsrcs {}
+ set local_srcs {}
foreach sfile $opts(source) {
+ set local_src [file join [file dirname $file] $sfile]
+ lappend local_srcs $local_src
+
if [is_remote host] {
- lappend src [remote_download host [file join [file dirname $file] $sfile]]
+ set src [remote_download host [file join [file dirname $file] $sfile]]
+ } else {
+ set src [file join [file dirname $file] $sfile]
+ }
+
+ if { $opts(link) == "objects" } {
+ set obj "[file rootname $src].o"
+ set comp_output [prune_warnings [run_host_cmd "$CC_FOR_TARGET" "$CFLAGS_FOR_TARGET $lookup_flags $src -c -o $obj"]]
+
+ if { $comp_output != ""} {
+ send_log "compilation of CTF program $local_src failed with <$comp_output>"
+ fail $testname
+ return 0
+ }
+ lappend objsrcs $obj
+ lappend objs $obj
} else {
- lappend src [file join [file dirname $file] $sfile]
+ lappend objsrcs $src
}
}
- set comp_output [prune_warnings [run_host_cmd "$CC_FOR_TARGET" "$CFLAGS_FOR_TARGET $lookup_flags [concat $src] -o $lookup_output"]]
+ set comp_output [prune_warnings [run_host_cmd "$CC_FOR_TARGET" "$CFLAGS_FOR_TARGET $lookup_flags $ld_flags [concat $objsrcs] -o $lookup_output"]]
if { $comp_output != ""} {
- send_log "compilation of CTF program [concat $src] failed with <$comp_output>"
+ send_log "compilation of CTF program [concat $local_srcs] failed with <$comp_output>"
fail $testname
return 0
}
@@ -306,12 +330,13 @@ proc run_lookup_test { name } {
}
}
- # Invoke the lookup program on the outputs, possibly through the wrapper.
+ # Invoke the lookup program on the outputs, possibly through the wrapper, including all
+ # the object file names if they were filled out.
if { [llength $opts(wrapper)] == 0 } {
- set results [run_host_cmd tmpdir/lookup $lookup_output]
+ set results [run_host_cmd tmpdir/lookup "$lookup_output $objs"]
} else {
- set results [run_host_cmd "$opts(wrapper) tmpdir/lookup" $lookup_output]
+ set results [run_host_cmd "$opts(wrapper) tmpdir/lookup" "$lookup_output $objs"]
}
if { [regexp {^UNSUPPORTED: (.*)$} $results -> reason] } {
diff --git a/libctf/testsuite/libctf-lookup/big-struct-corruption.c b/libctf/testsuite/libctf-lookup/big-struct-corruption.c
new file mode 100644
index 0000000..2cc05be
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/big-struct-corruption.c
@@ -0,0 +1,118 @@
+/* Determine whether libctf/33339 is fixed, if and only if GCC PR 121411 is also
+ fixed. */
+
+#include "config.h"
+#include <ctf-api.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Determine whether the passed-in struct's member's offsets ever descend. */
+static int
+offsets_ascending (ctf_dict_t *fp, ctf_id_t type)
+{
+ ctf_next_t *it = NULL;
+ ssize_t offset, last_offset = 0;
+
+ while ((offset = ctf_member_next (fp, type, &it, NULL, NULL, 0)) >= 0)
+ {
+ if (offset < last_offset)
+ return 0;
+ last_offset = offset;
+ }
+ if (ctf_errno (fp) != ECTF_NEXT_END)
+ {
+ fprintf (stderr, "Cannot check member offsets: %s\n",
+ ctf_errmsg (ctf_errno (fp)));
+ exit (0);
+ }
+
+ return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+ ctf_archive_t *ctf;
+ ctf_dict_t *fp;
+ ctf_id_t type;
+ int err;
+
+ if (argc != 3)
+ {
+ fprintf (stderr, "Syntax: %s PROGRAM OBJ\n", argv[0]);
+ exit(1);
+ }
+
+ /* Check for bugginess of compiler. */
+
+ if ((ctf = ctf_open (argv[2], NULL, &err)) == NULL)
+ {
+ fprintf (stderr, "Cannot open compiler object file %s: %s\n",
+ argv[2], ctf_errmsg (err));
+ exit (1);
+ }
+
+ /* Verify that offsets only ascend. */
+
+ if ((fp = ctf_arc_lookup_symbol_name (ctf, "huge_used", &type, &err)) == NULL)
+ {
+ fprintf (stderr, "UNSUPPORTED: compiler does not provide expected symbol.\n");
+ exit (0);
+ }
+
+ if (!offsets_ascending (fp, type))
+ {
+ fprintf (stderr, "UNSUPPORTED: GCC bug PR121411 detected.\n");
+ exit (0);
+ }
+
+ ctf_dict_close (fp);
+ ctf_close (ctf);
+
+ /* Check if test is disabled (e.g. on 32-bit). */
+
+ if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL)
+ {
+ fprintf (stderr, "Cannot open linked binary test file %s: %s\n",
+ argv[1], ctf_errmsg (err));
+ exit (1);
+ }
+
+ if ((fp = ctf_arc_lookup_symbol_name (ctf, "test_disabled", &type, &err)) != NULL)
+ {
+ fprintf (stderr, "UNSUPPORTED: test not necessary on 32-bit targets.\n");
+ exit (0);
+ }
+
+ if ((fp = ctf_arc_lookup_symbol_name (ctf, "big_used", &type, &err)) == NULL)
+ {
+ fprintf (stderr, "big struct symbol not found.\n");
+ exit (1);
+ }
+
+ if (!offsets_ascending (fp, type))
+ {
+ fprintf (stderr, "large struct offsets incorrect.\n");
+ exit (1);
+ }
+ ctf_dict_close (fp);
+
+ if ((fp = ctf_arc_lookup_symbol_name (ctf, "huge_used", &type, &err)) == NULL)
+ {
+ fprintf (stderr, "huge struct symbol not found.\n");
+ exit (1);
+ }
+
+ if (!offsets_ascending (fp, type))
+ {
+ fprintf (stderr, "huge struct offsets incorrect.\n");
+ exit (1);
+ }
+
+ ctf_dict_close (fp);
+ ctf_close (ctf);
+
+ fprintf (stderr, "Large and huge structs working fine.\n");
+ exit (0);
+}
diff --git a/libctf/testsuite/libctf-lookup/big-struct-corruption.lk b/libctf/testsuite/libctf-lookup/big-struct-corruption.lk
new file mode 100644
index 0000000..980cb0b
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/big-struct-corruption.lk
@@ -0,0 +1,3 @@
+# source: big-struct-ctf.c
+# link: objects
+Large and huge structs working fine.
diff --git a/libctf/testsuite/libctf-lookup/big-struct-ctf.c b/libctf/testsuite/libctf-lookup/big-struct-ctf.c
new file mode 100644
index 0000000..fc99a3e
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/big-struct-ctf.c
@@ -0,0 +1,72 @@
+#if defined (__SIZEOF_PTRDIFF_T__) && __SIZEOF_PTRDIFF_T__ > 4
+
+#define CONCAT_(a,b) a ## b
+#define CONCAT(a,b) CONCAT_(a, b)
+#define COUNT(name) CONCAT(name, __COUNTER__)
+#define MEMBNAME const char COUNT(memb)[1024 * 1024]
+#define MEMB10 \
+ MEMBNAME; \
+ MEMBNAME; \
+ MEMBNAME; \
+ MEMBNAME; \
+ MEMBNAME; \
+ MEMBNAME; \
+ MEMBNAME; \
+ MEMBNAME; \
+ MEMBNAME; \
+ MEMBNAME;
+
+#define MEMB100 \
+ MEMB10 \
+ MEMB10 \
+ MEMB10 \
+ MEMB10 \
+ MEMB10 \
+ MEMB10 \
+ MEMB10 \
+ MEMB10 \
+ MEMB10 \
+ MEMB10
+
+#define MEMB1000 \
+ MEMB100 \
+ MEMB100 \
+ MEMB100 \
+ MEMB100 \
+ MEMB100 \
+ MEMB100 \
+ MEMB100 \
+ MEMB100 \
+ MEMB100 \
+ MEMB100
+
+#define MEMB10000 \
+ MEMB1000 \
+ MEMB1000 \
+ MEMB1000 \
+ MEMB1000 \
+ MEMB1000 \
+ MEMB1000 \
+ MEMB1000 \
+ MEMB1000 \
+ MEMB1000 \
+ MEMB1000
+
+struct big
+{
+ MEMB1000;
+};
+
+struct huge
+{
+ MEMB10000;
+};
+
+struct big big_used;
+struct huge huge_used;
+
+#else
+
+int test_disabled;
+
+#endif
diff --git a/libctf/testsuite/libctf-lookup/multidim-array-ctf.c b/libctf/testsuite/libctf-lookup/multidim-array-ctf.c
new file mode 100644
index 0000000..05b6ebe
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/multidim-array-ctf.c
@@ -0,0 +1,3 @@
+int a[3][5][9];
+int b[1][2];
+
diff --git a/libctf/testsuite/libctf-lookup/multidim-array.c b/libctf/testsuite/libctf-lookup/multidim-array.c
new file mode 100644
index 0000000..2a86f26
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/multidim-array.c
@@ -0,0 +1,71 @@
+#include <ctf-api.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+ ctf_archive_t *ctf;
+ ctf_dict_t *fp;
+ int err;
+ ctf_dump_state_t *dump_state = NULL;
+ char *dumpstr;
+ ctf_next_t *it = NULL;
+ ctf_id_t type;
+ int flagged = 0;
+
+ if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL)
+ goto open_err;
+ if ((fp = ctf_dict_open (ctf, NULL, &err)) == NULL)
+ goto open_err;
+
+ /* First, check for signs that the compiler is fixed but not emitting the
+ relevant flag yet. This combination is not expected to work right. */
+
+ while ((dumpstr = ctf_dump (fp, &dump_state, CTF_SECT_HEADER,
+ NULL, NULL)) != NULL)
+ {
+ if (strstr (dumpstr, "CTF_F_ARRNELEMS") != NULL)
+ flagged = 1;
+ free (dumpstr);
+ }
+
+ if (!flagged)
+ {
+ ctf_arinfo_t ar;
+
+ if ((type = ctf_lookup_by_symbol_name (fp, "a")) == CTF_ERR)
+ goto unexpected;
+
+ if (ctf_array_info (fp, type, &ar) < 0)
+ goto unexpected;
+
+ if (ar.ctr_nelems == 3)
+ {
+ fprintf (stderr, "UNSUPPORTED: compiler has GCC PR114186 fixed but "
+ "no indicative flag\n");
+ return 0;
+ }
+ }
+
+ /* Now check for the actual bug. */
+
+ while ((type = ctf_type_next (fp, &it, NULL, 1)) != -1)
+ printf ("%s\n", ctf_type_aname (fp, type));
+
+ ctf_dict_close (fp);
+ ctf_close (ctf);
+
+ return 0;
+
+ open_err:
+ fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err));
+ return 1;
+
+ unexpected:
+ fprintf (stderr, "Cannot look up symbol to determine compiler bugginess: %s\n",
+ ctf_errmsg (ctf_errno (fp)));
+ return 1;
+}
+
diff --git a/libctf/testsuite/libctf-lookup/multidim-array.lk b/libctf/testsuite/libctf-lookup/multidim-array.lk
new file mode 100644
index 0000000..41b3cd9
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/multidim-array.lk
@@ -0,0 +1,9 @@
+# source: multidim-array-ctf.c
+int
+(long )?unsigned int
+int \[9\]
+int \[5\]\[9\]
+int \[3\]\[5\]\[9\]
+int \[2\]
+int \[1\]\[2\]
+