63 changed files with 1505 additions and 318 deletions
@ -0,0 +1,570 @@ |
|||
/* BFD back-end for Intel arm COFF files.
|
|||
Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. |
|||
Written by Cygnus Support. |
|||
|
|||
This file is part of BFD, the Binary File Descriptor library. |
|||
|
|||
This program is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 2 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program; if not, write to the Free Software |
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|||
|
|||
#include "bfd.h" |
|||
#include "sysdep.h" |
|||
#include "libbfd.h" |
|||
#include "obstack.h" |
|||
|
|||
#include "coff/arm.h" |
|||
|
|||
#include "coff/internal.h" |
|||
|
|||
#ifdef COFF_WITH_PE |
|||
#include "coff/pe.h" |
|||
#endif |
|||
|
|||
#include "libcoff.h" |
|||
|
|||
static bfd_reloc_status_type |
|||
aoutarm_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR, |
|||
asection *, bfd *, char **)); |
|||
|
|||
static bfd_reloc_status_type |
|||
aoutarm_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, |
|||
asection *, bfd *, char **)); |
|||
|
|||
|
|||
static bfd_reloc_status_type coff_arm_reloc |
|||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); |
|||
|
|||
static bfd_reloc_status_type |
|||
coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, |
|||
error_message) |
|||
bfd *abfd; |
|||
arelent *reloc_entry; |
|||
asymbol *symbol; |
|||
PTR data; |
|||
asection *input_section; |
|||
bfd *output_bfd; |
|||
char **error_message; |
|||
{ |
|||
symvalue diff; |
|||
|
|||
if (output_bfd == (bfd *) NULL) |
|||
return bfd_reloc_continue; |
|||
|
|||
if (bfd_is_com_section (symbol->section)) |
|||
{ |
|||
/* We are relocating a common symbol. The current value in the
|
|||
object file is ORIG + OFFSET, where ORIG is the value of the |
|||
common symbol as seen by the object file when it was compiled |
|||
(this may be zero if the symbol was undefined) and OFFSET is |
|||
the offset into the common symbol (normally zero, but may be |
|||
non-zero when referring to a field in a common structure). |
|||
ORIG is the negative of reloc_entry->addend, which is set by |
|||
the CALC_ADDEND macro below. We want to replace the value in |
|||
the object file with NEW + OFFSET, where NEW is the value of |
|||
the common symbol which we are going to put in the final |
|||
object file. NEW is symbol->value. */ |
|||
diff = symbol->value + reloc_entry->addend; |
|||
} |
|||
else |
|||
{ |
|||
/* For some reason bfd_perform_relocation always effectively
|
|||
ignores the addend for a COFF target when producing |
|||
relocateable output. This seems to be always wrong for 386 |
|||
COFF, so we handle the addend here instead. */ |
|||
diff = reloc_entry->addend; |
|||
} |
|||
|
|||
#define DOIT(x) \ |
|||
x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) |
|||
|
|||
if (diff != 0) |
|||
{ |
|||
reloc_howto_type *howto = reloc_entry->howto; |
|||
unsigned char *addr = (unsigned char *) data + reloc_entry->address; |
|||
|
|||
switch (howto->size) |
|||
{ |
|||
case 0: |
|||
{ |
|||
char x = bfd_get_8 (abfd, addr); |
|||
DOIT (x); |
|||
bfd_put_8 (abfd, x, addr); |
|||
} |
|||
break; |
|||
|
|||
case 1: |
|||
{ |
|||
short x = bfd_get_16 (abfd, addr); |
|||
DOIT (x); |
|||
bfd_put_16 (abfd, x, addr); |
|||
} |
|||
break; |
|||
|
|||
case 2: |
|||
{ |
|||
long x = bfd_get_32 (abfd, addr); |
|||
DOIT (x); |
|||
bfd_put_32 (abfd, x, addr); |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
abort (); |
|||
} |
|||
} |
|||
|
|||
/* Now let bfd_perform_relocation finish everything up. */ |
|||
return bfd_reloc_continue; |
|||
} |
|||
|
|||
static reloc_howto_type aoutarm_std_reloc_howto[] = |
|||
{ |
|||
/* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ |
|||
HOWTO(0, /* type */ |
|||
0, /* rs */ |
|||
0, /* size */ |
|||
8, /* bsz */ |
|||
false, /* pcrel */ |
|||
0, /* bitpos */ |
|||
complain_overflow_bitfield, /* ovf */ |
|||
coff_arm_reloc, /* sf */ |
|||
"8", /*name */ |
|||
true, /* partial */ |
|||
0x000000ff, /*read mask */ |
|||
0x000000ff, /* setmask */ |
|||
PCRELOFFSET /* pcdone */), |
|||
HOWTO(1, |
|||
0, |
|||
1, |
|||
16, |
|||
false, |
|||
0, |
|||
complain_overflow_bitfield, |
|||
coff_arm_reloc, |
|||
"16", |
|||
true, |
|||
0x0000ffff, |
|||
0x0000ffff, |
|||
PCRELOFFSET), |
|||
HOWTO( 2, |
|||
0, |
|||
2, |
|||
32, |
|||
false, |
|||
0, |
|||
complain_overflow_bitfield, |
|||
coff_arm_reloc, |
|||
"32", |
|||
true, |
|||
0xffffffff, |
|||
0xffffffff, |
|||
PCRELOFFSET), |
|||
HOWTO( 3, |
|||
2, |
|||
3, |
|||
26, |
|||
true, |
|||
0, |
|||
complain_overflow_signed, |
|||
aoutarm_fix_pcrel_26 , |
|||
"ARM26", |
|||
true, |
|||
0x00ffffff, |
|||
0x00ffffff, |
|||
PCRELOFFSET), |
|||
HOWTO( 4, |
|||
0, |
|||
0, |
|||
8, |
|||
true, |
|||
0, |
|||
complain_overflow_signed, |
|||
coff_arm_reloc, |
|||
"DISP8", |
|||
true, |
|||
0x000000ff, |
|||
0x000000ff, |
|||
true), |
|||
HOWTO( 5, |
|||
0, |
|||
1, |
|||
16, |
|||
true, |
|||
0, |
|||
complain_overflow_signed, |
|||
coff_arm_reloc, |
|||
"DISP16", |
|||
true, |
|||
0x0000ffff, |
|||
0x0000ffff, |
|||
true), |
|||
HOWTO( 6, |
|||
0, |
|||
2, |
|||
32, |
|||
true, |
|||
0, |
|||
complain_overflow_signed, |
|||
coff_arm_reloc, |
|||
"DISP32", |
|||
true, |
|||
0xffffffff, |
|||
0xffffffff, |
|||
true), |
|||
HOWTO( 7, |
|||
2, |
|||
3, |
|||
26, |
|||
false, |
|||
0, |
|||
complain_overflow_signed, |
|||
aoutarm_fix_pcrel_26_done, |
|||
"ARM26D", |
|||
true, |
|||
0x00ffffff, |
|||
0x00ffffff, |
|||
false), |
|||
{-1}, |
|||
HOWTO( 9, |
|||
0, |
|||
-1, |
|||
16, |
|||
false, |
|||
0, |
|||
complain_overflow_bitfield, |
|||
coff_arm_reloc, |
|||
"NEG16", |
|||
true, |
|||
0x0000ffff, |
|||
0x0000ffff, |
|||
false), |
|||
HOWTO( 10, |
|||
0, |
|||
-2, |
|||
32, |
|||
false, |
|||
0, |
|||
complain_overflow_bitfield, |
|||
coff_arm_reloc, |
|||
"NEG32", |
|||
true, |
|||
0xffffffff, |
|||
0xffffffff, |
|||
false) |
|||
}; |
|||
|
|||
|
|||
|
|||
#define RTYPE2HOWTO(cache_ptr, dst) \ |
|||
(cache_ptr)->howto = aoutarm_std_reloc_howto + (dst)->r_type; |
|||
|
|||
static bfd_reloc_status_type |
|||
aoutarm_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section, |
|||
output_bfd, error_message) |
|||
bfd *abfd; |
|||
arelent *reloc_entry; |
|||
asymbol *symbol; |
|||
PTR data; |
|||
asection *input_section; |
|||
bfd *output_bfd; |
|||
char **error_message; |
|||
{ |
|||
/* This is dead simple at present. */ |
|||
return bfd_reloc_ok; |
|||
} |
|||
|
|||
static bfd_reloc_status_type |
|||
aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, |
|||
output_bfd, error_message) |
|||
bfd *abfd; |
|||
arelent *reloc_entry; |
|||
asymbol *symbol; |
|||
PTR data; |
|||
asection *input_section; |
|||
bfd *output_bfd; |
|||
char **error_message; |
|||
{ |
|||
bfd_vma relocation; |
|||
bfd_size_type addr = reloc_entry->address; |
|||
long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); |
|||
bfd_reloc_status_type flag = bfd_reloc_ok; |
|||
|
|||
/* If this is an undefined symbol, return error */ |
|||
if (symbol->section == &bfd_und_section |
|||
&& (symbol->flags & BSF_WEAK) == 0) |
|||
return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; |
|||
|
|||
/* If the sections are different, and we are doing a partial relocation,
|
|||
just ignore it for now. */ |
|||
if (symbol->section->name != input_section->name |
|||
&& output_bfd != (bfd *)NULL) |
|||
return bfd_reloc_continue; |
|||
|
|||
relocation = (target & 0x00ffffff) << 2; |
|||
relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ |
|||
relocation += symbol->value; |
|||
relocation += symbol->section->output_section->vma; |
|||
relocation += symbol->section->output_offset; |
|||
relocation += reloc_entry->addend; |
|||
relocation -= input_section->output_section->vma; |
|||
relocation -= input_section->output_offset; |
|||
relocation -= addr; |
|||
if (relocation & 3) |
|||
return bfd_reloc_overflow; |
|||
|
|||
/* Check for overflow */ |
|||
if (relocation & 0x02000000) |
|||
{ |
|||
if ((relocation & ~0x03ffffff) != ~0x03ffffff) |
|||
flag = bfd_reloc_overflow; |
|||
} |
|||
else if (relocation & ~0x03ffffff) |
|||
flag = bfd_reloc_overflow; |
|||
|
|||
target &= ~0x00ffffff; |
|||
target |= (relocation >> 2) & 0x00ffffff; |
|||
bfd_put_32 (abfd, target, (bfd_byte *) data + addr); |
|||
|
|||
/* Now the ARM magic... Change the reloc type so that it is marked as done.
|
|||
Strictly this is only necessary if we are doing a partial relocation. */ |
|||
reloc_entry->howto = &aoutarm_std_reloc_howto[7]; |
|||
|
|||
return flag; |
|||
} |
|||
|
|||
static CONST struct reloc_howto_struct * |
|||
arm_reloc_type_lookup(abfd,code) |
|||
bfd *abfd; |
|||
bfd_reloc_code_real_type code; |
|||
{ |
|||
#define ASTD(i,j) case i: return &aoutarm_std_reloc_howto[j] |
|||
if (code == BFD_RELOC_CTOR) |
|||
switch (bfd_get_arch_info (abfd)->bits_per_address) |
|||
{ |
|||
case 32: |
|||
code = BFD_RELOC_32; |
|||
break; |
|||
default: return (CONST struct reloc_howto_struct *) 0; |
|||
} |
|||
|
|||
switch (code) |
|||
{ |
|||
ASTD (BFD_RELOC_16, 1); |
|||
ASTD (BFD_RELOC_32, 2); |
|||
ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); |
|||
ASTD (BFD_RELOC_8_PCREL, 4); |
|||
ASTD (BFD_RELOC_16_PCREL, 5); |
|||
ASTD (BFD_RELOC_32_PCREL, 6); |
|||
default: return (CONST struct reloc_howto_struct *) 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
#define coff_bfd_reloc_type_lookup arm_reloc_type_lookup |
|||
|
|||
static reloc_howto_type *coff_arm_rtype_to_howto |
|||
PARAMS ((bfd *, asection *, struct internal_reloc *, |
|||
struct coff_link_hash_entry *, struct internal_syment *, |
|||
|
|||
bfd_vma *)); |
|||
|
|||
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) |
|||
/* The page size is a guess based on ELF. */ |
|||
#define COFF_PAGE_SIZE 0x1000 |
|||
|
|||
/* For some reason when using arm COFF the value stored in the .text
|
|||
section for a reference to a common symbol is the value itself plus |
|||
any desired offset. Ian Taylor, Cygnus Support. */ |
|||
|
|||
/* If we are producing relocateable output, we need to do some
|
|||
adjustments to the object file that are not done by the |
|||
bfd_perform_relocation function. This function is called by every |
|||
reloc type to make any required adjustments. */ |
|||
|
|||
static bfd_reloc_status_type |
|||
aacoff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, |
|||
error_message) |
|||
bfd *abfd; |
|||
arelent *reloc_entry; |
|||
asymbol *symbol; |
|||
PTR data; |
|||
asection *input_section; |
|||
bfd *output_bfd; |
|||
char **error_message; |
|||
{ |
|||
symvalue diff; |
|||
|
|||
if (output_bfd == (bfd *) NULL) |
|||
return bfd_reloc_continue; |
|||
|
|||
if (bfd_is_com_section (symbol->section)) |
|||
{ |
|||
/* We are relocating a common symbol. The current value in the
|
|||
object file is ORIG + OFFSET, where ORIG is the value of the |
|||
common symbol as seen by the object file when it was compiled |
|||
(this may be zero if the symbol was undefined) and OFFSET is |
|||
the offset into the common symbol (normally zero, but may be |
|||
non-zero when referring to a field in a common structure). |
|||
ORIG is the negative of reloc_entry->addend, which is set by |
|||
the CALC_ADDEND macro below. We want to replace the value in |
|||
the object file with NEW + OFFSET, where NEW is the value of |
|||
the common symbol which we are going to put in the final |
|||
object file. NEW is symbol->value. */ |
|||
diff = symbol->value + reloc_entry->addend; |
|||
} |
|||
else |
|||
{ |
|||
/* For some reason bfd_perform_relocation always effectively
|
|||
ignores the addend for a COFF target when producing |
|||
relocateable output. This seems to be always wrong for arm |
|||
COFF, so we handle the addend here instead. */ |
|||
diff = reloc_entry->addend; |
|||
} |
|||
|
|||
#define DOIT(x) \ |
|||
x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) |
|||
|
|||
if (diff != 0) |
|||
{ |
|||
reloc_howto_type *howto = reloc_entry->howto; |
|||
unsigned char *addr = (unsigned char *) data + reloc_entry->address; |
|||
|
|||
switch (howto->size) |
|||
{ |
|||
case 0: |
|||
{ |
|||
char x = bfd_get_8 (abfd, addr); |
|||
DOIT (x); |
|||
bfd_put_8 (abfd, x, addr); |
|||
} |
|||
break; |
|||
|
|||
case 1: |
|||
{ |
|||
short x = bfd_get_16 (abfd, addr); |
|||
DOIT (x); |
|||
bfd_put_16 (abfd, x, addr); |
|||
} |
|||
break; |
|||
|
|||
case 2: |
|||
{ |
|||
long x = bfd_get_32 (abfd, addr); |
|||
DOIT (x); |
|||
bfd_put_32 (abfd, x, addr); |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
abort (); |
|||
} |
|||
} |
|||
|
|||
/* Now let bfd_perform_relocation finish everything up. */ |
|||
return bfd_reloc_continue; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
/* Turn a howto into a reloc nunmber */ |
|||
|
|||
#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } |
|||
#define BADMAG(x) ARMBADMAG(x) |
|||
#define ARM 1 /* Customize coffcode.h */ |
|||
|
|||
|
|||
/* On SCO Unix 3.2.2 the native assembler generates two .data
|
|||
sections. We handle that by renaming the second one to .data2. It |
|||
does no harm to do this for any arm COFF target. */ |
|||
#define TWO_DATA_SECS |
|||
|
|||
/* For arm COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
|
|||
library. On some other COFF targets STYP_BSS is normally |
|||
STYP_NOLOAD. */ |
|||
#define BSS_NOLOAD_IS_SHARED_LIBRARY |
|||
|
|||
|
|||
/* We use the special COFF backend linker. */ |
|||
#define coff_relocate_section _bfd_coff_generic_relocate_section |
|||
|
|||
|
|||
|
|||
#include "coffcode.h" |
|||
|
|||
static const bfd_target * |
|||
i3coff_object_p(a) |
|||
bfd *a; |
|||
{ |
|||
return coff_object_p(a); |
|||
} |
|||
|
|||
const bfd_target |
|||
#ifdef TARGET_SYM |
|||
TARGET_SYM = |
|||
#else |
|||
armcoff_vec = |
|||
#endif |
|||
{ |
|||
#ifdef TARGET_NAME |
|||
TARGET_NAME, |
|||
#else |
|||
"coff-arm", /* name */ |
|||
#endif |
|||
bfd_target_coff_flavour, |
|||
false, /* data byte order is little */ |
|||
false, /* header byte order is little */ |
|||
|
|||
(HAS_RELOC | EXEC_P | /* object flags */ |
|||
HAS_LINENO | HAS_DEBUG | |
|||
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), |
|||
|
|||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ |
|||
#ifdef TARGET_UNDERSCORE |
|||
TARGET_UNDERSCORE, /* leading underscore */ |
|||
#else |
|||
0, /* leading underscore */ |
|||
#endif |
|||
'/', /* ar_pad_char */ |
|||
15, /* ar_max_namelen */ |
|||
|
|||
2, /* minimum alignment power */ |
|||
bfd_getl64, bfd_getl_signed_64, bfd_putl64, |
|||
bfd_getl32, bfd_getl_signed_32, bfd_putl32, |
|||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ |
|||
bfd_getl64, bfd_getl_signed_64, bfd_putl64, |
|||
bfd_getl32, bfd_getl_signed_32, bfd_putl32, |
|||
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ |
|||
|
|||
/* Note that we allow an object file to be treated as a core file as well. */ |
|||
{_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */ |
|||
bfd_generic_archive_p, i3coff_object_p}, |
|||
{bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ |
|||
bfd_false}, |
|||
{bfd_false, coff_write_object_contents, /* bfd_write_contents */ |
|||
_bfd_write_archive_contents, bfd_false}, |
|||
|
|||
BFD_JUMP_TABLE_GENERIC (coff), |
|||
BFD_JUMP_TABLE_COPY (coff), |
|||
BFD_JUMP_TABLE_CORE (_bfd_nocore), |
|||
BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), |
|||
BFD_JUMP_TABLE_SYMBOLS (coff), |
|||
BFD_JUMP_TABLE_RELOCS (coff), |
|||
BFD_JUMP_TABLE_WRITE (coff), |
|||
BFD_JUMP_TABLE_LINK (coff), |
|||
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), |
|||
|
|||
COFF_SWAP_TABLE, |
|||
}; |
|||
@ -0,0 +1,101 @@ |
|||
# Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
|||
|
|||
# This program is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License |
|||
# along with this program; if not, write to the Free Software |
|||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|||
|
|||
# Please email any bugs, comments, and/or additions to this file to: |
|||
# bug-dejagnu@prep.ai.mit.edu |
|||
|
|||
# This file was written by Rob Savoye <rob@cygnus.com> |
|||
# and rewritten by Ian Lance Taylor <ian@cygnus.com> |
|||
|
|||
if {[which $NM] == 0} then { |
|||
perror "$NM does not exist" |
|||
return |
|||
} |
|||
|
|||
send_user "Version [binutil_version $NM]" |
|||
|
|||
|
|||
if {![binutils_assemble $AS $srcdir$subdir/bintest.s tmpdir/bintest.o]} then { |
|||
return |
|||
} |
|||
|
|||
# Test nm with no arguments. |
|||
|
|||
# This test does not work correctly on ECOFF targets, because ECOFF |
|||
# stores most symbols twice, which messes up the nm output. |
|||
setup_xfail "alpha*-*-osf*" "alpha*-*-netware*" |
|||
setup_xfail "mips*-*-ultrix*" "mips*-*-ecoff*" "mips*-*-irix4*" |
|||
setup_xfail "mips*-*-riscos*" "mips*-*-sysv3*" |
|||
|
|||
set got [binutils_run $NM "$NMFLAGS tmpdir/bintest.o"] |
|||
|
|||
if [info exists vars] then { unset vars } |
|||
while {[regexp "(\[a-zA-Z\]) (\[a-z\]*_symbol)(.*)" $got all type symbol rest]} { |
|||
set vars($symbol) $type |
|||
set got $rest |
|||
} |
|||
|
|||
if {![info exists vars(text_symbol)] \ |
|||
|| $vars(text_symbol) != "t" \ |
|||
|| ![info exists vars(data_symbol)] \ |
|||
|| $vars(data_symbol) != "d" \ |
|||
|| ![info exists vars(common_symbol)] \ |
|||
|| $vars(common_symbol) != "C" \ |
|||
|| ![info exists vars(external_symbol)] \ |
|||
|| $vars(external_symbol) != "U"} then { |
|||
fail "nm (no arguments)" |
|||
} else { |
|||
pass "nm (no arguments)" |
|||
} |
|||
|
|||
# Test nm -g |
|||
|
|||
set got [binutils_run $NM "$NMFLAGS -g tmpdir/bintest.o"] |
|||
|
|||
if [info exists vars] then { unset vars } |
|||
while {[regexp "(\[a-z\]*_symbol)(.*)" $got all symbol rest]} { |
|||
set vars($symbol) 1 |
|||
set got $rest |
|||
} |
|||
|
|||
if {[info exists vars(text_symbol)] \ |
|||
|| [info exists vars(data_symbol)] \ |
|||
|| ![info exists vars(common_symbol)] \ |
|||
|| ![info exists vars(external_symbol)]} then { |
|||
fail "nm -g" |
|||
} else { |
|||
pass "nm -g" |
|||
} |
|||
|
|||
# Test nm -P |
|||
|
|||
# This test does not work correctly on ECOFF targets, because ECOFF |
|||
# stores most symbols twice, which messes up the nm output. |
|||
setup_xfail "alpha*-*-osf*" "alpha*-*-netware*" |
|||
setup_xfail "mips*-*-ultrix*" "mips*-*-ecoff*" "mips*-*-irix4*" |
|||
setup_xfail "mips*-*-riscos*" "mips*-*-sysv3*" |
|||
|
|||
set got [binutils_run $NM "$NMFLAGS -P tmpdir/bintest.o"] |
|||
|
|||
set want "common_symbol C \[0\]*4.*data_symbol d \[0-9a-fA-F\]*.*external_symbol U.*text_symbol t \[0-9a-fA-F\]*" |
|||
|
|||
if [regexp $want $got] then { |
|||
pass "nm -P" |
|||
} else { |
|||
fail "nm -P" |
|||
} |
|||
|
|||
# There are certainly other tests that could be run. |
|||
@ -0,0 +1,70 @@ |
|||
# Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
|||
|
|||
# This program is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License |
|||
# along with this program; if not, write to the Free Software |
|||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|||
|
|||
# Please email any bugs, comments, and/or additions to this file to: |
|||
# bug-dejagnu@prep.ai.mit.edu |
|||
|
|||
# This file was written by Rob Savoye <rob@cygnus.com> |
|||
# and rewritten by Ian Lance Taylor <ian@cygnus.com> |
|||
|
|||
if {[which $SIZE] == 0} then { |
|||
perror "$SIZE does not exist" |
|||
return |
|||
} |
|||
|
|||
send_user "Version [binutil_version $SIZE]" |
|||
|
|||
|
|||
if {![binutils_assemble $AS $srcdir$subdir/bintest.s tmpdir/bintest.o]} then { |
|||
return |
|||
} |
|||
|
|||
set dec "\[0-9\]+" |
|||
set hex "\[0-9a-fA-F\]+" |
|||
|
|||
# Test size with no arguments |
|||
|
|||
set got [binutils_run $SIZE "$SIZEFLAGS tmpdir/bintest.o"] |
|||
|
|||
set want "($dec)\[ \]+($dec)\[ \]+($dec)\[ \]+($dec)\[ \]+($hex)\[ \]+tmpdir/bintest.o" |
|||
|
|||
if ![regexp $want $got all text data bss dtot hextot] then { |
|||
fail "size (no arguments)" |
|||
} else { |
|||
if {$text < 8 || $data < 4} then { |
|||
fail "size (no arguments)" |
|||
} else { |
|||
pass "size (no arguments)" |
|||
} |
|||
} |
|||
|
|||
# Test size -A |
|||
|
|||
set got [binutils_run $SIZE "$SIZEFLAGS -A tmpdir/bintest.o"] |
|||
|
|||
set want "tmpdir/bintest.o.*(text|TEXT)\[^\n\r\]*\[ \]($dec)\[ \]+$dec.*(data|DATA)\[^\n\r\]*\[ \]($dec)\[ \]+$dec" |
|||
|
|||
if ![regexp $want $got all textname textsize dataname datasize] then { |
|||
fail "size -A" |
|||
} else { |
|||
verbose "text size: $textsize" |
|||
verbose "data size: $datasize" |
|||
if {$textsize < 8 || $datasize < 4} then { |
|||
fail "size -A" |
|||
} else { |
|||
pass "size -A" |
|||
} |
|||
} |
|||
@ -0,0 +1,116 @@ |
|||
# Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
|||
|
|||
# This program is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License |
|||
# along with this program; if not, write to the Free Software |
|||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|||
|
|||
# Please email any bugs, comments, and/or additions to this file to: |
|||
# bug-dejagnu@prep.ai.mit.edu |
|||
|
|||
# This file was written by Rob Savoye <rob@cygnus.com> |
|||
# and extended by Ian Lance Taylor <ian@cygnus.com> |
|||
|
|||
proc binutil_version { prog } { |
|||
if {[which $prog] == 0} then { |
|||
perror "$prog can't be run, file not found." |
|||
return "" |
|||
} |
|||
catch "exec $prog --version" tmp |
|||
# Should find a way to discard constant parts, keep whatever's |
|||
# left, so the version string could be almost anything at all... |
|||
regexp "version (cygnus-|)\[-0-9.a-zA-Z-\]+" $tmp version |
|||
if ![info exists version] then { |
|||
return "[which $prog] (no version number)\n" |
|||
} |
|||
set tmp $version |
|||
return "[which $prog] $version\n" |
|||
} |
|||
|
|||
# |
|||
# default_binutils_run |
|||
# run a program, returning the output |
|||
# sets binutils_run_failed if the program does not exist |
|||
# |
|||
proc default_binutils_run { prog progargs } { |
|||
global binutils_run_failed |
|||
|
|||
set binutils_run_failed 0 |
|||
|
|||
if {[which $prog] == 0} then { |
|||
perror "$prog does not exist" |
|||
set binutils_run_failed 1 |
|||
return "" |
|||
} |
|||
|
|||
send_log "$prog $progargs\n" |
|||
verbose "$prog $progargs" |
|||
|
|||
# This used to be |
|||
# catch "exec $prog $progargs" exec_output |
|||
# but that would evaluate $progargs twice, which would fail if |
|||
# any arguments started with `$'. This is a dismal hack to avoid |
|||
# this problem. I tried using |
|||
# catch { exec $prog $progargs } exec_output |
|||
# but that failed because $progargs was not split into words by |
|||
# exec. I don't know if this operation can be done correctly. No |
|||
# matter how hard I try, I can not convince myself that TCL is a |
|||
# language. |
|||
regsub -all "\\$" $progargs "\\$" progq |
|||
catch "exec $prog $progq" exec_output |
|||
if {![string match "" $exec_output]} then { |
|||
send_log "$exec_output\n" |
|||
verbose "$exec_output" |
|||
} |
|||
return $exec_output |
|||
} |
|||
|
|||
# |
|||
# default_binutils_assemble |
|||
# assemble a file |
|||
# |
|||
proc default_binutils_assemble { as source object } { |
|||
global ASFLAGS |
|||
global srcdir |
|||
|
|||
if {[which $as] == 0} then { |
|||
perror "$as does not exist" |
|||
return 0 |
|||
} |
|||
|
|||
if ![info exists ASFLAGS] { set ASFLAGS "" } |
|||
|
|||
# The HPPA assembler syntax is a little different than most, to make |
|||
# the test source file assemble we need to run it through sed. |
|||
# |
|||
# This is a hack in that it won't scale well if other targets need |
|||
# similar transformations to assemble. We'll generalize the hack |
|||
# if/when other targets need similar handling. |
|||
if [istarget "hppa*-*-*" ] then { |
|||
send_log "sed -f $srcdir/config/hppa.sed < $source | $as $ASFLAGS -o $object\n" |
|||
verbose "sed -f $srcdir/config/hppa.sed < $source | $as $ASFLAGS -o $object" |
|||
catch "exec sed -f $srcdir/config/hppa.sed < $source | $as $ASFLAGS -o $object" exec_output |
|||
} else { |
|||
send_log "$as $ASFLAGS -o $object $source\n" |
|||
verbose "$as $ASFLAGS -o $object $source" |
|||
catch "exec $as $ASFLAGS -o $object $source" exec_output |
|||
} |
|||
|
|||
if [string match "" $exec_output] then { |
|||
return 1 |
|||
} else { |
|||
send_log "$exec_output\n" |
|||
verbose "$exec_output" |
|||
perror "$source: assembly failed" |
|||
return 0 |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
# Expect script for LD Bootstrap Tests |
|||
# Copyright (C) 1993,1994,1995 Free Software Foundation |
|||
# |
|||
# This file is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License |
|||
# along with this program; if not, write to the Free Software |
|||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|||
# |
|||
# Written by Jeffrey Wheat (cassidy@cygnus.com) |
|||
# Rewritten by Ian Lance Taylor (ian@cygnus.com) |
|||
# |
|||
|
|||
# Make sure that ld can bootstrap itself. |
|||
|
|||
# This test can only be run if ld generates native executables. |
|||
if ![isnative] { |
|||
return |
|||
} |
|||
|
|||
# Bootstrap ld. First link the object files together using -r, in |
|||
# order to test -r. Then link the result into an executable, ld1, to |
|||
# really test -r. Use ld1 to link a fresh ld, ld2. Use ld2 to link a |
|||
# new ld, ld3. ld2 and ld3 should be identical. |
|||
|
|||
foreach flags {"" "--static" "--traditional-format" "--no-keep-memory"} { |
|||
if {"$flags" != ""} { |
|||
set testname "bootstrap with $flags" |
|||
} else { |
|||
set testname "bootstrap" |
|||
} |
|||
|
|||
# This test can only be run if we have the ld build directory, |
|||
# since we need the object files. |
|||
if {$ld != "$objdir/ld.new"} { |
|||
untested $testname |
|||
continue |
|||
} |
|||
|
|||
if ![ld_relocate $ld tmpdir/ld-partial.o "$flags $OFILES"] { |
|||
fail $testname |
|||
continue |
|||
} |
|||
|
|||
if ![ld_link $ld tmpdir/ld1 "$flags tmpdir/ld-partial.o $BFDLIB $LIBIBERTY"] { |
|||
fail $testname |
|||
continue |
|||
} |
|||
|
|||
if ![ld_link tmpdir/ld1 tmpdir/ld2 "$flags $OFILES $BFDLIB $LIBIBERTY"] { |
|||
fail $testname |
|||
continue |
|||
} |
|||
|
|||
if ![ld_link tmpdir/ld2 tmpdir/ld3 "$flags $OFILES $BFDLIB $LIBIBERTY"] { |
|||
fail $testname |
|||
continue |
|||
} |
|||
|
|||
send_log "cmp tmpdir/ld2 tmpdir/ld3\n" |
|||
verbose "cmp tmpdir/ld2 tmpdir/ld3" |
|||
catch "exec cmp tmpdir/ld2 tmpdir/ld3" exec_output |
|||
set exec_output [prune_system_crud $host_triplet $exec_output] |
|||
|
|||
if [string match "" $exec_output] then { |
|||
pass $testname |
|||
} else { |
|||
send_log "$exec_output\n" |
|||
verbose "$exec_output" 1 |
|||
|
|||
fail $testname |
|||
} |
|||
} |
|||
@ -0,0 +1,94 @@ |
|||
# Expect script for LD cdtest Tests |
|||
# Copyright (C) 1993,1994,1995 Free Software Foundation |
|||
# |
|||
# This file is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 of the License, or |
|||
# (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License |
|||
# along with this program; if not, write to the Free Software |
|||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|||
# |
|||
# Written by Jeffrey Wheat (cassidy@cygnus.com) |
|||
# Rewritten by Ian Lance Taylor (ian@cygnus.com) |
|||
# |
|||
|
|||
# Make sure that constructors are handled correctly. |
|||
|
|||
set test1 "cdtest" |
|||
set test2 "cdtest with -Ur" |
|||
|
|||
# This test requires running the executable generated by ld. |
|||
if ![isnative] { |
|||
return |
|||
} |
|||
|
|||
if { ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir$subdir/cdtest-foo.cc tmpdir/cdtest-foo.o] |
|||
|| ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir$subdir/cdtest-bar.cc tmpdir/cdtest-bar.o] |
|||
|| ![ld_compile "$CXX $CXXFLAGS -fgnu-linker" $srcdir$subdir/cdtest-main.cc tmpdir/cdtest-main.o] } { |
|||
unresolved $test1 |
|||
unresolved $test2 |
|||
return |
|||
} |
|||
|
|||
if ![ld_link $ld tmpdir/cdtest {tmpdir/cdtest-foo.o tmpdir/cdtest-bar.o tmpdir/cdtest-main.o}] { |
|||
fail $test1 |
|||
} else { |
|||
send_log "tmpdir/cdtest >tmpdir/cdtest.out\n" |
|||
verbose "tmpdir/cdtest >tmpdir/cdtest.out" |
|||
catch "exec tmpdir/cdtest >tmpdir/cdtest.out" exec_output |
|||
if ![string match "" $exec_output] then { |
|||
send_log "$exec_output\n" |
|||
verbose "$exec_output" 1 |
|||
fail $test1 |
|||
} else { |
|||
send_log "diff tmpdir/cdtest.out $srcdir$subdir/cdtest.dat\n" |
|||
verbose "diff tmpdir/cdtest.out $srcdir$subdir/cdtest.dat" |
|||
catch "exec diff tmpdir/cdtest.out $srcdir$subdir/cdtest.dat" exec_output |
|||
set exec_output [prune_system_crud $host_triplet $exec_output] |
|||
|
|||
if [string match "" $exec_output] then { |
|||
pass $test1 |
|||
} else { |
|||
send_log "$exec_output\n" |
|||
verbose "$exec_output" 1 |
|||
fail $test1 |
|||
} |
|||
} |
|||
} |
|||
|
|||
if ![ld_relocate $ld tmpdir/cdtest.o {-Ur tmpdir/cdtest-foo.o tmpdir/cdtest-bar.o tmpdir/cdtest-main.o}] { |
|||
fail $test2 |
|||
} else { |
|||
if ![ld_link $ld tmpdir/cdtest tmpdir/cdtest.o] { |
|||
fail $test2 |
|||
} else { |
|||
send_log "tmpdir/cdtest >tmpdir/cdtest.out\n" |
|||
verbose "tmpdir/cdtest >tmpdir/cdtest.out" |
|||
catch "exec tmpdir/cdtest >tmpdir/cdtest.out" exec_output |
|||
if ![string match "" $exec_output] then { |
|||
send_log "$exec_output\n" |
|||
verbose "$exec_output" 1 |
|||
fail $test2 |
|||
} else { |
|||
send_log "diff tmpdir/cdtest.out $srcdir$subdir/cdtest.dat\n" |
|||
verbose "diff tmpdir/cdtest.out $srcdir$subdir/cdtest.dat" |
|||
catch "exec diff tmpdir/cdtest.out $srcdir$subdir/cdtest.dat" exec_output |
|||
set exec_output [prune_system_crud $host_triplet $exec_output] |
|||
|
|||
if [string match "" $exec_output] then { |
|||
pass $test2 |
|||
} else { |
|||
send_log "$exec_output\n" |
|||
verbose "$exec_output" 1 |
|||
fail $test2 |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue