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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [ld/] [testsuite/] [lib/] [ld-lib.exp] - Blame information for rev 219

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

Line No. Rev Author Line
1 205 julius
# Support routines for LD testsuite.
2
#   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3
#    2004, 2005, 2006, 2007, 2008, 2009  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
# Define various symbols needed when not linking against all
356
# target libs.
357
proc ld_simple_link_defsyms {} {
358
 
359
    set flags "--defsym __stack_chk_fail=0"
360
 
361
    # ARM targets call __gccmain
362
    if {[istarget arm*-*-*]       || \
363
        [istarget strongarm*-*-*] || \
364
        [istarget xscale*-*-*]    || \
365
        [istarget thumb-*-*] } {
366
        append flags " --defsym __gccmain=0"
367
    }
368
 
369
    # PowerPC EABI code calls __eabi.
370
    if {[istarget powerpc*-*-eabi*] || [istarget powerpc*-*-rtems*]} {
371
        append flags " --defsym __eabi=0"
372
    }
373
 
374
    # mn10200 code calls __truncsipsi2_d0_d2.
375
    if {[istarget mn10200*-*-*]} then {
376
        append flags " --defsym __truncsipsi2_d0_d2=0"
377
    }
378
 
379
    # m6811/m6812 code has references to soft registers.
380
    if {[istarget m6811-*-*] || [istarget m6812-*-*]} {
381
        append flags " --defsym _.frame=0 --defsym _.d1=0 --defsym _.d2=0"
382
        append flags " --defsym _.d3=0 --defsym _.d4=0"
383
        append flags " --defsym _.tmp=0 --defsym _.xy=0 --defsym _.z=0"
384
    }
385
 
386
    # Some OpenBSD targets have ProPolice and reference __guard and
387
    # __stack_smash_handler.
388
    if [istarget *-*-openbsd*] {
389
        append flags " --defsym __guard=0"
390
        append flags " --defsym __stack_smash_handler=0"
391
    }
392
 
393
    return $flags
394
}
395
 
396
# True if the object format is known to be ELF.
397
#
398
proc is_elf_format {} {
399
    if { ![istarget *-*-sysv4*] \
400
         && ![istarget *-*-unixware*] \
401
         && ![istarget *-*-elf*] \
402
         && ![istarget *-*-eabi*] \
403
         && ![istarget hppa*64*-*-hpux*] \
404
         && ![istarget *-*-linux*] \
405
         && ![istarget frv-*-uclinux*] \
406
         && ![istarget bfin-*-uclinux] \
407
         && ![istarget *-*-irix5*] \
408
         && ![istarget *-*-irix6*] \
409
         && ![istarget *-*-netbsd*] \
410
         && ![istarget *-*-solaris2*] } {
411
        return 0
412
    }
413
 
414
    if { [istarget *-*-linux*aout*] \
415
         || [istarget *-*-linux*oldld*] } {
416
        return 0
417
    }
418
 
419
    if { ![istarget *-*-netbsdelf*] \
420
         && ([istarget *-*-netbsd*aout*] \
421
             || [istarget *-*-netbsdpe*] \
422
             || [istarget arm*-*-netbsd*] \
423
             || [istarget sparc-*-netbsd*] \
424
             || [istarget i*86-*-netbsd*] \
425
             || [istarget m68*-*-netbsd*] \
426
             || [istarget vax-*-netbsd*] \
427
             || [istarget ns32k-*-netbsd*]) } {
428
        return 0
429
    }
430
    return 1
431
}
432
 
433
# True if the object format is known to be 64-bit ELF.
434
#
435
proc is_elf64 { binary_file } {
436
    global READELF
437
    global READELFFLAGS
438
 
439
    set readelf_size ""
440
    catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
441
 
442
    if ![string match "" $got] then {
443
        return 0
444
    }
445
 
446
    if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
447
           [file_contents readelf.out] nil readelf_size] } {
448
        return 0
449
    }
450
 
451
    if { $readelf_size == "64" } {
452
        return 1
453
    }
454
 
455
    return 0
456
}
457
 
458
# True if the object format is known to be a.out.
459
#
460
proc is_aout_format {} {
461
    if { [istarget *-*-*\[ab\]out*] \
462
             || [istarget *-*-linux*oldld*] \
463
             || [istarget *-*-msdos*] \
464
             || [istarget arm-*-netbsd] \
465
             || [istarget i?86-*-netbsd] \
466
             || [istarget i?86-*-mach*] \
467
             || [istarget i?86-*-vsta] \
468
             || [istarget pdp11-*-*] \
469
             || [istarget m68*-ericsson-ose] \
470
             || [istarget m68k-hp-bsd*] \
471
             || [istarget m68*-*-hpux*] \
472
             || [istarget m68*-*-netbsd] \
473
             || [istarget m68*-*-netbsd*4k*] \
474
             || [istarget m68k-sony-*] \
475
             || [istarget m68*-sun-sunos\[34\]*] \
476
             || [istarget m68*-wrs-vxworks*] \
477
             || [istarget ns32k-*-*] \
478
             || [istarget sparc*-*-netbsd] \
479
             || [istarget sparc-sun-sunos4*] \
480
             || [istarget vax-dec-ultrix*] \
481
             || [istarget vax-*-netbsd] } {
482
        return 1
483
    }
484
    return 0
485
}
486
 
487
# True if the object format is known to be PE COFF.
488
#
489
proc is_pecoff_format {} {
490
    if { ![istarget *-*-mingw*] \
491
         && ![istarget *-*-cygwin*] \
492
         && ![istarget *-*-cegcc*] \
493
         && ![istarget *-*-pe*] } {
494
        return 0
495
    }
496
 
497
    return 1
498
}
499
 
