OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [ld/] [testsuite/] [lib/] [ld-lib.exp] - Blame information for rev 854

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
# Support routines for LD testsuite.
2
#   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3
#    2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4
#
5
# This file is part of the GNU Binutils.
6
#
7
# This file is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
# MA 02110-1301, USA.
21
 
22
# Extract and print the version number of ld.
23
#
24
proc default_ld_version { ld } {
25
    global host_triplet
26
 
27
    if { ![is_remote host] && [which $ld] == 0 } then {
28
        perror "$ld does not exist"
29
        exit 1
30
    }
31
 
32
    remote_exec host "$ld --version" "" "/dev/null" "ld.version"
33
    remote_upload host "ld.version"
34
    set tmp [prune_warnings [file_contents "ld.version"]]
35
    remote_file build delete "ld.version"
36
    remote_file host delete "ld.version"
37
 
38
    regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" $tmp version cyg number
39
    if [info exists number] then {
40
        clone_output "$ld $number\n"
41
    }
42
}
43
 
44
proc run_host_cmd { prog command } {
45
    global link_output
46
 
47
    if { ![is_remote host] && [which "$prog"] == 0 } then {
48
        perror "$prog does not exist"
49
        return 0
50
    }
51
 
52
    verbose -log "$prog $command"
53
    set status [remote_exec host [concat sh -c [list "$prog $command 2>&1"]] "" "/dev/null" "ld.tmp"]
54
    remote_upload host "ld.tmp"
55
    set link_output [file_contents "ld.tmp"]
56
    regsub "\n$" $link_output "" link_output
57
    if { [lindex $status 0] != 0 && [string match "" $link_output] } then {
58
        append link_output "child process exited abnormally"
59
    }
60
    remote_file build delete ld.tmp
61
    remote_file host delete ld.tmp
62
 
63
    if [string match "" $link_output] then {
64
        return ""
65
    }
66
 
67
    verbose -log "$link_output"
68
    return "$link_output"
69
}
70
 
71
proc run_host_cmd_yesno { prog command } {
72
    global exec_output
73
 
74
    set exec_output [prune_warnings [run_host_cmd "$prog" "$command"]]
75
    if [string match "" $exec_output] then {
76
        return 1;
77
    }
78
    return 0;
79
}
80
 
81
# Link an object using relocation.
82
#
83
proc default_ld_relocate { ld target objects } {
84
    global HOSTING_EMU
85
 
86
    remote_file host delete $target
87
    return [run_host_cmd_yesno "$ld" "$HOSTING_EMU -o $target -r $objects"]
88
}
89
 
90
# Check to see if ld is being invoked with a non-endian output format
91
#
92
proc is_endian_output_format { object_flags } {
93
 
94
    if {[string match "*-oformat binary*" $object_flags] ||      \
95
        [string match "*-oformat ieee*" $object_flags] ||        \
96
        [string match "*-oformat ihex*" $object_flags] ||        \
97
        [string match "*-oformat netbsd-core*" $object_flags] || \
98
        [string match "*-oformat srec*" $object_flags] ||        \
99
        [string match "*-oformat tekhex*" $object_flags] ||      \
100
        [string match "*-oformat trad-core*" $object_flags] } then {
101
        return 0
102
    } else {
103
        return 1
104
    }
105
}
106
 
107
# Look for big-endian or little-endian switches in the multlib
108
# options and translate these into a -EB or -EL switch.  Note
109
# we cannot rely upon proc process_multilib_options to do this
110
# for us because for some targets the compiler does not support
111
# -EB/-EL but it does support -mbig-endian/-mlittle-endian, and
112
# the site.exp file will include the switch "-mbig-endian"
113
# (rather than "big-endian") which is not detected by proc
114
# process_multilib_options.
115
#
116
proc big_or_little_endian {} {
117
 
118
    if [board_info [target_info name] exists multilib_flags] {
119
        set tmp_flags " [board_info [target_info name] multilib_flags]"
120
 
121
        foreach x $tmp_flags {
122
            case $x in {
123
                {*big*endian eb EB -eb -EB -mb -meb} {
124
                    set flags " -EB"
125
                    return $flags
126
                }
127
                {*little*endian el EL -el -EL -ml -mel} {
128
                    set flags " -EL"
129
                    return $flags
130
                }
131
            }
132
        }
133
    }
134
 
135
    set flags ""
136
    return $flags
137
}
138
 
139
# Link a program using ld.
140
#
141
proc default_ld_link { ld target objects } {
142
    global HOSTING_EMU
143
    global HOSTING_CRT0
144
    global HOSTING_LIBS
145
    global LIBS
146
    global host_triplet
147
    global link_output
148
    global exec_output
149
 
150
    set objs "$HOSTING_CRT0 $objects"
151
    set libs "$LIBS $HOSTING_LIBS"
152
 
153
    if [is_endian_output_format $objects] then {
154
        set flags [big_or_little_endian]
155
    } else {
156
        set flags ""
157
    }
158
 
159
    remote_file host delete $target
160
 
161
    return [run_host_cmd_yesno "$ld" "$HOSTING_EMU $flags -o $target $objs $libs"]
162
}
163
 
164
# Link a program using ld, without including any libraries.
165
#
166
proc default_ld_simple_link { ld target objects } {
167
    global host_triplet
168
    global gcc_ld_flag
169
    global exec_output
170
 
171
    if [is_endian_output_format $objects] then {
172
        set flags [big_or_little_endian]
173
    } else {
174
        set flags ""
175
    }
176
 
177
    # If we are compiling with gcc, we want to add gcc_ld_flag to
178
    # flags.  Rather than determine this in some complex way, we guess
179
    # based on the name of the compiler.
180
    set ldexe $ld
181
    set ldparm [string first " " $ld]
182
    if { $ldparm > 0 } then {
183
        set ldexe [string range $ld 0 $ldparm]
184
    }
185
    set ldexe [string replace $ldexe 0 [string last "/" $ldexe] ""]
186
    if {[string match "*gcc*" $ldexe] || [string match "*++*" $ldexe]} then {
187
        set flags "$gcc_ld_flag $flags"
188
    }
189
 
190
    remote_file host delete $target
191
 
192
    set exec_output [run_host_cmd "$ld" "$flags -o $target $objects"]
193
    set exec_output [prune_warnings $exec_output]
194
 
195
    # We don't care if we get a warning about a non-existent start
196
    # symbol, since the default linker script might use ENTRY.
197
    regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
198
 
199
    if [string match "" $exec_output] then {
200
        return 1
201
    } else {
202
        return 0
203
    }
204
}
205
 
