public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Problem setting the CONTENTS flag
@ 2006-04-21 18:08 Andrew STUBBS
  2006-04-21 22:26 ` H. J. Lu
  0 siblings, 1 reply; 9+ messages in thread
From: Andrew STUBBS @ 2006-04-21 18:08 UTC (permalink / raw)
  To: binutils

Hi all,

I have encountered an error setting the CONTENTS and LOAD flags with 
relatively recent versions of objcopy/bfd.

Given the simplest program:

   int main()
   {
   }

and a simple linker script (not a real world example):

   SECTIONS
   {
     .text           :
     {
       *(.text .stub .text.* .gnu.linkonce.t.*)
     } =0
     .post_text_reserve :
     {
       /* Reserve some space so we can drop something in here later */
       . += 0x160;
     }
   }

compiled with:

   sh-elf-gcc test.c -T link2.ld -nostdlib

I get a file with the following properties:

   sh-elf-objdump -h a.out

   a.out:     file format elf32-shl

   Sections:
   Idx Name          Size      VMA       LMA       File off  Algn
     0 .text         0000000c  00000000  00000000  00000080  2**1
                     CONTENTS, ALLOC, LOAD, READONLY, CODE
     1 .post_text_reserve 00000160  0000000c  0000000c  0000008c  2**0
                     ALLOC
     2 .comment      00000043  00000000  00000000  0000008c  2**0
                     CONTENTS, READONLY

   sh-elf-readelf -S a.out

   There are 7 section headers, starting at offset 0x10c:

   Section Headers:
     [Nr] Name              Type            Addr     Off    Size   ES 
Flg Lk Inf Al
     [ 0]                   NULL            00000000 000000 000000 00 
    0   0  0
     [ 1] .text             PROGBITS        00000000 000080 00000c 00 
AX  0   0  2
     [ 2] .post_text_reserv NOBITS          0000000c 00008c 000160 00 
WA  0   0  1
     [ 3] .comment          PROGBITS        00000000 00008c 000043 00 
    0   0  1
     [ 4] .shstrtab         STRTAB          00000000 0000cf 00003d 00 
    0   0  1
     [ 5] .symtab           SYMTAB          00000000 000224 0000b0 10 
    6   8  4
     [ 6] .strtab           STRTAB          00000000 0002d4 00001c 00 
    0   0  1
   Key to Flags:
     W (write), A (alloc), X (execute), M (merge), S (strings)
     I (info), L (link order), G (group), x (unknown)
     O (extra OS processing required) o (OS specific), p (processor 
specific)

All is good so far.

Now I want to add the missing flags to the .post_test_reserve (the next 
step would be to actually add some data).

So I do the following:

   sh-elf-objcopy --set-section-flags 
.post_text_reserve=contents,alloc,load,readonly,code a.out a2.out

Now I get:

   sh-elf-objdump -h a2.out

   a2.out:     file format elf32-shl

   Sections:
   Idx Name          Size      VMA       LMA       File off  Algn
     0 .text         0000000c  00000000  00000000  00000080  2**1
                     CONTENTS, ALLOC, LOAD, READONLY, CODE
     1 .post_text_reserve 00000160  0000000c  0000000c  0000008c  2**0
                     ALLOC, READONLY, CODE
     2 .comment      00000043  00000000  00000000  000001ec  2**0
                     CONTENTS, READONLY

   sh-elf-readelf -S a2.out

   There are 7 section headers, starting at offset 0x26c:

   Section Headers:
     [Nr] Name              Type            Addr     Off    Size   ES 
Flg Lk Inf Al
     [ 0]                   NULL            00000000 000000 000000 00 
    0   0  0
     [ 1] .text             PROGBITS        00000000 000080 00000c 00 
AX  0   0  2
     [ 2] .post_text_reserv NOBITS          0000000c 00008c 000160 00 
AX  0   0  1
     [ 3] .comment          PROGBITS        00000000 0001ec 000043 00 
    0   0  1
     [ 4] .shstrtab         STRTAB          00000000 00022f 00003d 00 
    0   0  1
     [ 5] .symtab           SYMTAB          00000000 000384 0000b0 10 
    6   8  4
     [ 6] .strtab           STRTAB          00000000 000434 00001c 00 
    0   0  1
   Key to Flags:
     W (write), A (alloc), X (execute), M (merge), S (strings)
     I (info), L (link order), G (group), x (unknown)
     O (extra OS processing required) o (OS specific), p (processor 
specific)

The READONLY and CODE flags have been added, but the CONTENTS and LOAD 
flags remain absent. Also, the ELF section type remains NOBITS, where it 
ought to be PROGBITS.

After some examination of the source code and the ELF format I find that 
the CONTENTS and LOAD flags are in fact implicit in the PROGBITS section 
type, so all the above problems come down to the same issue.

AFAICT, the section type is set in elf_fake_sections(), but only if 
there is no existing type (sh_type != SHT_NULL). In this case the 
section already has a type - presumably loaded from the input file - and 
therefore does not have its type set. Thus the change to the CONTENTS 
and LOAD flags is ignored.

The documentation says:

  `--set-section-flags SECTION=FLAGS'
       Set the flags for the named section.  The FLAGS argument is a
       comma separated string of flag names.  The recognized names are
       `alloc', `contents', `load', `noload', `readonly', `code', `data',
       `rom', `share', and `debug'.  You can set the `contents' flag for
       a section which does not have contents, but it is not meaningful
       to clear the `contents' flag of a section which does have
       contents-just remove the section instead.  Not all flags are
       meaningful for all object file formats.

What I want to do - set the contents flag - is explicitly described.

This used to work in 2.15.94.0.1 from kernel.org, but it does not work 
in 2.16.91.0.5, also from kernel.org. Nor does it work in CVS HEAD.

I feel sure that I could bodge something up to fix this problem, but I 
do not know what the correct fix would be.

Any help would be appreciated.

Andrew Stubbs

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem setting the CONTENTS flag
  2006-04-21 18:08 Problem setting the CONTENTS flag Andrew STUBBS
@ 2006-04-21 22:26 ` H. J. Lu
  2006-04-21 23:32   ` Andreas Schwab
  2006-04-23 22:13   ` H. J. Lu
  0 siblings, 2 replies; 9+ messages in thread