500
# Compares two files line-by-line.
501
#   Returns differences if exist.
502
#   Returns null if file(s) cannot be opened.
503
#
504
proc simple_diff { file_1 file_2 } {
505
    global target
506
 
507
    set eof -1
508
    set differences 0
509
 
510
    if [file exists $file_1] then {
511
        set file_a [open $file_1 r]
512
    } else {
513
        warning "$file_1 doesn't exist"
514
        return
515
    }
516
 
517
    if [file exists $file_2] then {
518
        set file_b [open $file_2 r]
519
    } else {
520
        fail "$file_2 doesn't exist"
521
        return
522
    }
523
 
524
    verbose "# Diff'ing: $file_1 $file_2\n" 2
525
 
526
    while { [gets $file_a line] != $eof } {
527
        if [regexp "^#.*$" $line] then {
528
            continue
529
        } else {
530
            lappend list_a $line
531
        }
532
    }
533
    close $file_a
534
 
535
    while { [gets $file_b line] != $eof } {
536
        if [regexp "^#.*$" $line] then {
537
            continue
538
        } else {
539
            lappend list_b $line
540
        }
541
    }
542
    close $file_b
543
 
544
    for { set i 0 } { $i < [llength $list_a] } { incr i } {
545
        set line_a [lindex $list_a $i]
546
        set line_b [lindex $list_b $i]
547
 
548
        verbose "\t$file_1: $i: $line_a\n" 3
549
        verbose "\t$file_2: $i: $line_b\n" 3
550
        if [string compare $line_a $line_b] then {
551
            verbose -log "\t$file_1: $i: $line_a\n"
552
            verbose -log "\t$file_2: $i: $line_b\n"
553
 
554
            fail "Test: $target"
555
            return
556
        }
557
    }
558
 
559
    if { [llength $list_a] != [llength $list_b] } {
560
        fail "Test: $target"
561
        return
562
    }
563
 
564
    if $differences<1 then {
565
        pass "Test: $target"
566
    }
567
}
568
 