206
# Compile an object using cc.
207
#
208
proc default_ld_compile { cc source object } {
209
    global CFLAGS
210
    global CXXFLAGS
211
    global srcdir
212
    global subdir
213
    global host_triplet
214
    global gcc_gas_flag
215
 
216
    set cc_prog $cc
217
    if {[llength $cc_prog] > 1} then {
218
        set cc_prog [lindex $cc_prog 0]
219
    }
220
    if {![is_remote host] && [which $cc_prog] == 0} then {
221
        perror "$cc_prog does not exist"
222
        return 0
223
    }
224
 
225
    remote_file build delete "$object"
226
    remote_file host delete "$object"
227
 
228
    set flags "-I$srcdir/$subdir"
229
 
230
    # If we are compiling with gcc, we want to add gcc_gas_flag to
231
    # flags.  Rather than determine this in some complex way, we guess
232
    # based on the name of the compiler.
233
    set ccexe $cc
234
    set ccparm [string first " " $cc]
235
    set ccflags ""
236
    if { $ccparm > 0 } then {
237
        set ccflags [string range $cc $ccparm end]
238
        set ccexe [string range $cc 0 $ccparm]
239
        set cc $ccexe
240
    }
241
    set ccexe [string replace $ccexe 0 [string last "/" $ccexe] ""]
242
    if {[string match "*gcc*" $ccexe] || [string match "*++*" $ccexe]} then {
243
        set flags "$gcc_gas_flag $flags"
244
    }
245
 
246
    if {[string match "*++*" $ccexe]} {
247
        set flags "$flags $CXXFLAGS"
248
    } else {
249
        set flags "$flags $CFLAGS"
250
    }
251
 
252
    if [board_info [target_info name] exists multilib_flags] {
253
        append flags " [board_info [target_info name] multilib_flags]"
254
    }
255
 
256
    verbose -log "$cc $flags $ccflags -c $source -o $object"
257
 
258
    set status [remote_exec host [concat sh -c [list "$cc $flags $ccflags -c $source -o $object 2>&1"]] "" "/dev/null" "ld.tmp"]
259
    remote_upload host "ld.tmp"
260
    set exec_output [file_contents "ld.tmp"]
261
    remote_file build delete "ld.tmp"
262
    remote_file host delete "ld.tmp"
263
    set exec_output [prune_warnings $exec_output]
264
    if [string match "" $exec_output] then {
265
        if {![file exists $object]} then {
266
            regexp ".*/(\[^/\]*)$" $source all dobj
267
            regsub "\\.c" $dobj ".o" realobj
268
            verbose "looking for $realobj"
269
            if {[remote_file host exists $realobj]} then {
270
                verbose -log "mv $realobj $object"
271
                remote_upload "$realobj" "$object"
272
            } else {
273
                perror "$object not found after compilation"
274
                return 0
275
            }
276
        }
277
        return 1
278
    } else {
279
        verbose -log "$exec_output"
280
        perror "$source: compilation failed"
281
        return 0
282
    }
283
}
284
 
285
# Assemble a file.
286
#
287
proc default_ld_assemble { as source object } {
288
    global ASFLAGS
289
    global host_triplet
290
 
291
    if ![info exists ASFLAGS] { set ASFLAGS "" }
292
 
293
    set flags [big_or_little_endian]
294
    set exec_output [run_host_cmd "$as" "$flags $ASFLAGS -o $object $source"]
295
    set exec_output [prune_warnings $exec_output]
296
    if [string match "" $exec_output] then {
297
        return 1
298
    } else {
299
        perror "$source: assembly failed"
300
        return 0
301
    }
302
}
303
 
304
# Run nm on a file, putting the result in the array nm_output.
305
#
306
proc default_ld_nm { nm nmflags object } {
307
    global NMFLAGS
308
    global nm_output
309
    global host_triplet
310
 
311
    if {[info exists nm_output]} {
312
      unset nm_output
313
    }
314
 
315
    if ![info exists NMFLAGS] { set NMFLAGS "" }
316
 
317
    # Ensure consistent sorting of symbols
318
    if {[info exists env(LC_ALL)]} {
319
        set old_lc_all $env(LC_ALL)
320
    }
321
    set env(LC_ALL) "C"
322
 
323
    verbose -log "$nm $NMFLAGS $nmflags $object >tmpdir/nm.out"
324
 
325
    set status [remote_exec host [concat sh -c [list "$nm $NMFLAGS $nmflags $object 2>ld.stderr"]] "" "/dev/null" "tmpdir/nm.out"]
326
    if {[info exists old_lc_all]} {
327
        set env(LC_ALL) $old_lc_all
328
    } else {
329
        unset env(LC_ALL)
330
    }
331
    remote_upload host "ld.stderr"
332
    remote_upload host "tmpdir/nm.out" "tmpdir/nm.out"
333
    set exec_output [prune_warnings [file_contents "ld.stderr"]]
334
    remote_file host delete "ld.stderr"
335
    remote_file build delete "ld.stderr"
336
    if [string match "" $exec_output] then {
337
        set file [open tmpdir/nm.out r]
338
        while { [gets $file line] != -1 } {
339
            verbose "$line" 2
340
            if [regexp "^(\[0-9a-fA-F\]+) \[a-zA-Z0-9\] \\.*(.+)$" $line whole value name] {
341
                set name [string trimleft $name "_"]
342
                verbose "Setting nm_output($name) to 0x$value" 2
343
                set nm_output($name) 0x$value
344
            }
345
        }
346
        close $file
347
        return 1
348
    } else {
349
        verbose -log "$exec_output"
350
        perror "$object: nm failed"
351
        return 0
352
    }
353
}
354
 
355
# True if the object format is known to be ELF.
356
#
357
proc is_elf_format {} {
358
    if { ![istarget *-*-sysv4*] \
359
         && ![istarget *-*-unixware*] \
360
         && ![istarget *-*-elf*] \
361
         && ![istarget *-*-eabi*] \
362
         && ![istarget hppa*64*-*-hpux*] \
363
         && ![istarget *-*-linux*] \
364
         && ![istarget frv-*-uclinux*] \
365
         && ![istarget *-*-irix5*] \
366
         && ![istarget *-*-irix6*] \
367
         && ![istarget *-*-netbsd*] \
368
         && ![istarget *-*-solaris2*] } {
369
        return 0
370
    }
371
 
372
    if { [istarget *-*-linux*aout*] \
373
         || [istarget *-*-linux*oldld*] } {
374
        return 0
375
    }
376
 
377
    if { ![istarget *-*-netbsdelf*] \
378
         && ([istarget *-*-netbsd*aout*] \
379
             || [istarget *-*-netbsdpe*] \
380
             || [istarget arm*-*-netbsd*] \
381
             || [istarget sparc-*-netbsd*] \
382
             || [istarget i*86-*-netbsd*] \
383
             || [istarget m68*-*-netbsd*] \
384
             || [istarget vax-*-netbsd*] \
385
             || [istarget ns32k-*-netbsd*]) } {
386
        return 0
387
    }
388
    return 1
389
}
390
 