From: H. J. Lu @ 2006-04-21 22:26 UTC (permalink / raw)
  To: Andrew STUBBS; +Cc: binutils

On Fri, Apr 21, 2006 at 01:58:08PM +0100, Andrew STUBBS wrote:
> Hi all,
> 
> I have encountered an error setting the CONTENTS and LOAD flags with 
> relatively recent versions of objcopy/bfd.
> 

Could you please open a bug report with a simple testcase? This patch
should work.

Thanks.


H.J.
----
2006-04-21  H.J. Lu  <hongjiu.lu@intel.com>

	* elf.c (_bfd_elf_new_section_hook): Don't set section ELF type
	and flags if its BFD flags has been set.

--- bfd/elf.c.copy	2006-04-21 07:00:02.000000000 -0700
+++ bfd/elf.c	2006-04-21 07:32:26.000000000 -0700
@@ -2487,10 +2487,11 @@ _bfd_elf_new_section_hook (bfd *abfd, as
   bed = get_elf_backend_data (abfd);
   sec->use_rela_p = bed->default_use_rela_p;
 
-  /* When we read a file, we don't need section type and flags unless
-     it is a linker created section.  They will be overridden in
-     _bfd_elf_make_section_from_shdr anyway.  */
-  if (abfd->direction != read_direction
+  /* When we read a file or section BFD flags has been set, we don't
+     need section type and flags unless it is a linker created section.
+     They will be overridden in _bfd_elf_make_section_from_shdr
+     anyway.  */
+  if ((!sec->flags && abfd->direction != read_direction)
       || (sec->flags & SEC_LINKER_CREATED) != 0)
     {
       ssect = (*bed->get_sec_type_attr) (abfd, sec);

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem setting the CONTENTS flag
  2006-04-21 22:26 ` H. J. Lu
@ 2006-04-21 23:32   ` Andreas Schwab
  2006-04-23 22:13   ` H. J. Lu
  1 sibling, 0 replies; 9+ messages in thread
From: Andreas Schwab @ 2006-04-21 23:32 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Andrew STUBBS, binutils

"H. J. Lu" <hjl@lucon.org> writes:

> +  /* When we read a file or section BFD flags has been set, we don't

s/has/have/

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem setting the CONTENTS flag
  2006-04-21 22:26 ` H. J. Lu
  2006-04-21 23:32   ` Andreas Schwab
@ 2006-04-23 22:13   ` H. J. Lu
  2006-04-24 19:55     ` Andrew STUBBS
  2006-04-25 16:37     ` Nick Clifton
  1 sibling, 2 replies; 9+ messages in thread
From: H. J. Lu @ 2006-04-23 22:13 UTC (permalink / raw)
  To: Andrew STUBBS; +Cc: binutils

On Fri, Apr 21, 2006 at 07:35:58AM -0700, H. J. Lu wrote:
> On Fri, Apr 21, 2006 at 01:58:08PM +0100, Andrew STUBBS wrote:
> > Hi all,
> > 
> > I have encountered an error setting the CONTENTS and LOAD flags with 
> > relatively recent versions of objcopy/bfd.
> > 
> 
> Could you please open a bug report with a simple testcase? This patch
> should work.
> 
> Thanks.
> 
> 

Here is an updated patch.


H.J.
----
2006-04-21  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/2593
	* elf.c (_bfd_elf_new_section_hook): Don't set section ELF type
	and flags if its BFD flags has been set.
	(_bfd_elf_init_private_section_data): Don't copy the output ELF
	section type from input if it has been set to something
	different.

--- bfd/elf.c.copy	2006-04-21 07:00:02.000000000 -0700
+++ bfd/elf.c	2006-04-21 16:15:41.000000000 -0700
@@ -2487,10 +2487,11 @@ _bfd_elf_new_section_hook (bfd *abfd, as
   bed = get_elf_backend_data (abfd);
   sec->use_rela_p = bed->default_use_rela_p;
 
-  /* When we read a file, we don't need section type and flags unless
-     it is a linker created section.  They will be overridden in
-     _bfd_elf_make_section_from_shdr anyway.  */
-  if (abfd->direction != read_direction
+  /* When we read a file or section BFD flags have been set, we don't
+     need section type and flags unless it is a linker created section.
+     They will be overridden in _bfd_elf_make_section_from_shdr
+     anyway.  */
+  if ((!sec->flags && abfd->direction != read_direction)
       || (sec->flags & SEC_LINKER_CREATED) != 0)
     {
       ssect = (*bed->get_sec_type_attr) (abfd, sec);
@@ -5906,9 +5907,9 @@ _bfd_elf_init_private_section_data (bfd 
       || obfd->xvec->flavour != bfd_target_elf_flavour)
     return TRUE;
 
-  /* FIXME: What if the output ELF section type has been set to
-     something different?  */
-  if (elf_section_type (osec) == SHT_NULL)
+  /* Don't copy the output ELF section type from input if it has been
+     set to something different.  */
+  if (osec->flags == isec->flags || !osec->flags)
     elf_section_type (osec) = elf_section_type (isec);
 
   /* Set things up for objcopy and relocatable link.  The output

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem setting the CONTENTS flag
  2006-04-23 22:13   ` H. J. Lu
@ 2006-04-24 19:55     ` Andrew STUBBS
  2006-04-25 16:37     ` Nick Clifton
  1 sibling, 0 replies; 9+ messages in thread
From: Andrew STUBBS @ 2006-04-24 19:55 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

H. J. Lu wrote:
> Here is an updated patch.

Thanks, this is exactly what I need.

Andrew

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem setting the CONTENTS flag
  2006-04-23 22:13   ` H. J. Lu
  2006-04-24 19:55     ` Andrew STUBBS
@ 2006-04-25 16:37     ` Nick Clifton
  2006-04-26  0:21       ` PATCH: binutils/2593: " H. J. Lu
  2006-04-26  0:39       ` H. J. Lu
  1 sibling, 2 replies; 9+ messages in thread
From: Nick Clifton @ 2006-04-25 16:37 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Andrew STUBBS, binutils

HI H.J.

> Here is an updated patch.

There are a couple of minor problems with this version of the patch:

> +  /* When we read a file or section BFD flags have been set, we don't
> +     need section type and flags unless it is a linker created section.
> +     They will be overridden in _bfd_elf_make_section_from_shdr
> +     anyway.  */
> +  if ((!sec->flags && abfd->direction != read_direction)
>        || (sec->flags & SEC_LINKER_CREATED) != 0)

I think that the comment could be reworded to be clearer.  For example:

   A section without any flags or with the SEC_LINKER_CREATED flag
   must have its type and other flags set.  Skip this for sections
   with no flags that have been read in, as this state must have been
   requested by the user, and it will be overridden by
   _bfd_elf_make_section_from_shdr anyway.

> -  /* FIXME: What if the output ELF section type has been set to
> -     something different?  */
> -  if (elf_section_type (osec) == SHT_NULL)
> +  /* Don't copy the output ELF section type from input if it has been
> +     set to something different.  */
> +  if (osec->flags == isec->flags || !osec->flags)
>      elf_section_type (osec) = elf_section_type (isec);

A section's type is not determined by its flags.  Therefore it seems to 
be counter-intuitive to be testing the flags when we are concerned about 
the type.   Also what happens if the output sections flags have been set 
to something other than the input section's flags, but the output 
section's type is SHT_NULL ?  According to the ELF spec this would mean 
that the flags are undefined as well.

I think that for this part of the patch the comment ought to be reworded 
and you ought to test for SHT_NULL and either change it or issue an 
error message.  eg:

   /* Copy the output ELF section type from the input section type if
      the output section flags were copied from the input, or if the
      output section has no type or flags.  */
   if (osec->flags == isec->flags
       || osec->flags == 0
       || elf_section_type (osec) == SHT_NULL)
    elf_section_type (osec) = elf_section_type (isec);


Cheers
   Nick


^ permalink raw reply	[flat|nested] 9+ messages in thread

* PATCH: binutils/2593: Problem setting the CONTENTS flag
  2006-04-25 16:37     ` Nick Clifton
@ 2006-04-26  0:21       ` H. J. Lu
  2006-04-26 12:16         ` Nick Clifton
  2006-04-26  0:39       ` H. J. Lu
  1 sibling, 1 reply; 9+ messages in thread
From: H. J. Lu @ 2006-04-26  0:21 UTC (permalink / raw)
  To: Nick Clifton; +Cc: Andrew STUBBS, binutils

On Tue, Apr 25, 2006 at 04:20:53PM +0100, Nick Clifton wrote:
> HI H.J.
> 
> >Here is an updated patch.
> 
> There are a couple of minor problems with this version of the patch:
> 

I will look into them.

Here is a patch to add 2 tests for objcopy. The second test both
fail on i386-aout and i386-coff. They don't set .text to DATA.


H.J.
----
2006-04-25  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/2593
	* binutils-all/copy-1.d: New file.
	* binutils-all/copy-1.s: Likewise.
	* binutils-all/copy-2.d: Likewise.

	* binutils-all/objcopy.exp: Add run_dump_test "copy-1" and
	run_dump_test "copy-2".

	* lib/utils-lib.exp (run_dump_test): New.
	(slurp_options): Likewise.
	(regexp_diff): Likewise.
	(file_contents): Likewise.
	(verbose_eval): Likewise.

--- binutils/testsuite/binutils-all/copy-1.d.copy	2006-04-25 07:33:44.000000000 -0700
+++ binutils/testsuite/binutils-all/copy-1.d	2006-04-25 12:38:51.000000000 -0700
@@ -0,0 +1,13 @@
+#PROG: objcopy
+#objdump: -h
+#objcopy: --set-section-flags .post_text_reserve=contents,alloc,load,readonly,code
+#name: copy with seting section flags 1
+
+.*: +file format .*
+
+Sections:
+Idx.*
+#...
+  [0-9]* .post_text_reserve.*
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+#...
--- binutils/testsuite/binutils-all/copy-1.s.copy	2006-04-25 07:02:44.000000000 -0700
+++ binutils/testsuite/binutils-all/copy-1.s	2006-04-25 12:35:54.000000000 -0700
@@ -0,0 +1,6 @@
+	.globl text_symbol
+	.text
+text_symbol:	
+	.long	1
+	.section .post_text_reserve,"w", %nobits
+	.space 160
--- binutils/testsuite/binutils-all/copy-2.d.copy	2006-04-25 12:39:14.000000000 -0700
+++ binutils/testsuite/binutils-all/copy-2.d	2006-04-25 12:59:38.000000000 -0700
@@ -0,0 +1,14 @@
+#PROG: objcopy
+#objdump: -h
+#objcopy: --set-section-flags .text=alloc,data
+#name: copy with seting section flags 2
+#source: bintest.s
+
+.*: +file format .*
+
+Sections:
+Idx.*
+#...
+  [0-9]* .text.*
+                  CONTENTS, ALLOC, LOAD, RELOC, DATA
+#...
--- binutils/testsuite/binutils-all/objcopy.exp.copy	2006-04-24 15:36:20.000000000 -0700
+++ binutils/testsuite/binutils-all/objcopy.exp	2006-04-25 12:41:56.000000000 -0700
@@ -724,3 +724,6 @@ if [is_elf_format] {
     objcopy_test "ELF unknown section type" unknown.s
     objcopy_test_readelf "ELF group" group.s
 }
+
+run_dump_test "copy-1"
+run_dump_test "copy-2"
--- binutils/testsuite/lib/utils-lib.exp.copy	2006-04-14 14:44:43.000000000 -0700
+++ binutils/testsuite/lib/utils-lib.exp	2006-04-25 12:48:18.000000000 -0700
@@ -167,3 +167,490 @@ proc exe_ext {} {
         return ""
     }
 }
+
+# Copied and modified from gas.
+
+# run_dump_test FILE (optional:) EXTRA_OPTIONS
+#
+# Assemble a .s file, then run some utility on it and check the output.
+#
+# There should be an assembly language file named FILE.s in the test
+# suite directory, and a pattern file called FILE.d.  `run_dump_test'
+# will assemble FILE.s, run some tool like `objdump', `objcopy', or
+# `nm' on the .o file to produce textual output, and then analyze that
+# with regexps.  The FILE.d file specifies what program to run, and
+# what to expect in its output.
+#
+# The FILE.d file begins with zero or more option lines, which specify
+# flags to pass to the assembler, the program to run to dump the
+# assembler's output, and the options it wants.  The option lines have
+# the syntax:
+#
+#         # OPTION: VALUE
+#
+# OPTION is the name of some option, like "name" or "objdump", and
+# VALUE is OPTION's value.  The valid options are described below.
+# Whitespace is ignored everywhere, except within VALUE.  The option
+# list ends with the first line that doesn't match the above syntax.
+# However, a line within the options that begins with a #, but doesn't
+# have a recognizable option name followed by a colon, is considered a
+# comment and entirely ignored.
+#
+# The optional EXTRA_OPTIONS argument to `run_dump_test' is a list of
+# two-element lists.  The first element of each is an option name, and
+# the second additional arguments to be added on to the end of the
+# option list as given in FILE.d.  (If omitted, no additional options
+# are added.)
+#
+# The interesting options are:
+#
+#   name: TEST-NAME
+#	The name of this test, passed to DejaGNU's `pass' and `fail'
+#       commands.  If omitted, this defaults to FILE, the root of the
+#       .s and .d files' names.
+#
+#   as: FLAGS
+#	When assembling FILE.s, pass FLAGS to the assembler.
+#
+#   PROG: PROGRAM-NAME
+#       The name of the program to run to analyze the .o file produced
+#       by the assembler.  This can be omitted; run_dump_test will guess
+#       which program to run by seeing which of the flags options below
+#	is present.
+#
+#   objdump: FLAGS
+#   nm: FLAGS
+#   objcopy: FLAGS
+#	Use the specified program to analyze the .o file, and pass it
+#	FLAGS, in addition to the .o file name.  Note that they are run
+#	with LC_ALL=C in the environment to give consistent sorting
+#	of symbols.
+#
+#   source: SOURCE
+#	Assemble the file SOURCE.s.  If omitted, this defaults to FILE.s.
+#       This is useful if several .d files want to share a .s file.
+#
+#   target: GLOBS...
+#       Run this test only on a specified list of targets.  More precisely,
+#       each glob in the space-separated list is passed to "istarget"; if
+#       it evaluates true for any of them, the test will be run, otherwise
+#       it will be marked unsupported.
+#
+#   not-target: GLOBS...
+#       Do not run this test on a specified list of targets.  Again,
+#       the each glob in the space-separated list is passed to
+#       "istarget", and the test is run if it evaluates *false* for
+#       *all* of them.  Otherwise it will be marked unsupported.
+#
+#   skip: GLOBS...
+#   not-skip: GLOBS...
+#       These are exactly the same as "not-target" and "target",
+#       respectively, except that they do nothing at all if the check
+#       fails.  They should only be used in groups, to construct a single
+#       test which is run on all targets but with variant options or
+#       expected output on some targets.  (For example, see
+#       gas/arm/inst.d and gas/arm/wince_inst.d.)
+#
+#   error: REGEX
+#	An error with message matching REGEX must be emitted for the test
+#	to pass.  The PROG, objdump, nm and objcopy options have no
+#	meaning and need not supplied if this is present.
+#
+#   warning: REGEX
+#	Expect a gas warning matching REGEX.  It is an error to issue
+#	both "error" and "warning".
+#
+#   stderr: FILE
+#       FILE contains regexp lines to be matched against the diagnostic
+#       output of the assembler.  This does not preclude the use of
+#       PROG, nm, objdump, or objcopy.
+#
+#   error-output: FILE
+#       Means the same as 'stderr', but also indicates that the assembler
+#       is expected to exit unsuccessfully (therefore PROG, objdump, nm,
+#       and objcopy have no meaning and should not be supplied).
+#
+# Each option may occur at most once.
+#
+# After the option lines come regexp lines.  `run_dump_test' calls
+# `regexp_diff' to compare the output of the dumping tool against the
+# regexps in FILE.d.  `regexp_diff' is defined later in this file; see
+# further comments there.
+
+proc run_dump_test { name {extra_options {}} } {
+    global subdir srcdir
+    global OBJDUMP NM OBJCOPY READELF
+    global OBJDUMPFLAGS NMFLAGS OBJCOPYFLAGS READELFFLAGS
+    global host_triplet
+    global env
+    global copyfile
+    global tempfile
+
+    if [string match "*/*" $name] {
+	set file $name
+	set name [file tail $name]
+    } else {
+	set file "$srcdir/$subdir/$name"
+    }
+    set opt_array [slurp_options "${file}.d"]
+    if { $opt_array == -1 } {
+	perror "error reading options from $file.d"
+	unresolved $subdir/$name
+	return
+    }
+    set opts(objdump) {}
+    set opts(nm) {}
+    set opts(objcopy) {}
+    set opts(strip) {}
+    set opts(readelf) {}
+    set opts(name) {}
+    set opts(PROG) {}
+    set opts(DUMPPROG) {}
+    set opts(source) {}
+    set opts(target) {}
+    set opts(not-target) {}
+    set opts(skip) {}
+    set opts(not-skip) {}
+
+    foreach i $opt_array {
+	set opt_name [lindex $i 0]
+	set opt_val [lindex $i 1]
+	if ![info exists opts($opt_name)] {
+	    perror "unknown option $opt_name in file $file.d"
+	    unresolved $subdir/$name
+	    return
+	}
+	if [string length $opts($opt_name)] {
+	    perror "option $opt_name multiply set in $file.d"
+	    unresolved $subdir/$name
+	    return
+	}
+	set opts($opt_name) $opt_val
+    }
+
+    foreach i $extra_options {
+	set opt_name [lindex $i 0]
+	set opt_val [lindex $i 1]
+	if ![info exists opts($opt_name)] {
+	    perror "unknown option $opt_name given in extra_opts"
+	    unresolved $subdir/$name
+	    return
+	}
+	# add extra option to end of existing option, adding space
+	# if necessary.
+	if [string length $opts($opt_name)] {
+	    append opts($opt_name) " "
+	}
+	append opts($opt_name) $opt_val
+    }
+
+    if { $opts(name) == "" } {
+	set testname "$subdir/$name"
+    } else {
+	set testname $opts(name)
+    }
+    verbose "Testing $testname"
+
+    if {$opts(PROG) == ""} {
+	perror "program isn't set in $file.d"
+	unresolved $testname
+	return
+    }
+
+    switch -- $opts(PROG) {
+	objcopy	{ set program objcopy }
+	objdump	{ set program objdump }
+	nm	{ set program nm }
+	readelf	{ set program readelf }
+	default	{
+	    perror "unrecognized program option $opts(PROG) in $file.d"
+	    unresolved $testname
+	    return }
+    }
+
+    set dumpprogram ""
+    if { $opts(DUMPPROG) != "" } {
+	switch -- $opts(DUMPPROG) {
+	    objdump	{ set dumpprogram objdump }
+	    nm		{ set dumpprogram nm }
+	    readelf	{ set dumpprogram readelf }
+	    default	{
+		perror "unrecognized dump program option $opts(DUMPPROG) in $file.d"
+		unresolved $testname
+		return }
+	}
+    } else {
+	# Guess which program to run, by seeing which option was specified.
+	foreach p {objdump nm readelf} {
+	    if {$opts($p) != ""} {
+		if {$dumpprogram != ""} {
+		    perror "ambiguous dump program in $file.d"
+		    unresolved $testname
+		    return
+		} else {
+		    set dumpprogram $p
+		}
+	    }
+	}
+    }
+
+    # Handle skipping the test on specified targets.
+    # You can have both skip/not-skip and target/not-target, but you can't
+    # have both skip and not-skip, or target and not-target, in the same file.
+    if { $opts(skip) != "" } then {
+	if { $opts(not-skip) != "" } then {
+	    perror "$testname: mixing skip and not-skip directives is invalid"
+	    unresolved $testname
+	    return
+	}
+	foreach glob $opts(skip) {
+	    if {[istarget $glob]} { return }
+	}
+    }
+    if { $opts(not-skip) != "" } then {
+	set skip 1
+	foreach glob $opts(not-skip) {
+	    if {[istarget $glob]} { 
+		set skip 0
+		break
+	    }
+	}
+	if {$skip} { return }
+    }
+    if { $opts(target) != "" } then {
+	if { $opts(not-target) != "" } then {
+	    perror "$testname: mixing target and not-target directives is invalid"
+	    unresolved $testname
+	    return
+	}
+	set skip 1
+	foreach glob $opts(target) {
+	    if {[istarget $glob]} { 
+		set skip 0
+		break
+	    }
+	}
+	if {$skip} { 
+	    unsupported $testname
+	    return 
+	}
+    }
+    if { $opts(not-target) != "" } then {
+	foreach glob $opts(not-target) {
+	    if {[istarget $glob]} {
+		unsupported $testname
+		return 
+	    }
+	}
+    }
+
+    if { $opts(source) == "" } {
+	set srcfile ${file}.s
+    } else {
+	set srcfile $srcdir/$subdir/$opts(source)
+    }
+
+    set exec_output [binutils_assemble ${srcfile} tmpdir/bintest.o]
+    if [string match "" $exec_output] then {
+	send_log "$exec_output\n"
+	verbose "$exec_output"
+	fail $testname
+	return
+    }
+
+    set progopts1 $opts($program)
+    eval set progopts \$[string toupper $program]FLAGS
+    eval set binary \$[string toupper $program]
+
+    set exec_output [binutils_run $binary "$progopts $progopts1 $tempfile ${copyfile}.o"]
+    if ![string match "" $exec_output] {
+	send_log "$exec_output\n"
+	verbose "$exec_output"
+	fail $testname
+	return
+    }
+
+    set progopts1 $opts($dumpprogram)
+    eval set progopts \$[string toupper $dumpprogram]FLAGS
+    eval set binary \$[string toupper $dumpprogram]
+
+    if { [which $binary] == 0 } {
+	untested $testname
+	return
+    }
+
+    verbose "running $binary $progopts $progopts1" 3
+
+    set cmd "$binary $progopts $progopts1 ${copyfile}.o > tmpdir/dump.out"
+
+    # Ensure consistent sorting of symbols
+    if {[info exists env(LC_ALL)]} {
+	set old_lc_all $env(LC_ALL)
+    }
+    set env(LC_ALL) "C"
+    send_log "$cmd\n"
+    catch "exec $cmd" comp_output
+    if {[info exists old_lc_all]} {
+	set env(LC_ALL) $old_lc_all
+    } else {
+	unset env(LC_ALL)
+    }
+    set comp_output [prune_warnings $comp_output]
+    if ![string match "" $comp_output] then {
+	send_log "$comp_output\n"
+	fail $testname
+	return
+    }
+
+    verbose_eval {[file_contents "tmpdir/dump.out"]} 3
+    if { [regexp_diff "tmpdir/dump.out" "${file}.d"] } then {
+	fail $testname
+	verbose "output is [file_contents "tmpdir/dump.out"]" 2
+	return
+    }
+
+    pass $testname
+}
+
+proc slurp_options { file } {
+    if [catch { set f [open $file r] } x] {
+	#perror "couldn't open `$file': $x"
+	perror "$x"
+	return -1
+    }
+    set opt_array {}
+    # whitespace expression
+    set ws  {[ 	]*}
+    set nws {[^ 	]*}
+    # whitespace is ignored anywhere except within the options list;
+    # option names are alphabetic plus dash
+    set pat "^#${ws}(\[a-zA-Z-\]*)$ws:${ws}(.*)$ws\$"
+    while { [gets $f line] != -1 } {
+	set line [string trim $line]
+	# Whitespace here is space-tab.
+	if [regexp $pat $line xxx opt_name opt_val] {
+	    # match!
+	    lappend opt_array [list $opt_name $opt_val]
+	} elseif {![regexp "^#" $line ]} {
+	    break
+	}
+    }
+    close $f
+    return $opt_array
+}
+
+# regexp_diff, based on simple_diff taken from ld test suite
+#	compares two files line-by-line
+#	file1 contains strings, file2 contains regexps and #-comments
+#	blank lines are ignored in either file
+#	returns non-zero if differences exist
+#
+proc regexp_diff { file_1 file_2 } {
+
+    set eof -1
+    set end_1 0
+    set end_2 0
+    set differences 0
+    set diff_pass 0
+
+    if [file exists $file_1] then {
+	set file_a [open $file_1 r]
+    } else {
+	perror "$file_1 doesn't exist"
+	return 1
+    }
+
+    if [file exists $file_2] then {
+	set file_b [open $file_2 r]
+    } else {
+	perror "$file_2 doesn't exist"
+	close $file_a
+	return 1
+    }
+
+    verbose " Regexp-diff'ing: $file_1 $file_2" 2
+
+    while { 1 } {
+	set line_a ""
+	set line_b ""
+	while { [string length $line_a] == 0 } {
+	    if { [gets $file_a line_a] == $eof } {
+		set end_1 1
+		break
+	    }
+	}
+	while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
+	    if [ string match "#pass" $line_b ] {
+		set end_2 1
+		set diff_pass 1
+		break
+	    } elseif [ string match "#..." $line_b ] {
+		if { [gets $file_b line_b] == $eof } {
+		    set end_2 1
+		    set diff_pass 1
+		    break
+		}
+		verbose "looking for \"^$line_b$\"" 3
+		while { ![regexp "^$line_b$" "$line_a"] } {
+		    verbose "skipping    \"$line_a\"" 3
+		    if { [gets $file_a line_a] == $eof } {
+			set end_1 1
+			break
+		    }
+		}
+		break
+	    }
+	    if { [gets $file_b line_b] == $eof } {
+		set end_2 1
+		break
+	    }
+	}
+
+        if { $diff_pass } {
+            break
+        } elseif { $end_1 && $end_2 } {
+            break
+        } elseif { $end_1 } {
+            send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
+            verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
+            set differences 1
+            break
+        } elseif { $end_2 } {
+            send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
+            verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
+            set differences 1
+            break
+        } else {
+            verbose "regexp \"^$line_b$\"\nline   \"$line_a\"" 3
+            if ![regexp "^$line_b$" "$line_a"] {
+		send_log "regexp_diff match failure\n"
+		send_log "regexp \"^$line_b$\"\nline   \"$line_a\"\n"
+		verbose "regexp_diff match failure\n" 3
+		set differences 1
+            }
+        }
+    }
+
+    if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
+	send_log "$file_1 and $file_2 are different lengths\n"
+	verbose "$file_1 and $file_2 are different lengths" 3
+	set differences 1
+    }
+
+    close $file_a
+    close $file_b
+
+    return $differences
+}
+
+proc file_contents { filename } {
+    set file [open $filename r]
+    set contents [read $file]
+    close $file
+    return $contents
+}
+
+proc verbose_eval { expr { level 1 } } {
+    global verbose
+    if $verbose>$level then { eval verbose "$expr" $level }
+}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problem setting the CONTENTS flag
  2006-04-25 16:37     ` Nick Clifton
  2006-04-26  0:21       ` PATCH: binutils/2593: " H. J. Lu
@ 2006-04-26  0:39       ` H. J. Lu
  1 sibling, 0 replies; 9+ messages in thread
From: H. J. Lu @ 2006-04-26  0:39 UTC (permalink / raw)
  To: Nick Clifton; +Cc: Andrew STUBBS, binutils

On Tue, Apr 25, 2006 at 04:20:53PM +0100, Nick Clifton wrote:
> HI H.J.
> 
> >Here is an updated patch.
> 
> There are a couple of minor problems with this version of the patch:
> 
> >+  /* When we read a file or section BFD flags have been set, we don't
> >+     need section type and flags unless it is a linker created section.
> >+     They will be overridden in _bfd_elf_make_section_from_shdr
> >+     anyway.  */
> >+  if ((!sec->flags && abfd->direction != read_direction)
> >       || (sec->flags & SEC_LINKER_CREATED) != 0)
> 
> I think that the comment could be reworded to be clearer.  For example:
> 
>   A section without any flags or with the SEC_LINKER_CREATED flag
>   must have its type and other flags set.  Skip this for sections
>   with no flags that have been read in, as this state must have been
>   requested by the user, and it will be overridden by
>   _bfd_elf_make_section_from_shdr anyway.
> >-  /* FIXME: What if the output ELF section type has been set to
> >-     something different?  */
> >-  if (elf_section_type (osec) == SHT_NULL)
> >+  /* Don't copy the output ELF section type from input if it has been
> >+     set to something different.  */
> >+  if (osec->flags == isec->flags || !osec->flags)
> >     elf_section_type (osec) = elf_section_type (isec);
> 
> A section's type is not determined by its flags.  Therefore it seems to 

It is. See elf_fake_sections.

> be counter-intuitive to be testing the flags when we are concerned about 
> the type.   Also what happens if the output sections flags have been set 
> to something other than the input section's flags, but the output 
> section's type is SHT_NULL ?  According to the ELF spec this would mean 
> that the flags are undefined as well.
> 
> I think that for this part of the patch the comment ought to be reworded 
> and you ought to test for SHT_NULL and either change it or issue an 
> error message.  eg:
> 
>   /* Copy the output ELF section type from the input section type if
>      the output section flags were copied from the input, or if the
>      output section has no type or flags.  */
>   if (osec->flags == isec->flags
>       || osec->flags == 0
>       || elf_section_type (osec) == SHT_NULL)
>    elf_section_type (osec) = elf_section_type (isec);
> 
> 
> Cheers
>   Nick
> 


I updated the comments.


H.J.
----
2006-04-21  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/2593
	* elf.c (_bfd_elf_new_section_hook): Don't set section ELF type
	and flags if its BFD flags have been set.
	(_bfd_elf_init_private_section_data): Don't copy the output ELF
	section type from input if it has been set to something
	different.

--- bfd/elf.c.flags	2006-04-24 20:11:58.000000000 -0700
+++ bfd/elf.c	2006-04-25 13:17:24.000000000 -0700
@@ -2487,10 +2487,13 @@ _bfd_elf_new_section_hook (bfd *abfd, as
   bed = get_elf_backend_data (abfd);
   sec->use_rela_p = bed->default_use_rela_p;
 
-  /* When we read a file, we don't need section type and flags unless
-     it is a linker created section.  They will be overridden in
-     _bfd_elf_make_section_from_shdr anyway.  */
-  if (abfd->direction != read_direction
+  /* When we read a file, we don't need to set ELF section type and
+     flags.  They will be overridden in _bfd_elf_make_section_from_shdr
+     anyway.  We will set ELF section type and flags for all linker
+     created sections.  If user specifies BFD section flags, we will
+     set ELF section type and flags based on BFD section flags in
+     elf_fake_sections.  */
+  if ((!sec->flags && abfd->direction != read_direction)
       || (sec->flags & SEC_LINKER_CREATED) != 0)
     {
       ssect = (*bed->get_sec_type_attr) (abfd, sec);
@@ -5906,9 +5909,11 @@ _bfd_elf_init_private_section_data (bfd 
       || obfd->xvec->flavour != bfd_target_elf_flavour)
     return TRUE;
 
-  /* FIXME: What if the output ELF section type has been set to
-     something different?  */
-  if (elf_section_type (osec) == SHT_NULL)
+  /* Don't copy the output ELF section type from input if the
+     output BFD section flags has been set to something different.
+     elf_fake_sections will set ELF section type based on BFD
+     section flags.  */
+  if (osec->flags == isec->flags || !osec->flags)
     elf_section_type (osec) = elf_section_type (isec);
 
   /* Set things up for objcopy and relocatable link.  The output

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: binutils/2593: Problem setting the CONTENTS flag
  2006-04-26  0:21       ` PATCH: binutils/2593: " H. J. Lu
@ 2006-04-26 12:16         ` Nick Clifton
  0 siblings, 0 replies; 9+ messages in thread
From: Nick Clifton @ 2006-04-26 12:16 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Andrew STUBBS, binutils

Hi H.J.

>> There are a couple of minor problems with this version of the patch:
> I will look into them.

Thanks.

> Here is a patch to add 2 tests for objcopy. The second test both
> fail on i386-aout and i386-coff. They don't set .text to DATA.

This patch (to add the tests) is approved.

Cheers
   Nick

> 2006-04-25  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	PR binutils/2593
> 	* binutils-all/copy-1.d: New file.
> 	* binutils-all/copy-1.s: Likewise.
> 	* binutils-all/copy-2.d: Likewise.
> 
> 	* binutils-all/objcopy.exp: Add run_dump_test "copy-1" and
> 	run_dump_test "copy-2".
> 
> 	* lib/utils-lib.exp (run_dump_test): New.
> 	(slurp_options): Likewise.
> 	(regexp_diff): Likewise.
> 	(file_contents): Likewise.
> 	(verbose_eval): Likewise.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-04-26  9:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-21 18:08 Problem setting the CONTENTS flag Andrew STUBBS
2006-04-21 22:26 ` H. J. Lu
2006-04-21 23:32   ` Andreas Schwab
2006-04-23 22:13   ` H. J. Lu
2006-04-24 19:55     ` Andrew STUBBS
2006-04-25 16:37     ` Nick Clifton
2006-04-26  0:21       ` PATCH: binutils/2593: " H. J. Lu
2006-04-26 12:16         ` Nick Clifton
2006-04-26  0:39       ` H. J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).