569
# run_dump_test FILE
570
# Copied from gas testsuite, tweaked and further extended.
571
#
572
# Assemble a .s file, then run some utility on it and check the output.
573
#
574
# There should be an assembly language file named FILE.s in the test
575
# suite directory, and a pattern file called FILE.d.  `run_dump_test'
576
# will assemble FILE.s, run some tool like `objdump', `objcopy', or
577
# `nm' on the .o file to produce textual output, and then analyze that
578
# with regexps.  The FILE.d file specifies what program to run, and
579
# what to expect in its output.
580
#
581
# The FILE.d file begins with zero or more option lines, which specify
582
# flags to pass to the assembler, the program to run to dump the
583
# assembler's output, and the options it wants.  The option lines have
584
# the syntax:
585
#
586
#         # OPTION: VALUE
587
#
588
# OPTION is the name of some option, like "name" or "objdump", and
589
# VALUE is OPTION's value.  The valid options are described below.
590
# Whitespace is ignored everywhere, except within VALUE.  The option
591
# list ends with the first line that doesn't match the above syntax
592
# (hmm, not great for error detection).
593
#
594
# The interesting options are:
595
#
596
#   name: TEST-NAME
597
#       The name of this test, passed to DejaGNU's `pass' and `fail'
598
#       commands.  If omitted, this defaults to FILE, the root of the
599
#       .s and .d files' names.
600
#
601
#   as: FLAGS
602
#       When assembling, pass FLAGS to the assembler.
603
#       If assembling several files, you can pass different assembler
604
#       options in the "source" directives.  See below.
605
#
606
#   ld: FLAGS
607
#       Link assembled files using FLAGS, in the order of the "source"
608
#       directives, when using multiple files.
609
#
610
#   ld_after_inputfiles: FLAGS
611
#       Similar to "ld", but put after all input files.
612
#
613
#   objcopy_linked_file: FLAGS
614
#       Run objcopy on the linked file with the specified flags.
615
#       This lets you transform the linked file using objcopy, before the
616
#       result is analyzed by an analyzer program specified below (which
617
#       may in turn *also* be objcopy).
618
#
619
#   PROG: PROGRAM-NAME
620
#       The name of the program to run to analyze the .o file produced
621
#       by the assembler or the linker output.  This can be omitted;
622
#       run_dump_test will guess which program to run by seeing which of
623
#       the flags options below is present.
624
#
625
#   objdump: FLAGS
626
#   nm: FLAGS
627
#   objcopy: FLAGS
628
#       Use the specified program to analyze the assembler or linker
629
#       output file, and pass it FLAGS, in addition to the output name.
630
#       Note that they are run with LC_ALL=C in the environment to give
631
#       consistent sorting of symbols.
632
#
633
#   source: SOURCE [FLAGS]
634
#       Assemble the file SOURCE.s using the flags in the "as" directive
635
#       and the (optional) FLAGS.  If omitted, the source defaults to
636
#       FILE.s.
637
#       This is useful if several .d files want to share a .s file.
638
#       More than one "source" directive can be given, which is useful
639
#       when testing linking.
640
#
641
#   xfail: TARGET
642
#       The test is expected to fail on TARGET.  This may occur more than
643
#       once.
644
#
645
#   target: TARGET
646
#       Only run the test for TARGET.  This may occur more than once; the
647
#       target being tested must match at least one.  You may provide target
648
#       name "cfi" for any target supporting the CFI statements.
649
#
650
#   notarget: TARGET
651
#       Do not run the test for TARGET.  This may occur more than once;
652
#       the target being tested must not match any of them.
653
#
654
#   error: REGEX
655
#       An error with message matching REGEX must be emitted for the test
656
#       to pass.  The PROG, objdump, nm and objcopy options have no
657
#       meaning and need not supplied if this is present.
658
#
659
#   warning: REGEX
660
#       Expect a linker warning matching REGEX.  It is an error to issue
661
#       both "error" and "warning".
662
#
663
# Each option may occur at most once unless otherwise mentioned.
664
#
665
# After the option lines come regexp lines.  `run_dump_test' calls
666
# `regexp_diff' to compare the output of the dumping tool against the
667
# regexps in FILE.d.  `regexp_diff' is defined later in this file; see
668
# further comments there.
669
#
670
proc run_dump_test { name } {
671
    global subdir srcdir
672
    global OBJDUMP NM AS OBJCOPY READELF LD
673
    global OBJDUMPFLAGS NMFLAGS ASFLAGS OBJCOPYFLAGS READELFFLAGS LDFLAGS
674
    global host_triplet runtests
675
    global env verbose
676
 
677
    if [string match "*/*" $name] {
678
        set file $name
679
        set name [file tail $name]
680
    } else {
681
        set file "$srcdir/$subdir/$name"
682
    }
683
 
684
    if ![runtest_file_p $runtests $name] then {
685
        return
686
    }
687
 
688
    set opt_array [slurp_options "${file}.d"]
689
    if { $opt_array == -1 } {
690
        perror "error reading options from $file.d"
691
        unresolved $subdir/$name
692
        return
693
    }
694
    set dumpfile tmpdir/dump.out
695
    set run_ld 0
696
    set run_objcopy 0
697
    set opts(as) {}
698
    set opts(ld) {}
699
    set opts(ld_after_inputfiles) {}
700
    set opts(xfail) {}
701
    set opts(target) {}
702
    set opts(notarget) {}
703
    set opts(objdump) {}
704
    set opts(nm) {}
705
    set opts(objcopy) {}
706
    set opts(readelf) {}
707
    set opts(name) {}
708
    set opts(PROG) {}
709
    set opts(source) {}
710
    set opts(error) {}
711
    set opts(warning) {}
712
    set opts(objcopy_linked_file) {}
713
    set asflags(${file}.s) {}
714
 
715
    foreach i $opt_array {
716
        set opt_name [lindex $i 0]
717
        set opt_val [lindex $i 1]
718
        if ![info exists opts($opt_name)] {
719
            perror "unknown option $opt_name in file $file.d"
720
            unresolved $subdir/$name
721
            return
722
        }
723
 
724
        switch -- $opt_name {
725
            xfail {}
726
            target {}
727
            notarget {}
728
            source {
729
                # Move any source-specific as-flags to a separate array to
730
                # simplify processing.
731
                if { [llength $opt_val] > 1 } {
732
                    set asflags([lindex $opt_val 0]) [lrange $opt_val 1 end]
733
                    set opt_val [lindex $opt_val 0]
734
                } else {
735
                    set asflags($opt_val) {}
736
                }
737
            }
738
            default {
739
                if [string length $opts($opt_name)] {
740
                    perror "option $opt_name multiply set in $file.d"
741
                    unresolved $subdir/$name
742
                    return
743
                }
744
 
745
                # A single "# ld:" with no options should do the right thing.
746
                if { $opt_name == "ld" } {
747
                    set run_ld 1
748
                }
749
                # Likewise objcopy_linked_file.
750
                if { $opt_name == "objcopy_linked_file" } {
751
                    set run_objcopy 1
752
                }
753
            }
754
        }
755
        if { $opt_name == "as" || $opt_name == "ld" } {
756
            set opt_val [subst $opt_val]
757
        }
758
        set opts($opt_name) [concat $opts($opt_name) $opt_val]
759
    }
760
    foreach opt { as ld } {
761
        regsub {\[big_or_little_endian\]} $opts($opt) \
762
            [big_or_little_endian] opts($opt)
763
    }
764
 
765
    # Decide early whether we should run the test for this target.
766
    if { [llength $opts(target)] > 0 } {
767
        set targmatch 0
768
        foreach targ $opts(target) {
769
            if [istarget $targ] {
770
                set targmatch 1
771
                break
772
            }
773
        }
774
        if { $targmatch == 0 } {
775
            return
776
        }
777
    }
778
    foreach targ $opts(notarget) {
779
        if [istarget $targ] {
780
            return
781
        }
782
    }
783
 
784
    set program ""
785
    # It's meaningless to require an output-testing method when we
786
    # expect an error.
787
    if { $opts(error) == "" } {
788
        if {$opts(PROG) != ""} {
789
            switch -- $opts(PROG) {
790
                objdump { set program objdump }
791
                nm      { set program nm }
792
                objcopy { set program objcopy }
793
                readelf { set program readelf }
794
                default
795
                { perror "unrecognized program option $opts(PROG) in $file.d"
796
                  unresolved $subdir/$name
797
                  return }
798
            }
799
        } else {
800
        # Guess which program to run, by seeing which option was specified.
801
            foreach p {objdump objcopy nm readelf} {
802
                if {$opts($p) != ""} {
803
                    if {$program != ""} {
804
                        perror "ambiguous dump program in $file.d"
805
                        unresolved $subdir/$name
806
                        return
807
                    } else {
808
                        set program $p
809
                    }
810
                }
811
            }
812
        }
813
        if { $program == "" && $opts(warning) == "" } {
814
            perror "dump program unspecified in $file.d"
815
            unresolved $subdir/$name
816
            return
817
        }
818
    }
819
 
820
    if { $opts(name) == "" } {
821
        set testname "$subdir/$name"
822
    } else {
823
        set testname $opts(name)
824
    }
825
 
826
    if { $opts(source) == "" } {
827
        set sourcefiles [list ${file}.s]
828
    } else {
829
        set sourcefiles {}
830
        foreach sf $opts(source) {
831
            if { [string match "/*" $sf] } {
832
                lappend sourcefiles "$sf"
833
            } else {
834
                lappend sourcefiles "$srcdir/$subdir/$sf"
835
            }
836
            # Must have asflags indexed on source name.
837
            set asflags($srcdir/$subdir/$sf) $asflags($sf)
838
        }
839
    }
840
 
841
    # Time to setup xfailures.
842
    foreach targ $opts(xfail) {
843
        setup_xfail $targ
844
    }
845
 
846
    # Assemble each file.
847
    set objfiles {}
848
    for { set i 0 } { $i < [llength $sourcefiles] } { incr i } {
849
        set sourcefile [lindex $sourcefiles $i]
850
 
851
        set objfile "tmpdir/dump$i.o"
852
        catch "exec rm -f $objfile" exec_output
853
        lappend objfiles $objfile
854
        set cmd "$AS $ASFLAGS $opts(as) $asflags($sourcefile) -o $objfile $sourcefile"
855
 
856
        send_log "$cmd\n"
857
        set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
858
        remote_upload host "ld.tmp"
859
        set comp_output [prune_warnings [file_contents "ld.tmp"]]
860
        remote_file host delete "ld.tmp"
861
        remote_file build delete "ld.tmp"
862
 
863
        if { [lindex $cmdret 0] != 0 || ![string match "" $comp_output] } then {
864
            send_log "$comp_output\n"
865
            verbose "$comp_output" 3
866
 
867
            set exitstat "succeeded"
868
            if { $cmdret != 0 } { set exitstat "failed" }
869
            verbose -log "$exitstat with: <$comp_output>"
870
            fail $testname
871
            return
872
        }
873
    }
874
 
875
    set expmsg $opts(error)
876
    if { $opts(warning) != "" } {
877
        if { $expmsg != "" } {
878
            perror "$testname: mixing error and warning test-directives"
879
            return
880
        }
881
        set expmsg $opts(warning)
882
    }
883
 
884
    # Perhaps link the file(s).
885
    if { $run_ld } {
886
        set objfile "tmpdir/dump"
887
        catch "exec rm -f $objfile" exec_output
888
 
889
        # Add -L$srcdir/$subdir so that the linker command can use
890
        # linker scripts in the source directory.
891
        set cmd "$LD $LDFLAGS -L$srcdir/$subdir \
892
                   $opts(ld) -o $objfile $objfiles $opts(ld_after_inputfiles)"
893
 
894
        send_log "$cmd\n"
895
        set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
896
        remote_upload host "ld.tmp"
897
        set comp_output [file_contents "ld.tmp"]
898
        remote_file host delete "ld.tmp"
899
        remote_file build delete "ld.tmp"
900
        set cmdret [lindex $cmdret 0]
901
 
902
        if { $cmdret == 0 && $run_objcopy } {
903
            set infile $objfile
904
            set objfile "tmpdir/dump1"
905
            remote_file host delete $objfile
906
 
907
            # Note that we don't use OBJCOPYFLAGS here; any flags must be
908
            # explicitly specified.
909
            set cmd "$OBJCOPY $opts(objcopy_linked_file) $infile $objfile"
910
 
911
            send_log "$cmd\n"
912
            set cmdret [remote_exec host [concat sh -c [list "$cmd 2>&1"]] "" "/dev/null" "ld.tmp"]
913
            remote_upload host "ld.tmp"
914
            append comp_output [file_contents "ld.tmp"]
915
            remote_file host delete "ld.tmp"
916
            remote_file build delete "ld.tmp"
917
            set cmdret [lindex $cmdret 0]
918
        }
919
 
920
        regsub "\n$" $comp_output "" comp_output
921
        if { $cmdret != 0 || $comp_output != "" || $expmsg != "" } then {
922
            set exitstat "succeeded"
923
            if { $cmdret != 0 } { set exitstat "failed" }
924
            verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
925
            send_log "$comp_output\n"
926
            verbose "$comp_output" 3
927
 
928
            if { [regexp $expmsg $comp_output] \
929
                    && (($cmdret == 0) == ($opts(warning) != "")) } {
930
                # We have the expected output from ld.
931
                if { $opts(error) != "" || $program == "" } {
932
                    pass $testname
933
                    return
934
                }
935
            } else {
936
                verbose -log "$exitstat with: <$comp_output>, expected: <$expmsg>"
937
                fail $testname
938
                return
939
            }
940
        }
941
    } else {
942
        set objfile "tmpdir/dump0.o"
943
    }
944
 
945
    # We must not have expected failure if we get here.
946
    if { $opts(error) != "" } {
947
        fail $testname
948
        return
949
    }
950
 
951
    set progopts1 $opts($program)
952
    eval set progopts \$[string toupper $program]FLAGS
953
    eval set binary \$[string toupper $program]
954
 
955
    if { ![is_remote host] && [which $binary] == 0 } {
956
        untested $testname
957
        return
958
    }
959
 
960
    if { $progopts1 == "" } { set $progopts1 "-r" }
961
    verbose "running $binary $progopts $progopts1" 3
962
 
963
    # Objcopy, unlike the other two, won't send its output to stdout,
964
    # so we have to run it specially.
965
    set cmd "$binary $progopts $progopts1 $objfile > $dumpfile"
966
    if { $program == "objcopy" } {
967
        set cmd "$binary $progopts $progopts1 $objfile $dumpfile"
968
    }
969
 
970
    # Ensure consistent sorting of symbols
971
    if {[info exists env(LC_ALL)]} {
972
        set old_lc_all $env(LC_ALL)
973
    }
974
    set env(LC_ALL) "C"
975
    send_log "$cmd\n"
976
    set cmdret [remote_exec host [concat sh -c [list "$cmd 2>ld.tmp"]] "" "/dev/null"]
977
    remote_upload host "ld.tmp"
978
    set comp_output [prune_warnings [file_contents "ld.tmp"]]
979
    remote_file host delete "ld.tmp"
980
    remote_file build delete "ld.tmp"
981
    if {[info exists old_lc_all]} {
982
        set env(LC_ALL) $old_lc_all
983
    } else {
984
        unset env(LC_ALL)
985
    }
986
    if ![string match "" $comp_output] then {
987
        send_log "$comp_output\n"
988
        fail $testname
989
        return
990
    }
991
 
992
    if { $verbose > 2 } then { verbose "output is [file_contents $dumpfile]" 3 }
993
    if { [regexp_diff $dumpfile "${file}.d"] } then {
994
        fail $testname
995
        if { $verbose == 2 } then { verbose "output is [file_contents $dumpfile]" 2 }
996
        return
997
    }
998
 
999
    pass $testname
1000
}
1001
 
