#
# 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.
# 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"
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
}
}
}
- # 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] } {
--- /dev/null
+/* 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);
+}