From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30587 invoked by alias); 28 Jun 2004 13:34:27 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 30528 invoked from network); 28 Jun 2004 13:34:21 -0000 Received: from unknown (HELO modra.org) (144.136.182.188) by sourceware.org with SMTP; 28 Jun 2004 13:34:21 -0000 Received: by bubble.modra.org (Postfix, from userid 500) id 1A3E955807; Mon, 28 Jun 2004 23:04:20 +0930 (CST) Date: Mon, 28 Jun 2004 13:34:00 -0000 From: Alan Modra To: "Aaron W. LaFramboise" , binutils@sources.redhat.com Subject: Re: mainline ld on mingw32/pe is broken, returns 1 without error. Message-ID: <20040628133419.GT3469@bubble.modra.org> Mail-Followup-To: "Aaron W. LaFramboise" , binutils@sources.redhat.com References: <40DE22EB.7080001@aaronwl.com> <20040627040640.GM3469@bubble.modra.org> <40DE4DDA.5000304@aaronwl.com> <20040627114932.GO3469@bubble.modra.org> <40DFA627.5010009@aaronwl.com> <20040628051054.GR3469@bubble.modra.org> <40DFA9A4.3010303@aaronwl.com> <20040628062618.GS3469@bubble.modra.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040628062618.GS3469@bubble.modra.org> User-Agent: Mutt/1.4i X-SW-Source: 2004-06/txt/msg00516.txt.bz2 On Mon, Jun 28, 2004 at 03:56:18PM +0930, Alan Modra wrote: > Sigh. This has to be the stabstr section created at stabs.c:248 (if > the section came from an input file, it wouldn't have filepos == 0). > > It looks like the linker relies on raw size being zero for these > sections. ie. places where I do o->rawsize ? o->rawsize : o->size > are broken. The fix will be to set rawsize for all input sections, > and remove all the places I test rawsize. This should fix the stabs breakage. I decided not to pursue the idea of setting rawsize when reading sections from disk. The fewer places that need to touch rawsize, the better. bfd/ChangeLog * bfd-in.h (struct stab_info): Move from stabs.c. * stabs.c (struct stab_link_includes_table): Delete. (stab_link_includes_lookup): Delete. (_bfd_write_section_stabs, _bfd_write_stab_strings): Remove one level of indirection from sinfo parm. (_bfd_link_section_stabs): Likewise. Set SEC_LINKER_CREATED on stabstr section. Adjust hash table accesses. * coff-ppc.c (ppc_bfd_coff_final_link): Do include rawsize in contents alloc. Adjust stab_info test. * cofflink.c (_bfd_coff_link_hash_table_init): Clear stab_info. (_bfd_coff_final_link): Adjust stab_info test. (_bfd_coff_link_input_bfd): Ignore SEC_LINKER_CREATED sections. * elf-bfd.h (struct elf_link_hash_table): Include struct stab_info in place. * libcoff-in.h (struct coff_link_hash_table): Likewise. * elf.c (_bfd_elf_link_hash_table_init): Clear stab_info. * elflink.c (bfd_elf_final_link): Don't attempt to link linker created stabstr section. Adjust stab_info test. * libbfd-in.h (_bfd_link_section_stabs, _bfd_write_section_stabs) (_bfd_write_stab_strings): Adjust prototypes. * libbfd.h: Regenerate. * libcoff.h: Regenerate. * bfd-in2.h: Regenerate. Index: bfd/bfd-in.h =================================================================== RCS file: /cvs/src/src/bfd/bfd-in.h,v retrieving revision 1.83 diff -u -p -r1.83 bfd-in.h --- bfd/bfd-in.h 24 Jun 2004 04:46:14 -0000 1.83 +++ bfd/bfd-in.h 28 Jun 2004 13:15:59 -0000 @@ -439,6 +439,19 @@ extern void bfd_hash_traverse this size. */ extern void bfd_hash_set_default_size (bfd_size_type); +/* This structure is used to keep track of stabs in sections + information while linking. */ + +struct stab_info +{ + /* A hash table used to hold stabs strings. */ + struct bfd_strtab_hash *strings; + /* The header file hash table. */ + struct bfd_hash_table includes; + /* The first .stabstr section. */ + struct bfd_section *stabstr; +}; + #define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table /* User program access to BFD facilities. */ Index: bfd/coff-ppc.c =================================================================== RCS file: /cvs/src/src/bfd/coff-ppc.c,v retrieving revision 1.20 diff -u -p -r1.20 coff-ppc.c --- bfd/coff-ppc.c 24 Jun 2004 04:46:15 -0000 1.20 +++ bfd/coff-ppc.c 28 Jun 2004 13:16:06 -0000 @@ -2328,6 +2328,8 @@ ppc_bfd_coff_final_link (abfd, info) if (info->relocatable) o->reloc_count += sec->reloc_count; + if (sec->rawsize > max_contents_size) + max_contents_size = sec->rawsize; if (sec->size > max_contents_size) max_contents_size = sec->size; if (sec->lineno_count > max_lineno_count) @@ -2663,7 +2665,7 @@ ppc_bfd_coff_final_link (abfd, info) } /* If we have optimized stabs strings, output them. */ - if (coff_hash_table (info)->stab_info != NULL) + if (coff_hash_table (info)->stab_info.stabstr != NULL) { if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info)) return FALSE; Index: bfd/cofflink.c =================================================================== RCS file: /cvs/src/src/bfd/cofflink.c,v retrieving revision 1.44 diff -u -p -r1.44 cofflink.c --- bfd/cofflink.c 24 Jun 2004 04:46:16 -0000 1.44 +++ bfd/cofflink.c 28 Jun 2004 13:16:08 -0000 @@ -96,7 +96,7 @@ _bfd_coff_link_hash_table_init (struct c struct bfd_hash_table *, const char *)) { - table->stab_info = NULL; + memset (&table->stab_info, 0, sizeof (table->stab_info)); return _bfd_link_hash_table_init (&table->root, abfd, newfunc); } @@ -1082,7 +1082,7 @@ _bfd_coff_final_link (bfd *abfd, } /* If we have optimized stabs strings, output them. */ - if (coff_hash_table (info)->stab_info != NULL) + if (coff_hash_table (info)->stab_info.stabstr != NULL) { if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info)) return FALSE; @@ -2282,6 +2282,9 @@ _bfd_coff_link_input_bfd (struct coff_fi /* This section was omitted from the link. */ continue; + if ((o->flags & SEC_LINKER_CREATED) != 0) + continue; + if ((o->flags & SEC_HAS_CONTENTS) == 0 || (o->size == 0 && (o->flags & SEC_RELOC) == 0)) { Index: bfd/elf-bfd.h =================================================================== RCS file: /cvs/src/src/bfd/elf-bfd.h,v retrieving revision 1.143 diff -u -p -r1.143 elf-bfd.h --- bfd/elf-bfd.h 21 Jun 2004 14:45:41 -0000 1.143 +++ bfd/elf-bfd.h 28 Jun 2004 13:16:14 -0000 @@ -356,12 +356,12 @@ struct elf_link_hash_table /* The _GLOBAL_OFFSET_TABLE_ symbol. */ struct elf_link_hash_entry *hgot; - /* A pointer to information used to link stabs in sections. */ - void *stab_info; - /* A pointer to information used to merge SEC_MERGE sections. */ void *merge_info; + /* Used to link stabs in sections. */ + struct stab_info stab_info; + /* Used by eh_frame code when editing .eh_frame. */ struct eh_frame_hdr_info eh_info; Index: bfd/elf.c =================================================================== RCS file: /cvs/src/src/bfd/elf.c,v retrieving revision 1.231 diff -u -p -r1.231 elf.c --- bfd/elf.c 24 Jun 2004 04:46:18 -0000 1.231 +++ bfd/elf.c 28 Jun 2004 13:16:19 -0000 @@ -1466,8 +1466,8 @@ _bfd_elf_link_hash_table_init table->bucketcount = 0; table->needed = NULL; table->hgot = NULL; - table->stab_info = NULL; table->merge_info = NULL; + memset (&table->stab_info, 0, sizeof (table->stab_info)); memset (&table->eh_info, 0, sizeof (table->eh_info)); table->dynlocal = NULL; table->runpath = NULL; Index: bfd/elflink.c =================================================================== RCS file: /cvs/src/src/bfd/elflink.c,v retrieving revision 1.74 diff -u -p -r1.74 elflink.c --- bfd/elflink.c 24 Jun 2004 04:46:22 -0000 1.74 +++ bfd/elflink.c 28 Jun 2004 13:16:53 -0000 @@ -4124,7 +4124,7 @@ elf_link_add_object_symbols (bfd *abfd, secdata = elf_section_data (stab); if (! _bfd_link_section_stabs (abfd, - & hash_table->stab_info, + &hash_table->stab_info, stab, stabstr, &secdata->sec_info, &string_offset)) @@ -8001,6 +8001,8 @@ bfd_elf_final_link (bfd *abfd, struct bf created by _bfd_elf_link_create_dynamic_sections. */ continue; } + if (elf_hash_table (info)->stab_info.stabstr == o) + continue; if (elf_hash_table (info)->eh_info.hdr_sec == o) continue; if ((elf_section_data (o->output_section)->this_hdr.sh_type @@ -8036,7 +8038,7 @@ bfd_elf_final_link (bfd *abfd, struct bf } /* If we have optimized stabs strings, output them. */ - if (elf_hash_table (info)->stab_info != NULL) + if (elf_hash_table (info)->stab_info.stabstr != NULL) { if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info)) goto error_return; Index: bfd/libbfd-in.h =================================================================== RCS file: /cvs/src/src/bfd/libbfd-in.h,v retrieving revision 1.37 diff -u -p -r1.37 libbfd-in.h --- bfd/libbfd-in.h 24 Jun 2004 04:46:24 -0000 1.37 +++ bfd/libbfd-in.h 28 Jun 2004 13:17:00 -0000 @@ -498,7 +498,8 @@ extern bfd_reloc_status_type _bfd_reloca /* Link stabs in sections in the first pass. */ extern bfd_boolean _bfd_link_section_stabs - (bfd *, void **, asection *, asection *, void **, bfd_size_type *); + (bfd *, struct stab_info *, asection *, asection *, void **, + bfd_size_type *); /* Eliminate stabs for discarded functions and symbols. */ extern bfd_boolean _bfd_discard_section_stabs @@ -507,12 +508,12 @@ extern bfd_boolean _bfd_discard_section_ /* Write out the .stab section when linking stabs in sections. */ extern bfd_boolean _bfd_write_section_stabs - (bfd *, void **, asection *, void **, bfd_byte *); + (bfd *, struct stab_info *, asection *, void **, bfd_byte *); /* Write out the .stabstr string table when linking stabs in sections. */ extern bfd_boolean _bfd_write_stab_strings - (bfd *, void **); + (bfd *, struct stab_info *); /* Find an offset within a .stab section when linking stabs in sections. */ Index: bfd/libcoff-in.h =================================================================== RCS file: /cvs/src/src/bfd/libcoff-in.h,v retrieving revision 1.20 diff -u -p -r1.20 libcoff-in.h --- bfd/libcoff-in.h 20 Oct 2003 14:38:39 -0000 1.20 +++ bfd/libcoff-in.h 28 Jun 2004 13:17:01 -0000 @@ -276,7 +276,7 @@ struct coff_link_hash_table { struct bfd_link_hash_table root; /* A pointer to information used to link stabs in sections. */ - PTR stab_info; + struct stab_info stab_info; }; /* Look up an entry in a COFF linker hash table. */ Index: bfd/stabs.c =================================================================== RCS file: /cvs/src/src/bfd/stabs.c,v retrieving revision 1.19 diff -u -p -r1.19 stabs.c --- bfd/stabs.c 24 Jun 2004 04:46:26 -0000 1.19 +++ bfd/stabs.c 28 Jun 2004 13:17:05 -0000 @@ -48,13 +48,6 @@ #define VALOFF (8) #define STABSIZE (12) -/* A hash table used for header files with N_BINCL entries. */ - -struct stab_link_includes_table -{ - struct bfd_hash_table root; -}; - /* A linked list of totals that we have found for a particular header file. A total is a unique identifier for a particular BINCL...EINCL sequence of STABs that can be used to identify duplicate sequences. @@ -80,12 +73,6 @@ struct stab_link_includes_entry struct stab_link_includes_totals *totals; }; -/* Look up an entry in an the header file hash table. */ - -#define stab_link_includes_lookup(table, string, create, copy) \ - ((struct stab_link_includes_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - /* This structure is used to hold a list of N_BINCL symbols, some of which might be converted into N_EXCL symbols. */ @@ -124,19 +111,6 @@ struct stab_section_info bfd_size_type stridxs[1]; }; -/* This structure is used to keep track of stabs in sections - information while linking. */ - -struct stab_info -{ - /* A hash table used to hold stabs strings. */ - struct bfd_strtab_hash *strings; - /* The header file hash table. */ - struct stab_link_includes_table includes; - /* The first .stabstr section. */ - asection *stabstr; -}; - static struct bfd_hash_entry *stab_link_includes_newfunc PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); @@ -176,16 +150,15 @@ stab_link_includes_newfunc (entry, table pass of the linker. */ bfd_boolean -_bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_offset) +_bfd_link_section_stabs (abfd, sinfo, stabsec, stabstrsec, psecinfo, pstring_offset) bfd *abfd; - PTR *psinfo; + struct stab_info *sinfo; asection *stabsec; asection *stabstrsec; PTR *psecinfo; bfd_size_type *pstring_offset; { bfd_boolean first; - struct stab_info *sinfo; bfd_size_type count, amt; struct stab_section_info *secinfo; bfd_byte *stabbuf = NULL; @@ -227,30 +200,26 @@ _bfd_link_section_stabs (abfd, psinfo, s first = FALSE; - if (*psinfo == NULL) + if (sinfo->stabstr == NULL) { /* Initialize the stabs information we need to keep track of. */ first = TRUE; - amt = sizeof (struct stab_info); - *psinfo = (PTR) bfd_alloc (abfd, amt); - if (*psinfo == NULL) - goto error_return; - sinfo = (struct stab_info *) *psinfo; sinfo->strings = _bfd_stringtab_init (); if (sinfo->strings == NULL) goto error_return; /* Make sure the first byte is zero. */ (void) _bfd_stringtab_add (sinfo->strings, "", TRUE, TRUE); - if (! bfd_hash_table_init_n (&sinfo->includes.root, + if (! bfd_hash_table_init_n (&sinfo->includes, stab_link_includes_newfunc, 251)) goto error_return; sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr"); - sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING; + if (sinfo->stabstr == NULL) + goto error_return; + sinfo->stabstr->flags |= (SEC_HAS_CONTENTS | SEC_READONLY + | SEC_DEBUGGING | SEC_LINKER_CREATED); } - sinfo = (struct stab_info *) *psinfo; - /* Initialize the information we are going to store for this .stab section. */ @@ -411,8 +380,8 @@ _bfd_link_section_stabs (abfd, psinfo, s /* If we have already included a header file with the same value, then replaced this one with an N_EXCL symbol. */ - incl_entry = stab_link_includes_lookup (&sinfo->includes, string, - TRUE, TRUE); + incl_entry = (struct stab_link_includes_entry * ) + bfd_hash_lookup (&sinfo->includes, string, TRUE, TRUE); if (incl_entry == NULL) goto error_return; @@ -439,7 +408,7 @@ _bfd_link_section_stabs (abfd, psinfo, s /* This is the first time we have seen this header file with this set of stabs strings. */ t = ((struct stab_link_includes_totals *) - bfd_hash_allocate (&sinfo->includes.root, sizeof *t)); + bfd_hash_allocate (&sinfo->includes, sizeof *t)); if (t == NULL) goto error_return; t->sum_chars = sum_chars; @@ -718,20 +687,18 @@ _bfd_discard_section_stabs (abfd, stabse contents. */ bfd_boolean -_bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents) +_bfd_write_section_stabs (output_bfd, sinfo, stabsec, psecinfo, contents) bfd *output_bfd; - PTR *psinfo; + struct stab_info *sinfo; asection *stabsec; PTR *psecinfo; bfd_byte *contents; { - struct stab_info *sinfo; struct stab_section_info *secinfo; struct stab_excl_list *e; bfd_byte *sym, *tosym, *symend; bfd_size_type *pstridx; - sinfo = (struct stab_info *) *psinfo; secinfo = (struct stab_section_info *) *psecinfo; if (secinfo == NULL) @@ -792,17 +759,10 @@ _bfd_write_section_stabs (output_bfd, ps /* Write out the .stabstr section. */ bfd_boolean -_bfd_write_stab_strings (output_bfd, psinfo) +_bfd_write_stab_strings (output_bfd, sinfo) bfd *output_bfd; - PTR *psinfo; + struct stab_info *sinfo; { - struct stab_info *sinfo; - - sinfo = (struct stab_info *) *psinfo; - - if (sinfo == NULL) - return TRUE; - if (bfd_is_abs_section (sinfo->stabstr->output_section)) { /* The section was discarded from the link. */ @@ -824,7 +784,7 @@ _bfd_write_stab_strings (output_bfd, psi /* We no longer need the stabs information. */ _bfd_stringtab_free (sinfo->strings); - bfd_hash_table_free (&sinfo->includes.root); + bfd_hash_table_free (&sinfo->includes); return TRUE; } Index: opcodes/ppc-opc.c =================================================================== RCS file: /cvs/src/src/opcodes/ppc-opc.c,v retrieving revision 1.72 diff -u -p -r1.72 ppc-opc.c --- opcodes/ppc-opc.c 26 Jun 2004 08:32:12 -0000 1.72 +++ opcodes/ppc-opc.c 28 Jun 2004 13:17:54 -0000 @@ -998,11 +998,22 @@ insert_fxm (unsigned long insn, int dialect, const char **errmsg) { + /* If we're handling the mfocrf and mtocrf insns ensure that exactly + one bit of the mask field is set. */ + if ((insn & (1 << 20)) != 0) + { + if (value == 0 || (value & -value) != value) + { + *errmsg = _("invalid mask field"); + value = 0; + } + } + /* If the optional field on mfcr is missing that means we want to use the old form of the instruction that moves the whole cr. In that case we'll have VALUE zero. There doesn't seem to be a way to distinguish this from the case where someone writes mfcr %r3,0. */ - if (value == 0) + else if (value == 0) ; /* If only one bit of the FXM field is set, we can use the new form @@ -1028,7 +1039,7 @@ insert_fxm (unsigned long insn, static long extract_fxm (unsigned long insn, - int dialect, + int dialect ATTRIBUTE_UNUSED, int *invalid) { long mask = (insn >> 12) & 0xff; @@ -1036,14 +1047,9 @@ extract_fxm (unsigned long insn, /* Is this a Power4 insn? */ if ((insn & (1 << 20)) != 0) { - if ((dialect & PPC_OPCODE_POWER4) == 0) + /* Exactly one bit of MASK should be set. */ + if (mask == 0 || (mask & -mask) != mask) *invalid = 1; - else - { - /* Exactly one bit of MASK should be set. */ - if (mask == 0 || (mask & -mask) != mask) - *invalid = 1; - } } /* Check that non-power4 form of mfcr has a zero MASK. */ @@ -1681,11 +1687,12 @@ extract_tbr (unsigned long insn, #define XS_MASK XS (0x3f, 0x1ff, 1) /* A mask for the FXM version of an XFX form instruction. */ -#define XFXFXM_MASK (X_MASK | (1 << 11)) +#define XFXFXM_MASK (X_MASK | (1 << 11) | (1 << 20)) /* An XFX form instruction with the FXM field filled in. */ -#define XFXM(op, xop, fxm) \ - (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12)) +#define XFXM(op, xop, fxm, p4) \ + (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12) \ + | ((unsigned long)(p4) << 20)) /* An XFX form instruction with the SPR field filled in. */ #define XSPR(op, xop, spr) \ @@ -3227,6 +3234,7 @@ const struct powerpc_opcode powerpc_opco { "iseleq", X(31,79), X_MASK, PPCISEL, { RT, RA, RB } }, { "isel", XISEL(31,15), XISEL_MASK, PPCISEL, { RT, RA, RB, CRB } }, +{ "mfocrf", XFXM(31,19,0,1), XFXFXM_MASK, COM, { RT, FXM } }, { "mfcr", X(31,19), XRARB_MASK, NOPOWER4, { RT } }, { "mfcr", X(31,19), XFXFXM_MASK, POWER4, { RT, FXM4 } }, @@ -3382,7 +3390,8 @@ const struct powerpc_opcode powerpc_opco { "dcbtstlse",X(31,142),X_MASK, PPCCHLK64, { CT, RA, RB }}, -{ "mtcr", XFXM(31,144,0xff), XRARB_MASK, COM, { RS }}, +{ "mtocrf", XFXM(31,144,0,1), XFXFXM_MASK, COM, { FXM, RS } }, +{ "mtcr", XFXM(31,144,0xff,0), XRARB_MASK, COM, { RS }}, { "mtcrf", X(31,144), XFXFXM_MASK, COM, { FXM, RS } }, { "mtmsr", X(31,146), XRARB_MASK, COM, { RS } }, -- Alan Modra IBM OzLabs - Linux Technology Centre