1002
proc slurp_options { file } {
1003
    if [catch { set f [open $file r] } x] {
1004
        #perror "couldn't open `$file': $x"
1005
        perror "$x"
1006
        return -1
1007
    }
1008
    set opt_array {}
1009
    # whitespace expression
1010
    set ws  {[  ]*}
1011
    set nws {[^         ]*}
1012
    # whitespace is ignored anywhere except within the options list;
1013
    # option names are alphabetic plus underscore only.
1014
    set pat "^#${ws}(\[a-zA-Z_\]*)$ws:${ws}(.*)$ws\$"
1015
    while { [gets $f line] != -1 } {
1016
        set line [string trim $line]
1017
        # Whitespace here is space-tab.
1018
        if [regexp $pat $line xxx opt_name opt_val] {
1019
            # match!
1020
            lappend opt_array [list $opt_name $opt_val]
1021
        } else {
1022
            break
1023
        }
1024
    }
1025
    close $f
1026
    return $opt_array
1027
}
1028
 
1029
# regexp_diff, copied from gas, based on simple_diff above.
1030
#       compares two files line-by-line
1031
#       file1 contains strings, file2 contains regexps and #-comments
1032
#       blank lines are ignored in either file
1033
#       returns non-zero if differences exist
1034
#
1035
proc regexp_diff { file_1 file_2 } {
1036
 
1037
    set eof -1
1038
    set end_1 0
1039
    set end_2 0
1040
    set differences 0
1041
    set diff_pass 0
1042
 
1043
    if [file exists $file_1] then {
1044
        set file_a [open $file_1 r]
1045
    } else {
1046
        warning "$file_1 doesn't exist"
1047
        return 1
1048
    }
1049
 
1050
    if [file exists $file_2] then {
1051
        set file_b [open $file_2 r]
1052
    } else {
1053
        fail "$file_2 doesn't exist"
1054
        close $file_a
1055
        return 1
1056
    }
1057
 
1058
    verbose " Regexp-diff'ing: $file_1 $file_2" 2
1059
 
1060
    while { 1 } {
1061
        set line_a ""
1062
        set line_b ""
1063
        while { [string length $line_a] == 0 } {
1064
            if { [gets $file_a line_a] == $eof } {
1065
                set end_1 1
1066
                break
1067
            }
1068
        }
1069
        while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
1070
            if [ string match "#pass" $line_b ] {
1071
                set end_2 1
1072
                set diff_pass 1
1073
                break
1074
            } elseif [ string match "#..." $line_b ] {
1075
                if { [gets $file_b line_b] == $eof } {
1076
                    set end_2 1
1077
                    set diff_pass 1
1078
                    break
1079
                }
1080
                verbose "looking for \"^$line_b$\"" 3
1081
                while { ![regexp "^$line_b$" "$line_a"] } {
1082
                    verbose "skipping    \"$line_a\"" 3
1083
                    if { [gets $file_a line_a] == $eof } {
1084
                        set end_1 1
1085
                        break
1086
                    }
1087
                }
1088
                break
1089
            }
1090
            if { [gets $file_b line_b] == $eof } {
1091
                set end_2 1
1092
                break
1093
            }
1094
        }
1095
 
1096
        if { $diff_pass } {
1097
            break
1098
        } elseif { $end_1 && $end_2 } {
1099
            break
1100
        } elseif { $end_1 } {
1101
            send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
1102
            verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
1103
            set differences 1
1104
            break
1105
        } elseif { $end_2 } {
1106
            send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
1107
            verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
1108
            set differences 1
1109
            break
1110
        } else {
1111
            verbose "regexp \"^$line_b$\"\nline   \"$line_a\"" 3
1112
            if ![regexp "^$line_b$" "$line_a"] {
1113
                send_log "regexp_diff match failure\n"
1114
                send_log "regexp \"^$line_b$\"\nline   \"$line_a\"\n"
1115
                set differences 1
1116
            }
1117
        }
1118
    }