391
# True if the object format is known to be 64-bit ELF.
392
#
393
proc is_elf64 { binary_file } {
394
    global READELF
395
    global READELFFLAGS
396
 
397
    set readelf_size ""
398
    catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
399
 
400
    if ![string match "" $got] then {
401
        return 0
402
    }
403
 
404
    if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
405
           [file_contents readelf.out] nil readelf_size] } {
406
        return 0
407
    }
408
 
409
    if { $readelf_size == "64" } {
410
        return 1
411
    }
412
 
413
    return 0
414
}
415
 
416
# True if the object format is known to be a.out.
417
#
418
proc is_aout_format {} {
419
    if { [istarget *-*-*\[ab\]out*] \
420
             || [istarget *-*-linux*oldld*] \
421
             || [istarget *-*-msdos*] \
422
             || [istarget arm-*-netbsd] \
423
             || [istarget i?86-*-netbsd] \
424
             || [istarget i?86-*-mach*] \
425
             || [istarget i?86-*-vsta] \
426
             || [istarget pdp11-*-*] \
427
             || [istarget m68*-ericsson-ose] \
428
             || [istarget m68k-hp-bsd*] \
429
             || [istarget m68*-*-hpux*] \
430
             || [istarget m68*-*-netbsd] \
431
             || [istarget m68*-*-netbsd*4k*] \
432
             || [istarget m68k-sony-*] \
433
             || [istarget m68*-sun-sunos\[34\]*] \
434
             || [istarget m68*-wrs-vxworks*] \
435
             || [istarget ns32k-*-*] \
436
             || [istarget sparc*-*-netbsd] \
437
             || [istarget sparc-sun-sunos4*] \
438
             || [istarget vax-dec-ultrix*] \
439
             || [istarget vax-*-netbsd] } {
440
        return 1
441
    }
442
    return 0
443
}
444
 
445
# True if the object format is known to be PE COFF.
446
#
447
proc is_pecoff_format {} {
448
    if { ![istarget *-*-mingw*] \
449
         && ![istarget *-*-cygwin*] \
450
         && ![istarget *-*-pe*] } {
451
        return 0
452
    }
453
 
454
    return 1
455
}
456
 
457
# Compares two files line-by-line.
458
#   Returns differences if exist.
459
#   Returns null if file(s) cannot be opened.
460
#
461
proc simple_diff { file_1 file_2 } {
462
    global target
463
 
464
    set eof -1
465
    set differences 0
466
 
467
    if [file exists $file_1] then {
468
        set file_a [open $file_1 r]
469
    } else {
470
        warning "$file_1 doesn't exist"
471
        return
472
    }
473
 
474
    if [file exists $file_2] then {
475
        set file_b [open $file_2 r]
476
    } else {
477
        fail "$file_2 doesn't exist"
478
        return
479
    }
480
 
481
    verbose "# Diff'ing: $file_1 $file_2\n" 2
482
 
483
    while { [gets $file_a line] != $eof } {
484
        if [regexp "^#.*$" $line] then {
485
            continue
486
        } else {
487
            lappend list_a $line
488
        }
489
    }
490
    close $file_a
491
 
492
    while { [gets $file_b line] != $eof } {
493
        if [regexp "^#.*$" $line] then {
494
            continue
495
        } else {
496
            lappend list_b $line
497
        }
498
    }
499
    close $file_b
500
 
501
    for { set i 0 } { $i < [llength $list_a] } { incr i } {
502
        set line_a [lindex $list_a $i]
503
        set line_b [lindex $list_b $i]
504
 
505
        verbose "\t$file_1: $i: $line_a\n" 3
506
        verbose "\t$file_2: $i: $line_b\n" 3
507
        if [string compare $line_a $line_b] then {
508
            verbose -log "\t$file_1: $i: $line_a\n"
509
            verbose -log "\t$file_2: $i: $line_b\n"
510
 
511
            fail "Test: $target"
512
            return
513
        }
514
    }
515
 
516
    if { [llength $list_a] != [llength $list_b] } {
517
        fail "Test: $target"
518
        return
519
    }
520
 
521
    if $differences<1 then {
522
        pass "Test: $target"
523
    }
524
}
525
 
