This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: intermittent 0-length for .note.gnu.arm.ident
- From: James Lemke <jwlemke at wasabisystems dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Fri, 28 Apr 2006 09:52:46 -0400
- Subject: Re: intermittent 0-length for .note.gnu.arm.ident
- References: <1145470462.6397.89.camel@winch.thelemkes.ca>
On Wed, 2006-04-19 at 14:14 -0400, James Lemke wrote:
:
> I'm building a mingw x xscale-elf toolchain and some of the objects have
> normal .note.gnu.arm.ident sections (length 0x1c) and others have those
> section with length 0. The objects with 0-length sections seem to be
> normal otherwise. If I ignore linker warnings the DejaGNU tests run OK.
Jim Wilson suggested that it might be the amount of environment space in
use that was causing the difference. He was correct... if I consume
about 14K of env space, gas fails everytime. (binutils-2.15)
The problems centre on gas/subsegs.c:subseg_set_rest(). It keeps a
linked list of segment / section fragments that is sorted and searched
by the addresses of the frchainS structures.
There are two sources for the frchainS structures that are stored on
this list. Some, like "*UND*", are globally declared. Most, like .text
and .note.gnu.arm.ident, are dynamically allocated.
In the usual case, the statically allocated frchainS structures will
have a lower address than all of the malloc'd ones. However, in the
MinGW environment with a lot of environment space in use, the reverse is
true placing "*UND*" at the end of the list.
".note.gnu.arm.ident" is subsequently added to this list. In the normal
case the search hits the end of the list where it is appended. In the
failing case the new section is inserted before "*UND*". This works
properly except here:
#ifdef BFD_ASSEMBLER
{
segment_info_type *seginfo;
seginfo = seg_info (seg);
if (seginfo && seginfo->frchainP == frcP)
seginfo->frchainP = newP;
}
#endif
seginfo->frchainP is NULL for the new section. In the normal case frcP
is also NULL because we hit the end of the list and seginfo->frchainP is
updated. In the failing case frcP is a pointer to "*UND*". Therefore,
seginfo->frchainP remains NULL.
Therefore the section's contents are never written out.
It looks like this potential problem also exists in the FSF HEAD
sources.
My fix was this:
--- subsegs.c-orig 2006-04-27 13:44:49.893500000 +0000
+++ subsegs.c 2006-04-27 13:47:51.909125000 +0000
@@ -297,7 +297,7 @@ subseg_set_rest (segT seg, subsegT subse
{
segment_info_type *seginfo;
seginfo = seg_info (seg);
- if (seginfo && seginfo->frchainP == frcP)
+ if (seginfo && (!seginfo->frchainP || seginfo->frchainP ==
frcP))
seginfo->frchainP = newP;
}
#endif
Which I have tested with check-{binutils,gas,gcc} and works well. So
I'm looking for comments about the approach. Then I will make up a
patch for HEAD and test there.
Also, JimW suggested a different approach which might be better:
*** tc-arm.c.orig 2004-11-16 22:41:34.000000000 -0800
--- tc-arm.c 2006-04-27 16:22:43.664683290 -0700
*************** md_begin ()
*** 12073,12079 ****
--- 12073,12082 ----
asection * arm_arch;
const char * arch_string;
+ #if 0
arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
+ #endif
+ arm_arch = subseg_new (ARM_NOTE_SECTION, 0);
#ifdef OBJ_COFF
bfd_set_section_flags (stdoutput, arm_arch,
*************** md_begin ()
*** 12084,12090 ****
--- 12087,12095 ----
SEC_READONLY | SEC_HAS_CONTENTS);
#endif
arm_arch->output_section = arm_arch;
+ #if 0
subseg_set (arm_arch, 0);
+ #endif
switch (mach)
{
--
Jim Lemke jwlemke@wasabisystems.com Orillia, Ontario