1119
 
1120
    if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
1121
        send_log "$file_1 and $file_2 are different lengths\n"
1122
        verbose "$file_1 and $file_2 are different lengths" 3
1123
        set differences 1
1124
    }
1125
 
1126
    close $file_a
1127
    close $file_b
1128
 
1129
    return $differences
1130
}
1131
 
1132
proc file_contents { filename } {
1133
    set file [open $filename r]
1134
    set contents [read $file]
1135
    close $file
1136
    return $contents
1137
}
1138
 
1139
# Create an archive using ar
1140
#
1141
proc ar_simple_create { ar aropts target objects } {
1142
    remote_file host delete $target
1143
 
1144
    set exec_output [run_host_cmd "$ar" "$aropts rc $target $objects"]
1145
    set exec_output [prune_warnings $exec_output]
1146
 
1147
    if [string match "" $exec_output] then {
1148
        send_log "$exec_output\n"
1149
        return 1
1150
    } else {
1151
        return 0
1152
    }
1153
}
1154
 
1155
# List contains test-items with 3 items followed by 2 lists, one item and
1156
# one optional item:
1157
# 0:name 1:ld/ar options 2:assembler options
1158
# 3:filenames of assembler files 4: action and options. 5: name of output file
1159
# 6:compiler flags (optional)
1160
#
1161
# Actions:
1162
# objdump: Apply objdump options on result.  Compare with regex (last arg).
1163
# nm: Apply nm options on result.  Compare with regex (last arg).
1164
# readelf: Apply readelf options on result.  Compare with regex (last arg).
1165
#
1166
proc run_ld_link_tests { ldtests } {
1167
    global ld
1168
    global as
1169
    global nm
1170
    global ar
1171
    global objdump
1172
    global READELF
1173
    global srcdir
1174
    global subdir
1175
    global env
1176
    global CC
1177
    global CFLAGS
1178
    global runtests
1179
 
1180
    foreach testitem $ldtests {
1181
        set testname [lindex $testitem 0]
1182
 
1183
        if ![runtest_file_p $runtests $testname] then {
1184
            continue
1185
        }
1186
 
1187
        set ld_options [lindex $testitem 1]
1188
        set as_options [lindex $testitem 2]
1189
        set src_files  [lindex $testitem 3]
1190
        set actions [lindex $testitem 4]
1191
        set binfile tmpdir/[lindex $testitem 5]
1192
        set cflags [lindex $testitem 6]
1193
        set objfiles {}
1194
        set is_unresolved 0
1195
        set failed 0
1196
 
1197
#       verbose -log "Testname is $testname"
1198
#       verbose -log "ld_options is $ld_options"
1199
#       verbose -log "as_options is $as_options"
1200
#       verbose -log "src_files is $src_files"
1201
#       verbose -log "actions is $actions"
1202
#       verbose -log "binfile is $binfile"
1203
 
1204
        # Assemble each file in the test.
1205
        foreach src_file $src_files {
1206
            set objfile "tmpdir/[file rootname $src_file].o"
1207
            lappend objfiles $objfile
1208
 
1209
            if { [file extension $src_file] == ".c" } {
1210
                set as_file "tmpdir/[file rootname $src_file].s"
1211
                if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
1212
                    set is_unresolved 1
1213
                    break
1214
                }
1215
            } else {
1216
                set as_file "$srcdir/$subdir/$src_file"
1217
            }
1218
            if ![ld_assemble $as "$as_options $as_file" $objfile] {
1219
                set is_unresolved 1
1220
                break
1221
            }
1222
        }
1223
 
1224
        # Catch assembler errors.
1225
        if { $is_unresolved != 0 } {
1226
            unresolved $testname
1227
            continue
1228
        }
1229
 
1230
        if { [regexp ".*a$" $binfile] } {
1231
            if { ![ar_simple_create $ar $ld_options $binfile "$objfiles"] } {
1232
                fail $testname
1233
                set failed 1
1234
            } else {
1235
                set failed 0
1236
            }
1237
        } elseif { ![ld_simple_link $ld $binfile "-L$srcdir/$subdir $ld_options $objfiles"] } {
1238
            fail $testname
1239
            set failed 1
1240
        } else {
1241
            set failed 0
1242
        }
1243
 
1244
        if { $failed == 0 } {
1245
            foreach actionlist $actions {
1246
                set action [lindex $actionlist 0]
1247
                set progopts [lindex $actionlist 1]
1248
 
1249
                # There are actions where we run regexp_diff on the
1250
                # output, and there are other actions (presumably).
1251
                # Handling of the former look the same.
1252
                set dump_prog ""
1253
                switch -- $action {
1254
                    objdump
1255
                        { set dump_prog $objdump }
1256
                    nm
1257
                        { set dump_prog $nm }
1258
                    readelf
1259
                        { set dump_prog $READELF }
1260
                    default
1261
                        {
1262
                            perror "Unrecognized action $action"
1263
                            set is_unresolved 1
1264
                            break
1265
                        }
1266
                    }
1267
 
1268
                if { $dump_prog != "" } {
1269
                    set dumpfile [lindex $actionlist 2]
1270
                    set binary $dump_prog
1271
 
1272
                    # Ensure consistent sorting of symbols
1273
                    if {[info exists env(LC_ALL)]} {
1274
                        set old_lc_all $env(LC_ALL)
1275
                    }
1276
                    set env(LC_ALL) "C"
1277
                    set cmd "$binary $progopts $binfile"
1278
                    set status [remote_exec host [concat sh -c [list "$cmd >dump.out 2>ld.stderr"]] "" "/dev/null"]
1279
                    send_log "$cmd\n"
1280
                    remote_upload host "ld.stderr"
1281
                    set comp_output [prune_warnings [file_contents "ld.stderr"]]
1282
                    remote_file host delete "ld.stderr"
1283
                    remote_file build delete "ld.stderr"
1284
 
1285
                    if {[info exists old_lc_all]} {
1286
                        set env(LC_ALL) $old_lc_all
1287
                    } else {
1288
                        unset env(LC_ALL)
1289
                    }
1290
 
1291
                    if ![string match "" $comp_output] then {
1292
                        send_log "$comp_output\n"
1293
                        set failed 1
1294
                        break
1295
                    }
1296
 
1297
                    remote_upload host "dump.out"
1298
 
1299
                    if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1300
                        verbose "output is [file_contents "dump.out"]" 2
1301
                        set failed 1
1302
                        remote_file build delete "dump.out"
1303
                        remote_file host delete "dump.out"
1304
                        break
1305
                    }
1306
                    remote_file build delete "dump.out"
1307
                    remote_file host delete "dump.out"
1308
                }
1309
            }
1310
 
1311
            if { $failed != 0 } {
1312
                fail $testname
1313
            } else { if { $is_unresolved == 0 } {
1314
                pass $testname
1315
            } }
1316
        }