526
# run_dump_test FILE
527
# Copied from gas testsuite, tweaked and further extended.
528
#
529
# Assemble a .s file, then run some utility on it and check the output.
530
#
531
# There should be an assembly language file named FILE.s in the test
532
# suite directory, and a pattern file called FILE.d.  `run_dump_test'
533
# will assemble FILE.s, run some tool like `objdump', `objcopy', or
534
# `nm' on the .o file to produce textual output, and then analyze that
535
# with regexps.  The FILE.d file specifies what program to run, and
536
# what to expect in its output.
537
#
538
# The FILE.d file begins with zero or more option lines, which specify
539
# flags to pass to the assembler, the program to run to dump the
540
# assembler's output, and the options it wants.  The option lines have
541
# the syntax:
542
#
543
#         # OPTION: VALUE
544
#
545
# OPTION is the name of some option, like "name" or "objdump", and
546
# VALUE is OPTION's value.  The valid options are described below.
547
# Whitespace is ignored everywhere, except within VALUE.  The option
548
# list ends with the first line that doesn't match the above syntax
549
# (hmm, not great for error detection).
550
#
551
# The interesting options are:
552
#
553
#   name: TEST-NAME
554
#       The name of this test, passed to DejaGNU's `pass' and `fail'
555
#       commands.  If omitted, this defaults to FILE, the root of the
556
#       .s and .d files' names.
557
#
558
#   as: FLAGS
559
#       When assembling, pass FLAGS to the assembler.
560
#       If assembling several files, you can pass different assembler
561
#       options in the "source" directives.  See below.
562
#
563
#   ld: FLAGS
564
#       Link assembled files using FLAGS, in the order of the "source"
565
#       directives, when using multiple files.
566
#
567
#   objcopy_linked_file: FLAGS
568
#       Run objcopy on the linked file with the specified flags.
569
#       This lets you transform the linked file using objcopy, before the
570
#       result is analyzed by an analyzer program specified below (which
571
#       may in turn *also* be objcopy).
572
#
573
#   PROG: PROGRAM-NAME
574
#       The name of the program to run to analyze the .o file produced
575
#       by the assembler or the linker output.  This can be omitted;
576
#       run_dump_test will guess which program to run by seeing which of
577
#       the flags options below is present.
578
#
579
#   objdump: FLAGS
580
#   nm: FLAGS
581
#   objcopy: FLAGS
582
#       Use the specified program to analyze the assembler or linker
583
#       output file, and pass it FLAGS, in addition to the output name.
584
#       Note that they are run with LC_ALL=C in the environment to give
585
#       consistent sorting of symbols.
586
#
587
#   source: SOURCE [FLAGS]
588
#       Assemble the file SOURCE.s using the flags in the "as" directive
589
#       and the (optional) FLAGS.  If omitted, the source defaults to
590
#       FILE.s.
591
#       This is useful if several .d files want to share a .s file.
592
#       More than one "source" directive can be given, which is useful
593
#       when testing linking.
594
#
595
#   xfail: TARGET
596
#       The test is expected to fail on TARGET.  This may occur more than
597
#       once.
598
#
599
#   target: TARGET
600
#       Only run the test for TARGET.  This may occur more than once; the
601
#       target being tested must match at least one.
602
#
603
#   notarget: TARGET
604
#       Do not run the test for TARGET.  This may occur more than once;
605
#       the target being tested must not match any of them.
606
#
607
#   error: REGEX
608
#       An error with message matching REGEX must be emitted for the test
609
#       to pass.  The PROG, objdump, nm and objcopy options have no
610
#       meaning and need not supplied if this is present.
611
#
612
#   warning: REGEX
613
#       Expect a linker warning matching REGEX.  It is an error to issue
614
#       both "error" and "warning".
615
#
616
# Each option may occur at most once unless otherwise mentioned.
617
#
618
# After the option lines come regexp lines.  `run_dump_test' calls
619
# `regexp_diff' to compare the output of the dumping tool against the
620
# regexps in FILE.d.  `regexp_diff' is defined later in this file; see
621
# further comments there.
622
#
623
proc run_dump_test { name } {
624
    global subdir srcdir
625
    global OBJDUMP NM AS OBJCOPY READELF LD
626
    global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
627
    global host_triplet runtests
628
    global env
629
 
630
    if [string match "*/*" $name] {
631
        set file $name
632
        set name [file tail $name]
633
    } else {
634
        set file "$srcdir/$subdir/$name"
635
    }
636
 
637
    if ![runtest_file_p $runtests $name] then {
638
        return
639
    }
640
 
641
    set opt_array [slurp_options "${file}.d"]
642
    if { $opt_array == -1 } {
643
        perror "error reading options from $file.d"
644
        unresolved $subdir/$name
645
        return
646
    }
647
    set dumpfile tmpdir/dump.out
648
    set run_ld 0
649
    set run_objcopy 0
650
    set opts(as) {}
651
    set opts(ld) {}
652
    set opts(xfail) {}
653
    set opts(target) {}
654
    set opts(notarget) {}
655
    set opts(objdump) {}
656
    set opts(nm) {}
657
    set opts(objcopy) {}
658
    set opts(readelf) {}
659
    set opts(name) {}
660
    set opts(PROG) {}
661
    set opts(source) {}
662
    set opts(error) {}
663
    set opts(warning) {}
664
    set opts(objcopy_linked_file) {}
665
    set asflags(${file}.s) {}
666
 
667
    foreach i $opt_array {
668
        set opt_name [lindex $i 0]
669
        set opt_val [lindex $i 1]
670
        if ![info exists opts($opt_name)] {
671
            perror "unknown option $opt_name in file $file.d"
672
            unresolved $subdir/$name
673
            return
674
        }
675
 
676
        switch -- $opt_name {
677
            xfail {}
678
            target {}
679
            notarget {}
680
            source {
681
                # Move any source-specific as-flags to a separate array to
682
                # simplify processing.
683
                if { [llength $opt_val] > 1 } {
684
                    set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
685
                    set opt_val [lindex $opt_val 0]
686
                } else {
687
                    set asflags($opt_val) {}
688
                }
689
            }
690
            default {
691
                if [string length $opts($opt_name)] {
692
                    perror "option $opt_name multiply set in $file.d"
693
                    unresolved $subdir/$name
694
                    return
695
                }
696
 
697
                # A single "# ld:" with no options should do the right thing.
698
                if { $opt_name == "ld" } {
699
                    set run_ld 1
700
                }
701
                # Likewise objcopy_linked_file.
702
                if { $opt_name == "objcopy_linked_file" } {
703
                    set run_objcopy 1
704
                }
705
            }
706
        }
707
        if { $opt_name == "as" || $opt_name == "ld" } {
708
            set opt_val [subst $opt_val]
709
        }
710
        set opts($opt_name) [concat $opts($opt_name) $opt_val]
711
    }
712
    foreach opt { as ld } {
713
        regsub {\[big_or_little_endian\]} $opts($opt) \
714
            [big_or_little_endian] opts($opt)
715
    }
716
 
717
    # Decide early whether we should run the test for this target.
718
    if { [llength $opts(target)] > 0 } {
719
        set targmatch 0
720
        foreach targ $opts(target) {
721
            if [istarget $targ] {
722
                set targmatch 1
723
                break
724
            }
725
        }
726
        if { $targmatch == 0 } {
727
            return
728
        }
729
    }
730
    foreach targ $opts(notarget) {
731
        if [istarget $targ] {
732
            return
733
        }
734
    }
735
 
736
    set program ""
737
    # It's meaningless to require an output-testing method when we
738
    # expect an error.
739
    if { $opts(error) == "" } {
740
        if {$opts(PROG) != ""} {
741
            switch -- $opts(PROG) {
742
                objdump { set program objdump }
743
                nm      { set program nm }
744
                objcopy { set program objcopy }
745
                readelf { set program readelf }
746
                default
747
                { perror "unrecognized program option $opts(PROG) in $file.d"
748
                  unresolved $subdir/$name
749
                  return }
750
            }
751
        } else {
752
        # Guess which program to run, by seeing which option was specified.
753
            foreach p {objdump objcopy nm readelf} {
754
                if {$opts($p) != ""} {
755
                    if {$program != ""} {
756
                        perror "ambiguous dump program in $file.d"
757
                        unresolved $subdir/$name
758
                        return
759
                    } else {
760
                        set program $p
761
                    }
762
                }
763
            }
764
        }
765
        if { $program == "" && $opts(warning) == "" } {
766
            perror "dump program unspecified in $file.d"
767
            unresolved $subdir/$name
768
            return
769
        }
770
    }
771
 
772
    if { $opts(name) == "" } {
773
        set testname "$subdir/$name"
774
    } else {
775
        set testname $opts(name)
776
    }
777
 
778
    if { $opts(source) == "" } {
779
        set sourcefiles [list ${file}.s]
780
    } else {
781
        set sourcefiles {}
782
        foreach sf $opts(source) {
783
            if { [string match "/*" $sf] } {
784
                lappend sourcefiles "$sf"
785
            } else {
786
                lappend sourcefiles "$srcdir/$subdir/$sf"
787
            }
788
            # Must have asflags indexed on source name.
789
            set asflags($srcdir/$subdir/$sf) $asflags($sf)
790
        }
791
    }
792
 
793
    # Time to setup xfailures.
794
    foreach targ $opts(xfail) {
795
        setup_xfail $targ
796
    }
797
 
798
    # Assemble each file.
799
    set objfiles {}
800
    for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
801
        set sourcefile [lindex $sourcefiles $i]
802
 
803
        set objfile "tmpdir/dump$i.o"
804
        catch "exec rm -f $objfile" exec_output
805
        lappend objfiles $objfile
806
        set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
807
 
808
        send_log "$cmd\n"
809
        set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
810
        remote_upload host "ld.tmp"
811
        set comp_output [prune_warnings [file_contents "ld.tmp"]]
812
        remote_file host delete "ld.tmp"
813
        remote_file build delete "ld.tmp"
814
 
815
        if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
816
            send_log "$comp_output\n"
817
            verbose "$comp_output" 3
818
 
819
            set exitstat "succeeded"
820
            if { $cmdret != 0 } { set exitstat "failed" }
821
            verbose -log "$exitstat with: <$comp_output>"
822
            fail $testname
823
            return
824
        }
825
    }
826
 
827
    set expmsg $opts(error)
828
    if { $opts(warning) != "" } {
829
        if { $expmsg != "" } {
830
            perror "$testname: mixing error and warning test-directives"
831
            return
832
        }
833
        set expmsg $opts(warning)
834
    }
835
 
836
    # Perhaps link the file(s).
837
    if { $run_ld } {
838
        set objfile "tmpdir/dump"
839
        catch "exec rm -f $objfile" exec_output
840
 
841
        # Add -L$srcdir/$subdir so that the linker command can use
842
        # linker scripts in the source directory.
843
        set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
844
                   $opts(ld) -o $objfile $objfiles"
845
 
846
        send_log "$cmd\n"
847
        set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
848
        remote_upload host "ld.tmp"
849
        set comp_output [file_contents "ld.tmp"]
850
        remote_file host delete "ld.tmp"
851
        remote_file build delete "ld.tmp"
852
        set cmdret [lindex $cmdret 0]
853
 
854
        if { $cmdret == 0 && $run_objcopy } {
855
            set infile $objfile
856
            set objfile "tmpdir/dump1"
857
            remote_file host delete $objfile
858
 
859
            # Note that we don't use OBJCOPYFLAGS here; any flags must be
860
            # explicitly specified.
861
            set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
862
 
863
            send_log "$cmd\n"
864
            set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
865
            remote_upload host "ld.tmp"
866
            append comp_output [file_contents "ld.tmp"]
867
            remote_file host delete "ld.tmp"
868
            remote_file build delete "ld.tmp"
869
            set cmdret [lindex $cmdret 0]
870
        }
871
 
872
        regsub "\n$" $comp_output "" comp_output
873
        if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
874
            set exitstat "succeeded"
875
            if { $cmdret != 0 } { set exitstat "failed" }
876
            verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
877
            send_log "$comp_output\n"
878
            verbose "$comp_output" 3
879
 
880
            if { [regexp $expmsg $comp_output] \
881
                    && (($cmdret == 0) == ($opts(warning) != "")) } {
882
                # We have the expected output from ld.
883
                if { $opts(error) != "" || $program == "" } {
884
                    pass $testname
885
                    return
886
                }
887
            } else {
888
                verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
889
                fail $testname
890
                return
891
            }
892
        }
893
    } else {
894
        set objfile "tmpdir/dump0.o"
895
    }
896
 
897
    # We must not have expected failure if we get here.
898
    if { $opts(error) != "" } {
899
        fail $testname
900
        return
901
    }
902
 
903
    set progopts1 $opts($program)
904
    eval set progopts \$[string toupper $program]FLAGS
905
    eval set binary \$[string toupper $program]
906
 
907
    if { ![is_remote host] && [which $binary] == 0 } {
908
        untested $testname
909
        return
910
    }
911
 
912
    if { $progopts1 == "" } { set $progopts1 "-r" }
913
    verbose "running $binary $progopts $progopts1" 3
914
 
915
    # Objcopy, unlike the other two, won't send its output to stdout,
916
    # so we have to run it specially.
917
    set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
918
    if { $program == "objcopy" } {
919
        set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
920
    }
921
 
922
    # Ensure consistent sorting of symbols
923
    if {[info exists env(LC_ALL)]} {
924
        set old_lc_all $env(LC_ALL)
925
    }
926
    set env(LC_ALL) "C"
927
    send_log "$cmd\n"
928
    set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
929
    remote_upload host "ld.tmp"
930
    set comp_output [prune_warnings [file_contents "ld.tmp"]]
931
    remote_file host delete "ld.tmp"
932
    remote_file build delete "ld.tmp"
933
    if {[info exists old_lc_all]} {
934
        set env(LC_ALL) $old_lc_all
935
    } else {
936
        unset env(LC_ALL)
937
    }
938
    if ![string match "" $comp_output] then {
939
        send_log "$comp_output\n"
940
        fail $testname
941
        return
942
    }
943
 
944
    verbose_eval {[file_contents $dumpfile]} 3
945
    if { [regexp_diff $dumpfile "${file}.d"] } then {
946
        fail $testname
947
        verbose "output is [file_contents $dumpfile]" 2
948
        return
949
    }
950
 
951
    pass $testname
952
}
953
 
954
proc slurp_options { file } {
955
    if [catch { set f [open $file r] } x] {
956
        #perror "couldn't open `$file': $x"
957
        perror "$x"
958
        return -1
959
    }
960
    set opt_array {}
961
    # whitespace expression
962
    set ws  {[  ]*}
963
    set nws {[^         ]*}
964
    # whitespace is ignored anywhere except within the options list;
965
    # option names are alphabetic plus underscore only.
966
    set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
967
    while { [gets $f line] != -1 } {
968
        set line [string trim $line]
969
        # Whitespace here is space-tab.
970
        if [regexp $pat $line xxx opt_name opt_val] {
971
            # match!
972
            lappend opt_array [list $opt_name $opt_val]
973
        } else {
974
            break
975
        }
976
    }
977
    close $f
978
    return $opt_array
979
}
980
 