1317
 
1318
        # Catch action errors.
1319
        if { $is_unresolved != 0 } {
1320
            unresolved $testname
1321
            continue
1322
        }
1323
    }
1324
}
1325
 
1326
# This definition is taken from an unreleased version of DejaGnu.  Once
1327
# that version gets released, and has been out in the world for a few
1328
# months at least, it may be safe to delete this copy.
1329
if ![string length [info proc prune_warnings]] {
1330
    #
1331
    # prune_warnings -- delete various system verbosities from TEXT
1332
    #
1333
    # An example is:
1334
    # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
1335
    #
1336
    # Sites with particular verbose os's may wish to override this in site.exp.
1337
    #
1338
    proc prune_warnings { text } {
1339
        # This is from sun4's.  Do it for all machines for now.
1340
        # The "\\1" is to try to preserve a "\n" but only if necessary.
1341
        regsub -all "(^|\n)(ld.so: warning:\[^\n\]*\n?)+" $text "\\1" text
1342
 
1343
        # It might be tempting to get carried away and delete blank lines, etc.
1344
        # Just delete *exactly* what we're ask to, and that's it.
1345
        return $text
1346
    }
1347
}
1348
 
1349
# targets_to_xfail is a list of target triplets to be xfailed.
1350
# ldtests contains test-items with 3 items followed by 1 lists, 2 items
1351
# and 3 optional items:
1352
#   0:name
1353
#   1:ld options
1354
#   2:assembler options
1355
#   3:filenames of source files
1356
#   4:name of output file
1357
#   5:expected output
1358
#   6:compiler flags (optional)
1359
#   7:language (optional)
1360
#   8:linker warning (optional)
1361
 