981
# regexp_diff, copied from gas, based on simple_diff above.
982
#       compares two files line-by-line
983
#       file1 contains strings, file2 contains regexps and #-comments
984
#       blank lines are ignored in either file
985
#       returns non-zero if differences exist
986
#
987
proc regexp_diff { file_1 file_2 } {
988
 
989
    set eof -1
990
    set end_1 0
991
    set end_2 0
992
    set differences 0
993
    set diff_pass 0
994
 
995
    if [file exists $file_1] then {
996
        set file_a [open $file_1 r]
997
    } else {
998
        warning "$file_1 doesn't exist"
999
        return 1
1000
    }
1001
 
1002
    if [file exists $file_2] then {
1003
        set file_b [open $file_2 r]
1004
    } else {
1005
        fail "$file_2 doesn't exist"
1006
        close $file_a
1007
        return 1
1008
    }
1009
 
1010
    verbose " Regexp-diff'ing: $file_1 $file_2" 2
1011
 
1012
    while { 1 } {
1013
        set line_a ""
1014
        set line_b ""
1015
        while { [string length $line_a] == 0 } {
1016
            if { [gets $file_a line_a] == $eof } {
1017
                set end_1 1
1018
                break
1019
            }
1020
        }
1021
        while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1022
            if [ string match "#pass" $line_b ] {
1023
                set end_2 1
1024
                set diff_pass 1
1025
                break
1026
            } elseif [ string match "#..." $line_b ] {
1027
                if { [gets $file_b line_b] == $eof } {
1028
                    set end_2 1
1029
                    set diff_pass 1
1030
                    break
1031
                }
1032
                verbose "looking for \"^$line_b$\"" 3
1033
                while { ![regexp "^$line_b$" "$line_a"] } {
1034
                    verbose "skipping    \"$line_a\"" 3
1035
                    if { [gets $file_a line_a] == $eof } {
1036
                        set end_1 1
1037
                        break
1038
                    }
1039
                }
1040
                break
1041
            }
1042
            if { [gets $file_b line_b] == $eof } {
1043
                set end_2 1
1044
                break
1045
            }
1046
        }
1047
 
1048
        if { $diff_pass } {
1049
            break
1050
        } elseif { $end_1 && $end_2 } {
1051
            break
1052
        } elseif { $end_1 } {
1053
            send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1054
            verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1055
            set differences 1
1056
            break
1057
        } elseif { $end_2 } {
1058
            send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1059
            verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1060
            set differences 1
1061
            break
1062
        } else {
1063
            verbose "regexp \"^$line_b$\"\nline   \"$line_a\"" 3
1064
            if ![regexp "^$line_b$" "$line_a"] {
1065
                send_log "regexp_diff match failure\n"
1066
                send_log "regexp \"^$line_b$\"\nline   \"$line_a\"\n"
1067
                set differences 1
1068
            }
1069
        }
1070
    }
1071
 
1072
    if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1073
        send_log "$file_1 and $file_2 are different lengths\n"
1074
        verbose "$file_1 and $file_2 are different lengths" 3
1075
        set differences 1
1076
    }
1077
 
1078
    close $file_a
1079
    close $file_b
1080
 
1081
    return $differences
1082
}
1083
 
1084
proc file_contents { filename } {
1085
    set file [open $filename r]
1086
    set contents [read $file]
1087
    close $file
1088
    return $contents
1089
}
1090
 
1091
# List contains test-items with 3 items followed by 2 lists, one item and
1092
# one optional item:
1093
# 0:name 1:ld options 2:assembler options
1094
# 3:filenames of assembler files 4: action and options. 5: name of output file
1095
# 6:compiler flags (optional)
1096
#
1097
# Actions:
1098
# objdump: Apply objdump options on result.  Compare with regex (last arg).
1099
# nm: Apply nm options on result.  Compare with regex (last arg).
1100
# readelf: Apply readelf options on result.  Compare with regex (last arg).
1101
#
1102
proc run_ld_link_tests { ldtests } {
1103
    global ld
1104
    global as
1105
    global nm
1106
    global objdump
1107
    global READELF
1108
    global srcdir
1109
    global subdir
1110
    global env
1111
    global CC
1112
    global CFLAGS
1113
 
1114
    foreach testitem $ldtests {
1115
        set testname [lindex $testitem 0]
1116
        set ld_options [lindex $testitem 1]
1117
        set as_options [lindex $testitem 2]
1118
        set src_files  [lindex $testitem 3]
1119
        set actions [lindex $testitem 4]
1120
        set binfile tmpdir/[lindex $testitem 5]
1121
        set cflags [lindex $testitem 6]
1122
        set objfiles {}
1123
        set is_unresolved 0
1124
        set failed 0
1125
 
1126
#       verbose -log "Testname is $testname"
1127
#       verbose -log "ld_options is $ld_options"
1128
#       verbose -log "as_options is $as_options"
1129
#       verbose -log "src_files is $src_files"
1130
#       verbose -log "actions is $actions"
1131
#       verbose -log "binfile is $binfile"
1132
 
1133
        # Assemble each file in the test.
1134
        foreach src_file $src_files {
1135
            set objfile "tmpdir/[file rootname $src_file].o"
1136
            lappend objfiles $objfile
1137
 
1138
            if { [file extension $src_file] == ".c" } {
1139
                set as_file "tmpdir/[file rootname $src_file].s"
1140
                if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1141
                    set is_unresolved 1
1142
                    break
1143
                }
1144
            } else {
1145
                set as_file "$srcdir/$subdir/$src_file"
1146
            }
1147
            if ![ld_assemble $as "$as_options $as_file" $objfile] {
1148
                set is_unresolved 1
1149
                break
1150
            }
1151
        }
1152
 
1153
        # Catch assembler errors.
1154
        if { $is_unresolved != 0 } {
1155
            unresolved $testname
1156
            continue
1157
        }
1158
 
1159
        if ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1160
            fail $testname
1161
        } else {
1162
            set failed 0
1163
            foreach actionlist $actions {
1164
                set action [lindex $actionlist 0]
1165
                set progopts [lindex $actionlist 1]
1166
 
1167
                # There are actions where we run regexp_diff on the
1168
                # output, and there are other actions (presumably).
1169
                # Handling of the former look the same.
1170
                set dump_prog ""
1171
                switch -- $action {
1172
                    objdump
1173
                        { set dump_prog $objdump }
1174
                    nm
1175
                        { set dump_prog $nm }
1176
                    readelf
1177
                        { set dump_prog $READELF }
1178
                    default
1179
                        {
1180
                            perror "Unrecognized action $action"
1181
                            set is_unresolved 1
1182
                            break
1183
                        }
1184
                    }
1185
 
1186
                if { $dump_prog != "" } {
1187
                    set dumpfile [lindex $actionlist 2]
1188
                    set binary $dump_prog
1189
 
1190
                    # Ensure consistent sorting of symbols
1191
                    if {[info exists env(LC_ALL)]} {
1192
                        set old_lc_all $env(LC_ALL)
1193
                    }
1194
                    set env(LC_ALL) "C"
1195
                    set cmd "$binary $progopts $binfile"
1196
                    set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1197
                    send_log "$cmd\n"
1198
                    remote_upload host "ld.stderr"
1199
                    set comp_output [prune_warnings [file_contents "ld.stderr"]]
1200
                    remote_file host delete "ld.stderr"
1201
                    remote_file build delete "ld.stderr"
1202
 
1203
                    if {[info exists old_lc_all]} {
1204
                        set env(LC_ALL) $old_lc_all
1205
                    } else {
1206
                        unset env(LC_ALL)
1207
                    }
1208
 
1209
                    if ![string match "" $comp_output] then {
1210
                        send_log "$comp_output\n"
1211
                        set failed 1
1212
                        break
1213
                    }
1214
 
1215
                    remote_upload host "dump.out"
1216
 
1217
                    if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1218
                        verbose "output is [file_contents "dump.out"]" 2
1219
                        set failed 1
1220
                        remote_file build delete "dump.out"
1221
                        remote_file host delete "dump.out"
1222
                        break
1223
                    }
1224
                    remote_file build delete "dump.out"
1225
                    remote_file host delete "dump.out"
1226
                }
1227
            }