1362
proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
1363
    global ld
1364
    global as
1365
    global srcdir
1366
    global subdir
1367
    global env
1368
    global CC
1369
    global CXX
1370
    global CFLAGS
1371
    global CXXFLAGS
1372
    global errcnt
1373
    global exec_output
1374
 
1375
    foreach testitem $ldtests {
1376
        foreach target $targets_to_xfail {
1377
            setup_xfail $target
1378
        }
1379
        set testname [lindex $testitem 0]
1380
        set ld_options [lindex $testitem 1]
1381
        set as_options [lindex $testitem 2]
1382
        set src_files  [lindex $testitem 3]
1383
        set binfile tmpdir/[lindex $testitem 4]
1384
        set expfile [lindex $testitem 5]
1385
        set cflags [lindex $testitem 6]
1386
        set lang [lindex $testitem 7]
1387
        set warning [lindex $testitem 8]
1388
        set objfiles {}
1389
        set failed 0
1390
 
1391
#       verbose -log "Testname is $testname"
1392
#       verbose -log "ld_options is $ld_options"
1393
#       verbose -log "as_options is $as_options"
1394
#       verbose -log "src_files is $src_files"
1395
#       verbose -log "actions is $actions"
1396
#       verbose -log "binfile is $binfile"
1397
 
1398
        # Assemble each file in the test.
1399
        foreach src_file $src_files {
1400
            set objfile "tmpdir/[file rootname $src_file].o"
1401
            lappend objfiles $objfile
1402
 
1403
            # We ignore warnings since some compilers may generate
1404
            # incorrect section attributes and the assembler will warn
1405
            # them.
1406
            if { [ string match "c++" $lang ] } {
1407
                ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1408
            } else {
1409
                ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1410
            }
1411
 
1412
            # We have to use $CC to build PIE and shared library.
1413
            if { [ string match "c" $lang ] } {
1414
                set link_proc ld_simple_link
1415
                set link_cmd $CC
1416
            } elseif { [ string match "c++" $lang ] } {
1417
                set link_proc ld_simple_link
1418
                set link_cmd $CXX
1419
            } elseif { [ string match "-shared" $ld_options ] \
1420
                 || [ string match "-pie" $ld_options ] } {
1421
                set link_proc ld_simple_link
1422
                set link_cmd $CC
1423
            } else {
1424
                set link_proc ld_link
1425
                set link_cmd $ld
1426
            }
1427
 
1428
            if ![$link_proc $link_cmd $binfile "-L$srcdir/$subdir $ld_options $objfiles"] {
1429
                set failed 1
1430
            } else {
1431
                set failed 0
1432
            }
1433
 
1434
            # Check if exec_output is expected.
1435
            if { $warning != "" } then {
1436
                verbose -log "returned with: <$exec_output>, expected: <$warning>"
1437
                if { [regexp $warning $exec_output] } then {
1438
                    set failed 0
1439
                } else {
1440
                    set failed 1
1441
                }
1442
            }
1443
 
1444
            if { $failed == 0 } {
1445
                send_log "Running: $binfile > $binfile.out\n"
1446
                verbose "Running: $binfile > $binfile.out"
1447
                catch "exec $binfile > $binfile.out" exec_output
1448
 
1449
                if ![string match "" $exec_output] then {
1450
                    send_log "$exec_output\n"
1451
                    verbose "$exec_output" 1
1452
                    set failed 1
1453
                } else {
1454
                    send_log "diff $binfile.out $srcdir/$subdir/$expfile\n"
1455
                    verbose "diff $binfile.out $srcdir/$subdir/$expfile"
1456
                    catch "exec diff $binfile.out $srcdir/$subdir/$expfile" exec_output
1457
                    set exec_output [prune_warnings $exec_output]
1458
 
1459
                    if ![string match "" $exec_output] then {
1460
                        send_log "$exec_output\n"
1461
                        verbose "$exec_output" 1
1462
                        set failed 1
1463
                    }
1464
                }
1465
            }
1466
 
1467
            if { $failed != 0 } {
1468
                fail $testname
1469
            } else {
1470
                set errcnt 0
1471
                pass $testname
1472
            }
1473
        }
1474
    }
1475
}
1476
 