1228
 
1229
            if { $failed != 0 } {
1230
                fail $testname
1231
            } else { if { $is_unresolved == 0 } {
1232
                pass $testname
1233
            } }
1234
        }
1235
 
1236
        # Catch action errors.
1237
        if { $is_unresolved != 0 } {
1238
            unresolved $testname
1239
            continue
1240
        }
1241
    }
1242
}
1243
 
1244
 
1245
proc verbose_eval { expr { level 1 } } {
1246
    global verbose
1247
    if $verbose>$level then { eval verbose "$expr" $level }
1248
}
1249
 
1250
# This definition is taken from an unreleased version of DejaGnu.  Once
1251
# that version gets released, and has been out in the world for a few
1252
# months at least, it may be safe to delete this copy.
1253
if ![string length [info proc prune_warnings]] {
1254
    #
1255
    # prune_warnings -- delete various system verbosities from TEXT
1256
    #
1257
    # An example is:
1258
    # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1259
    #
1260
    # Sites with particular verbose os's may wish to override this in site.exp.
1261
    #
1262
    proc prune_warnings { text } {
1263
        # This is from sun4's.  Do it for all machines for now.
1264
        # The "\\1" is to try to preserve a "\n" but only if necessary.
1265
        regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1266
 
1267
        # It might be tempting to get carried away and delete blank lines, etc.
1268
        # Just delete *exactly* what we're ask to, and that's it.
1269
        return $text
1270
    }
1271
}
1272
 
1273
# targets_to_xfail is a list of target triplets to be xfailed.
1274
# ldtests contains test-items with 3 items followed by 1 lists, 2 items
1275
# and 3 optional items:
1276
#   0:name
1277
#   1:ld options
1278
#   2:assembler options
1279
#   3:filenames of source files
1280
#   4:name of output file
1281
#   5:expected output
1282
#   6:compiler flags (optional)
1283
#   7:language (optional)
1284
#   8:linker warning (optional)
1285
 
1286
proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1287
    global ld
1288
    global as
1289
    global srcdir
1290
    global subdir
1291
    global env
1292
    global CC
1293
    global CXX
1294
    global CFLAGS
1295
    global CXXFLAGS
1296
    global errcnt
1297
    global exec_output
1298
 
1299
    foreach testitem $ldtests {
1300
        foreach target $targets_to_xfail {
1301
            setup_xfail $target
1302
        }
1303
        set testname [lindex $testitem 0]
1304
        set ld_options [lindex $testitem 1]
1305
        set as_options [lindex $testitem 2]
1306
        set src_files  [lindex $testitem 3]
1307
        set binfile tmpdir/[lindex $testitem 4]
1308
        set expfile [lindex $testitem 5]
1309
        set cflags [lindex $testitem 6]
1310
        set lang [lindex $testitem 7]
1311
        set warning [lindex $testitem 8]
1312
        set objfiles {}
1313
        set failed 0
1314
 
1315
#       verbose -log "Testname is $testname"
1316
#       verbose -log "ld_options is $ld_options"
1317
#       verbose -log "as_options is $as_options"
1318
#       verbose -log "src_files is $src_files"
1319
#       verbose -log "actions is $actions"
1320
#       verbose -log "binfile is $binfile"
1321
 
1322
        # Assemble each file in the test.
1323
        foreach src_file $src_files {
1324
            set objfile "tmpdir/[file rootname $src_file].o"
1325
            lappend objfiles $objfile
1326
 
1327
            # We ignore warnings since some compilers may generate
1328
            # incorrect section attributes and the assembler will warn
1329
            # them.
1330
            if { [ string match "c++" $lang ] } {
1331
                ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1332
            } else {
1333
                ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1334
            }
1335
 
1336
            # We have to use $CC to build PIE and shared library.
1337
            if { [ string match "c" $lang ] } {
1338
                set link_proc ld_simple_link
1339
                set link_cmd $CC
1340
            } elseif { [ string match "c++" $lang ] } {
1341
                set link_proc ld_simple_link
1342
                set link_cmd $CXX
1343
            } elseif { [ string match "-shared" $ld_options ] \
1344
                 || [ string match "-pie" $ld_options ] } {
1345
                set link_proc ld_simple_link
1346
                set link_cmd $CC
1347
            } else {
1348
                set link_proc ld_link
1349
                set link_cmd $ld
1350
            }
1351
 
1352
            if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1353
                set failed 1
1354
            } else {
1355
                set failed 0
1356
            }
1357
 
1358
            # Check if exec_output is expected.
1359
            if { $warning != "" } then {
1360
                verbose -log "returned with: <$exec_output>, expected: <$warning>"
1361
                if { [regexp $warning $exec_output] } then {
1362
                    set failed 0
1363
                } else {
1364
                    set failed 1
1365
                }
1366
            }
1367
 
1368
            if { $failed == 0 } {
1369
                send_log "Running: $binfile > $binfile.out\n"
1370
                verbose "Running: $binfile > $binfile.out"
1371
                catch "exec $binfile > $binfile.out" exec_output
1372
 
1373
                if ![string match "" $exec_output] then {
1374
                    send_log "$exec_output\n"
1375
                    verbose "$exec_output" 1
1376
                    set failed 1
1377
                } else {
1378
                    send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1379
                    verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1380
                    catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1381
                    set exec_output [prune_warnings $exec_output]
1382
 
1383
                    if ![string match "" $exec_output] then {
1384
                        send_log "$exec_output\n"
1385
                        verbose "$exec_output" 1
1386
                        set failed 1
1387
                    }
1388
                }
1389
            }
1390
 
1391
            if { $failed != 0 } {
1392
                fail $testname
1393
            } else {
1394
                set errcnt 0
1395
                pass $testname
1396
            }
1397
        }
1398
    }
1399
}
1400
 
1401
# List contains test-items with 3 items followed by 2 lists, one item and
1402
# one optional item:
1403
#  0:name
1404
#  1:link options
1405
#  2:compile options
1406
#  3:filenames of source files
1407
#  4:action and options.
1408
#  5:name of output file
1409
#  6:language (optional)
1410
#
1411
# Actions:
1412
# objdump: Apply objdump options on result.  Compare with regex (last arg).
1413
# nm: Apply nm options on result.  Compare with regex (last arg).
1414
# readelf: Apply readelf options on result.  Compare with regex (last arg).
1415
#
1416
proc run_cc_link_tests { ldtests } {
1417
    global nm
1418
    global objdump
1419
    global READELF
1420
    global srcdir
1421
    global subdir
1422
    global env
1423
    global CC
1424
    global CXX
1425
    global CFLAGS
1426
    global CXXFLAGS
1427
 
1428
    foreach testitem $ldtests {
1429
        set testname [lindex $testitem 0]
1430
        set ldflags [lindex $testitem 1]
1431
        set cflags [lindex $testitem 2]
1432
        set src_files  [lindex $testitem 3]
1433
        set actions [lindex $testitem 4]
1434
        set binfile tmpdir/[lindex $testitem 5]
1435
        set lang [lindex $testitem 6]
1436
        set objfiles {}
1437
        set is_unresolved 0
1438
        set failed 0
1439
 
1440
        # Compile each file in the test.
1441
        foreach src_file $src_files {
1442
            set objfile "tmpdir/[file rootname $src_file].o"
1443
            lappend objfiles $objfile
1444
 
1445
            # We ignore warnings since some compilers may generate
1446
            # incorrect section attributes and the assembler will warn
1447
            # them.
1448
            if { [ string match "c++" $lang ] } {
1449
                ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1450
            } else {
1451
                ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1452
            }
1453
        }
1454
 
1455
        # Clear error and warning counts.
1456
        reset_vars
1457
 
1458
        if { [ string match "c++" $lang ] } {
1459
            set cc_cmd $CXX
1460
        } else {
1461
            set cc_cmd $CC
1462
        }
1463
 
1464
        if ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
1465
            fail $testname
1466
        } else {
1467
            set failed 0
1468
            foreach actionlist $actions {
1469
                set action [lindex $actionlist 0]
1470
                set progopts [lindex $actionlist 1]
1471
 
1472
                # There are actions where we run regexp_diff on the
1473
                # output, and there are other actions (presumably).
1474
                # Handling of the former look the same.
1475
                set dump_prog ""
1476
                switch -- $action {
1477
                    objdump
1478
                        { set dump_prog $objdump }
1479
                    nm
1480
                        { set dump_prog $nm }
1481
                    readelf
1482
                        { set dump_prog $READELF }
1483
                    default
1484
                        {
1485
                            perror "Unrecognized action $action"
1486
                            set is_unresolved 1
1487
                            break
1488
                        }
1489
                    }
1490
 
1491
                if { $dump_prog != "" } {
1492
                    set dumpfile [lindex $actionlist 2]
1493
                    set binary $dump_prog
1494
 
1495
                    # Ensure consistent sorting of symbols
1496
                    if {[info exists env(LC_ALL)]} {
1497
                        set old_lc_all $env(LC_ALL)
1498
                    }
1499
                    set env(LC_ALL) "C"
1500
                    set cmd "$binary $progopts $binfile > dump.out"
1501
                    send_log "$cmd\n"
1502
                    catch "exec $cmd" comp_output
1503
                    if {[info exists old_lc_all]} {
1504
                        set env(LC_ALL) $old_lc_all
1505
                    } else {
1506
                        unset env(LC_ALL)
1507
                    }
1508
                    set comp_output [prune_warnings $comp_output]
1509
 
1510
                    if ![string match "" $comp_output] then {
1511
                        send_log "$comp_output\n"
1512
                        set failed 1
1513
                        break
1514
                    }
1515
 
1516
                    if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1517
                        verbose "output is [file_contents "dump.out"]" 2
1518
                        set failed 1
1519
                        break
1520
                    }
1521
                }
1522
            }
1523
 
1524
            if { $failed != 0 } {
1525
                fail $testname
1526
            } else { if { $is_unresolved == 0 } {
1527
                pass $testname
1528
            } }
1529
        }
1530
 
1531
        # Catch action errors.
1532
        if { $is_unresolved != 0 } {
1533
            unresolved $testname
1534
            continue
1535
        }
1536
    }
1537
}
1538
 
1539
# Returns true if --gc-sections is supported on the target.
1540
 
1541
proc check_gc_sections_available { } {
1542
    global gc_sections_available_saved
1543
    global ld
1544
 
1545
    if {![info exists gc_sections_available_saved]} {
1546
        # Some targets don't support gc-sections despite whatever's
1547
        # advertised by ld's options.
1548
        if { [istarget alpha*-*-*]
1549
             || [istarget ia64-*-*] } {
1550
            set gc_sections_available_saved 0
1551
            return 0
1552
        }
1553
 
1554
        # elf2flt uses -q (--emit-relocs), which is incompatible with
1555
        # --gc-sections.
1556
        if { [board_info target exists ldflags]
1557
             && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1558
            set gc_sections_available_saved 0
1559
            return 0
1560
        }
1561
 
1562
        # Check if the ld used by gcc supports --gc-sections.
1563
        set ld_output [remote_exec host $ld "--help"]
1564
        if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1565
            set gc_sections_available_saved 1
1566
        } else {
1567
            set gc_sections_available_saved 0
1568
        }
1569
    }
1570
    return $gc_sections_available_saved
1571
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.