1477
# List contains test-items with 3 items followed by 2 lists, one item and
1478
# one optional item:
1479
#  0:name
1480
#  1:ld or ar options
1481
#  2:compile options
1482
#  3:filenames of source files
1483
#  4:action and options.
1484
#  5:name of output file
1485
#  6:language (optional)
1486
#
1487
# Actions:
1488
# objdump: Apply objdump options on result.  Compare with regex (last arg).
1489
# nm: Apply nm options on result.  Compare with regex (last arg).
1490
# readelf: Apply readelf options on result.  Compare with regex (last arg).
1491
#
1492
proc run_cc_link_tests { ldtests } {
1493
    global nm
1494
    global objdump
1495
    global READELF
1496
    global srcdir
1497
    global subdir
1498
    global env
1499
    global CC
1500
    global CXX
1501
    global CFLAGS
1502
    global CXXFLAGS
1503
    global ar
1504
 
1505
    foreach testitem $ldtests {
1506
        set testname [lindex $testitem 0]
1507
        set ldflags [lindex $testitem 1]
1508
        set cflags [lindex $testitem 2]
1509
        set src_files  [lindex $testitem 3]
1510
        set actions [lindex $testitem 4]
1511
        set binfile tmpdir/[lindex $testitem 5]
1512
        set lang [lindex $testitem 6]
1513
        set objfiles {}
1514
        set is_unresolved 0
1515
        set failed 0
1516
 
1517
        # Compile each file in the test.
1518
        foreach src_file $src_files {
1519
            set objfile "tmpdir/[file rootname $src_file].o"
1520
            lappend objfiles $objfile
1521
 
1522
            # We ignore warnings since some compilers may generate
1523
            # incorrect section attributes and the assembler will warn
1524
            # them.
1525
            if { [ string match "c++" $lang ] } {
1526
                ld_compile "$CXX -c $CXXFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1527
            } else {
1528
                ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
1529
            }
1530
        }
1531
 
1532
        # Clear error and warning counts.
1533
        reset_vars
1534
 
1535
        if { [ string match "c++" $lang ] } {
1536
            set cc_cmd $CXX
1537
        } else {
1538
            set cc_cmd $CC
1539
        }
1540
 
1541
        if { [regexp ".*a$" $binfile] } {
1542
            if { ![ar_simple_create $ar $ldflags $binfile "$objfiles"] } {
1543
                fail $testname
1544
                set failed 1
1545
            } else {
1546
                set failed 0
1547
            }
1548
        } elseif { ![ld_simple_link $cc_cmd $binfile "-L$srcdir/$subdir $ldflags $objfiles"] } {
1549
            fail $testname
1550
            set failed 1
1551
        } else {
1552
            set failed 0
1553
        }
1554
 
1555
        if { $failed == 0 } {
1556
            foreach actionlist $actions {
1557
                set action [lindex $actionlist 0]
1558
                set progopts [lindex $actionlist 1]
1559
 
1560
                # There are actions where we run regexp_diff on the
1561
                # output, and there are other actions (presumably).
1562
                # Handling of the former look the same.
1563
                set dump_prog ""
1564
                switch -- $action {
1565
                    objdump
1566
                        { set dump_prog $objdump }
1567
                    nm
1568
                        { set dump_prog $nm }
1569
                    readelf
1570
                        { set dump_prog $READELF }
1571
                    default
1572
                        {
1573
                            perror "Unrecognized action $action"
1574
                            set is_unresolved 1
1575
                            break
1576
                        }
1577
                    }
1578
 
1579
                if { $dump_prog != "" } {
1580
                    set dumpfile [lindex $actionlist 2]
1581
                    set binary $dump_prog
1582
 
1583
                    # Ensure consistent sorting of symbols
1584
                    if {[info exists env(LC_ALL)]} {
1585
                        set old_lc_all $env(LC_ALL)
1586
                    }
1587
                    set env(LC_ALL) "C"
1588
                    set cmd "$binary $progopts $binfile > dump.out"
1589
                    send_log "$cmd\n"
1590
                    catch "exec $cmd" comp_output
1591
                    if {[info exists old_lc_all]} {
1592
                        set env(LC_ALL) $old_lc_all
1593
                    } else {
1594
                        unset env(LC_ALL)
1595
                    }
1596
                    set comp_output [prune_warnings $comp_output]
1597
 
1598
                    if ![string match "" $comp_output] then {
1599
                        send_log "$comp_output\n"
1600
                        set failed 1
1601
                        break
1602
                    }
1603
 
1604
                    if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
1605
                        verbose "output is [file_contents "dump.out"]" 2
1606
                        set failed 1
1607
                        break
1608
                    }
1609
                }
1610
            }
1611
 
1612
            if { $failed != 0 } {
1613
                fail $testname
1614
            } else { if { $is_unresolved == 0 } {
1615
                pass $testname
1616
            } }
1617
        }
1618
 
1619
        # Catch action errors.
1620
        if { $is_unresolved != 0 } {
1621
            unresolved $testname
1622
            continue
1623
        }
1624
    }
1625
}
1626
 
1627
# Returns true if --gc-sections is supported on the target.
1628
 
1629
proc check_gc_sections_available { } {
1630
    global gc_sections_available_saved
1631
    global ld
1632
 
1633
    if {![info exists gc_sections_available_saved]} {
1634
        # Some targets don't support gc-sections despite whatever's
1635
        # advertised by ld's options.
1636
        if { [istarget alpha*-*-*]
1637
             || [istarget mep-*-*]
1638
             || [istarget ia64-*-*]
1639
             || [istarget *-*-cygwin]
1640
             || [istarget *-*-mingw*] } {
1641
            set gc_sections_available_saved 0
1642
            return 0
1643
        }
1644
 
1645
        # elf2flt uses -q (--emit-relocs), which is incompatible with
1646
        # --gc-sections.
1647
        if { [board_info target exists ldflags]
1648
             && [regexp " -elf2flt\[ =\]" " [board_info target ldflags] "] } {
1649
            set gc_sections_available_saved 0
1650
            return 0
1651
        }
1652
 
1653
        # Check if the ld used by gcc supports --gc-sections.
1654
        set ld_output [remote_exec host $ld "--help"]
1655
        if { [ string first "--gc-sections" $ld_output ] >= 0 } {
1656
            set gc_sections_available_saved 1
1657
        } else {
1658
            set gc_sections_available_saved 0
1659
        }
1660
    }
1661
    return $gc_sections_available_saved
1662
}
1663
 
1664
# Check if the assembler supports CFI statements.
1665
 
1666
proc check_as_cfi { } {
1667
    global check_as_cfi_result
1668
    global as
1669
    if [info exists check_as_cfi_result] {
1670
        return $check_as_cfi_result
1671
    }
1672
    set as_file "tmpdir/check_as_cfi.s"
1673
    set as_fh [open $as_file w 0666]
1674
    puts $as_fh "# Generated file. DO NOT EDIT"
1675
    puts $as_fh "\t.cfi_startproc"
1676
    puts $as_fh "\t.cfi_endproc"
1677
    close $as_fh
1678
    remote_download host $as_file
1679
    verbose -log "Checking CFI support:"
1680
    rename "perror" "check_as_cfi_perror"
1681
    proc perror { args } { }
1682
    set success [ld_assemble $as $as_file "/dev/null"]
1683
    rename "perror" ""
1684
    rename "check_as_cfi_perror" "perror"
1685
    #remote_file host delete $as_file
1686
    set check_as_cfi_result $success
1687
    return $success
1688
}
1689
 
1690
# Provide virtual target "cfi" for targets supporting CFI.
1691
 
1692
rename "istarget" "istarget_ld"
1693
proc istarget { target } {
1694
    if {$target == "cfi"} {
1695
        return [check_as_cfi]
1696
    }
1697
    return [istarget_ld $target]
1698
}

powered by: WebSVN 2.1.0

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