This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Committed, MMIX: Bugs with on-demand register allocation fixed
- From: Hans-Peter Nilsson <hp at bitrange dot com>
- To: <binutils at sources dot redhat dot com>
- Date: Sun, 3 Feb 2002 23:46:48 -0500 (EST)
- Subject: Committed, MMIX: Bugs with on-demand register allocation fixed
Fixes and tests for bugs exposed by use in GCC (not committed there yet).
Also added a debug function in elf64-mmix.c.
bfd:
* elf64-mmix.c (mmix_dump_bpo_gregs): New function.
(mmix_elf_check_common_relocs) <case R_MMIX_BASE_PLUS_OFFSET>:
Call bfd_get_section_by_name only once. Initialize
bpodata->n_bpo_relocs_this_section.
(_bfd_mmix_prepare_linker_allocated_gregs): Remove comment
referring to DSOs.
(bpo_reloc_request_sort_fn): Don't use difference of values as
return-value.
ld:
* emultempl/mmix-elfnmmo.em (mmix_after_allocation): Use signed
arithmetic when checking for too many global registers.
ld/testsuite:
* ld-mmix/bpo-18.d, ld-mmix/bpo64addr.ld, ld-mmix/bpo-18m.d,
ld-mmix/bpo-9.s, ld-mmix/bpo-19.d, ld-mmix/bpo-19m.d,
ld-mmix/bpo-10.s, ld-mmix/bpo-20.d, ld-mmix/bpo-20m.d: New tests
for on-demand global register allocation.
Index: elf64-mmix.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-mmix.c,v
retrieving revision 1.8
diff -p -c -r1.8 elf64-mmix.c
*** elf64-mmix.c 2002/02/01 08:18:56 1.8
--- elf64-mmix.c 2002/02/04 04:35:47
*************** extern boolean mmix_elf_final_link PARAM
*** 182,187 ****
--- 182,191 ----
extern void mmix_elf_symbol_processing PARAMS ((bfd *, asymbol *));
+ /* Only intended to be called from a debugger. */
+ extern void mmix_dump_bpo_gregs
+ PARAMS ((struct bfd_link_info *, bfd_error_handler_type));
+
/* Watch out: this currently needs to have elements with the same index as
their R_MMIX_ number. */
static reloc_howto_type elf_mmix_howto_table[] =
*************** mmix_elf_check_common_relocs (abfd, inf
*** 1665,1674 ****
bpo_greg_owner = abfd;
info->base_file = (PTR) bpo_greg_owner;
}
- allocated_gregs_section
- = bfd_get_section_by_name (bpo_greg_owner,
- MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
if (allocated_gregs_section == NULL)
{
allocated_gregs_section
--- 1669,1680 ----
bpo_greg_owner = abfd;
info->base_file = (PTR) bpo_greg_owner;
}
+
+ if (allocated_gregs_section == NULL)
+ allocated_gregs_section
+ = bfd_get_section_by_name (bpo_greg_owner,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
if (allocated_gregs_section == NULL)
{
allocated_gregs_section
*************** mmix_elf_check_common_relocs (abfd, inf
*** 1716,1721 ****
--- 1722,1728 ----
= gregdata->n_max_bpo_relocs;
bpodata->bpo_greg_section
= allocated_gregs_section;
+ bpodata->n_bpo_relocs_this_section = 0;
}
bpodata->n_bpo_relocs_this_section++;
*************** _bfd_mmix_prepare_linker_allocated_gregs
*** 2075,2083 ****
= bfd_get_section_by_name (bpo_greg_owner,
MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
- /* This can't happen without DSO handling. When DSOs are handled
- without any R_MMIX_BASE_PLUS_OFFSET seen, there will be no such
- section. */
if (bpo_gregs_section == NULL)
return true;
--- 2082,2087 ----
*************** bpo_reloc_request_sort_fn (p1, p2)
*** 2201,2212 ****
if (r1->valid != r2->valid)
return r2->valid - r1->valid;
! /* Then sort on value. */
if (r1->value != r2->value)
! return r1->value - r2->value;
/* As a last re-sort, use the address so we get a stable sort. */
return r1 > r2 ? 1 : (r1 < r2 ? -1 : 0);
}
/* This links all R_MMIX_BASE_PLUS_OFFSET relocs into a special array, and
--- 2205,2275 ----
if (r1->valid != r2->valid)
return r2->valid - r1->valid;
! /* Then sort on value. Don't simplify and return just the difference of
! the values: the upper bits of the 64-bit value would be truncated on
! a host with 32-bit ints. */
if (r1->value != r2->value)
! return r1->value > r2->value ? 1 : -1;
/* As a last re-sort, use the address so we get a stable sort. */
return r1 > r2 ? 1 : (r1 < r2 ? -1 : 0);
+ }
+
+ /* For debug use only. Dumps the global register allocations resulting
+ from base-plus-offset relocs. */
+
+ void
+ mmix_dump_bpo_gregs (link_info, pf)
+ struct bfd_link_info *link_info;
+ bfd_error_handler_type pf;
+ {
+ bfd *bpo_greg_owner;
+ asection *bpo_gregs_section;
+ struct bpo_greg_section_info *gregdata;
+ unsigned int i;
+
+ if (link_info == NULL || link_info->base_file == NULL)
+ return;
+
+ bpo_greg_owner = (bfd *) link_info->base_file;
+
+ bpo_gregs_section
+ = bfd_get_section_by_name (bpo_greg_owner,
+ MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
+
+ if (bpo_gregs_section == NULL)
+ return;
+
+ gregdata = (struct bpo_greg_section_info *)
+ elf_section_data (bpo_gregs_section)->tdata;
+ if (gregdata == NULL)
+ return;
+
+ if (pf == NULL)
+ pf = _bfd_error_handler;
+
+ /* These format strings are not translated. They are for debug purposes
+ only and never displayed to an end user. Should they escape, we
+ surely want them in original. */
+ (*pf) (" n_bpo_relocs: %u\n n_max_bpo_relocs: %u\n n_remain...round: %u\n\
+ n_allocated_bpo_gregs: %u\n", gregdata->n_bpo_relocs,
+ gregdata->n_max_bpo_relocs,
+ gregdata->n_remaining_bpo_relocs_this_relaxation_round,
+ gregdata->n_allocated_bpo_gregs);
+
+ if (gregdata->reloc_request)
+ for (i = 0; i < gregdata->n_max_bpo_relocs; i++)
+ (*pf) ("%4u (%4u)/%4u#%u: 0x%08lx%08lx r: %3u o: %3u\n",
+ i,
+ gregdata->bpo_reloc_indexes != NULL
+ ? gregdata->bpo_reloc_indexes[i] : -1,
+ gregdata->reloc_request[i].bpo_reloc_no,
+ gregdata->reloc_request[i].valid,
+
+ (unsigned long) (gregdata->reloc_request[i].value >> 32),
+ (unsigned long) gregdata->reloc_request[i].value,
+ gregdata->reloc_request[i].regindex,
+ gregdata->reloc_request[i].offset);
}
/* This links all R_MMIX_BASE_PLUS_OFFSET relocs into a special array, and
Index: mmix-elfnmmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmix-elfnmmo.em,v
retrieving revision 1.2
diff -u -p -r1.2 mmix-elfnmmo.em
--- mmix-elfnmmo.em 2002/02/01 08:24:02 1.2
+++ mmix-elfnmmo.em 2002/02/04 04:17:11
@@ -59,7 +59,7 @@ mmix_after_allocation ()
{
asection *sec
= bfd_get_section_by_name (output_bfd, MMIX_REG_CONTENTS_SECTION_NAME);
- bfd_vma regvma;
+ bfd_signed_vma regvma;
/* If there's no register section, we don't need to do anything. */
if (sec == NULL)
@@ -73,7 +73,7 @@ mmix_after_allocation ()
(unsigned) sec->_raw_size / 8);
/* Set vma to correspond to first such register number * 8. */
- bfd_set_section_vma (output_bfd, sec, regvma);
+ bfd_set_section_vma (output_bfd, sec, (bfd_vma) regvma);
/* ??? Why isn't the section size (_cooked_size) set? Doesn't it get
set regardless of presence of relocations? */
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-18.d Sun Feb 3 07:23:41 2002
***************
*** 0 ****
--- 1,35 ----
+ #source: start.s
+ #source: bpo-1.s
+ #source: bpo-2.s
+ #source: bpo-5.s
+ #source: bpo-6.s
+ #as: -linker-allocated-gregs
+ #ld: -m elf64mmix -T$srcdir/$subdir/bpo64addr.ld
+ #objdump: -st
+
+ .*: file format elf64-mmix
+
+ SYMBOL TABLE:
+ 0+100 l d \.text 0+
+ 4000000000001060 l d \.text\.away 0+
+ 0+7e0 l d \.MMIX\.reg_contents 0+
+ 4000000000001088 l d \.data 0+
+ 4000000000001088 l d \.bss 0+
+ 0+ l d \*ABS\* 0+
+ 0+ l d \*ABS\* 0+
+ 0+ l d \*ABS\* 0+
+ 4000000000001064 l \.text\.away 0+ x
+ 0+100 g \.text 0+ x
+ 4000000000001060 g O \.text\.away 0+ Main
+ 0+104 g \.text 0+ x2
+ 4000000000001060 g \.text\.away 0+ _start
+ 4000000000001068 g \.text\.away 0+ y
+
+ Contents of section \.text:
+ 0100 232dfc00 232dfd00 .*
+ Contents of section \.text\.away:
+ 1060 e3fd0001 232afe1e 2321fe00 .*
+ Contents of section \.MMIX\.reg_contents:
+ 07e0 00000000 00001168 00000000 0000a514 .*
+ 07f0 40000000 00001070 .*
+ Contents of section \.data:
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo64addr.ld Sun Feb 3 07:12:33 2002
***************
*** 0 ****
--- 1,13 ----
+ OUTPUT_ARCH(mmix)
+ ENTRY(Main)
+ SECTIONS
+ {
+ .text 0x100 :
+ { *(.text.x); *(.text.x2); }
+
+ .text.away 0x4000000000001060 :
+ { *(.text); Main = _start; }
+
+ .MMIX.reg_contents :
+ { *(.MMIX.reg_contents.linker_allocated); *(.MMIX.reg_contents); }
+ }
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-18m.d Sun Feb 3 07:21:14 2002
***************
*** 0 ****
--- 1,25 ----
+ #source: start.s
+ #source: bpo-1.s
+ #source: bpo-2.s
+ #source: bpo-5.s
+ #source: bpo-6.s
+ #as: -linker-allocated-gregs
+ #ld: -m mmo -T$srcdir/$subdir/bpo64addr.ld
+ #objdump: -st
+
+ .*: file format mmo
+
+ SYMBOL TABLE:
+ 4000000000001060 g \*ABS\* Main
+ 0+100 g \.text x
+ 0+104 g \.text x2
+ 4000000000001060 g \*ABS\* _start
+ 4000000000001068 g \*ABS\* y
+
+ Contents of section \.text:
+ 0100 232dfc00 232dfd00 .*
+ Contents of section \.text\.away:
+ 1060 e3fd0001 232afe1e 2321fe00 .*
+ Contents of section \.MMIX\.reg_contents:
+ 07e0 00000000 00001168 00000000 0000a514 .*
+ 07f0 40000000 00001070 .*
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-9.s Sun Feb 3 23:39:25 2002
***************
*** 0 ****
--- 1,5 ----
+ .set i,0
+ .rept 223*4
+ LDA $11,_start+i*64
+ .set i,i+1
+ .endr
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-19.d Mon Feb 4 01:43:31 2002
***************
*** 0 ****
--- 1,44 ----
+ #source: start.s
+ #source: bpo-9.s
+ #as: -linker-allocated-gregs
+ #ld: -m elf64mmix
+ #objdump: -st
+
+ # 223 (max) linker-allocated GREGs, four relocs merged for each register
+ # allocated.
+
+ .*: file format elf64-mmix
+
+ SYMBOL TABLE:
+ 0+ l d \.text 0+
+ 2000000000000000 l d \.data 0+
+ 2000000000000000 l d \.sbss 0+
+ 2000000000000000 l d \.bss 0+
+ 0+100 l d \.MMIX\.reg_contents 0+
+ 0+ l d \*ABS\* 0+
+ 0+ l d \*ABS\* 0+
+ 0+ l d \*ABS\* 0+
+ 0+37c l \*ABS\* 0+ i
+ 0+ g \.text 0+ _start
+ 2000000000000000 g O \*ABS\* 0+ __bss_start
+ 2000000000000000 g O \*ABS\* 0+ _edata
+ 2000000000000000 g O \*ABS\* 0+ _end
+ 0+ g O \.text 0+ _start\.
+
+ Contents of section \.text:
+ 0000 e3fd0001 230b2000 230b2040 230b2080 .*
+ 0010 230b20c0 230b2100 230b2140 230b2180 .*
+ 0020 230b21c0 230b2200 230b2240 230b2280 .*
+ #...
+ 0dd0 230bfcc0 230bfd00 230bfd40 230bfd80 .*
+ 0de0 230bfdc0 230bfe00 230bfe40 230bfe80 .*
+ 0df0 230bfec0 .*
+ Contents of section \.data:
+ Contents of section \.sbss:
+ Contents of section \.MMIX\.reg_contents:
+ 0100 00000000 00000000 00000000 00000100 .*
+ 0110 00000000 00000200 00000000 00000300 .*
+ #...
+ 07d0 00000000 0000da00 00000000 0000db00 .*
+ 07e0 00000000 0000dc00 00000000 0000dd00 .*
+ 07f0 00000000 0000de00 .*
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-19m.d Mon Feb 4 01:47:24 2002
***************
*** 0 ****
--- 1,30 ----
+ #source: start.s
+ #source: bpo-9.s
+ #as: -linker-allocated-gregs
+ #ld: -m mmo
+ #objdump: -st
+
+ # 223 (max) linker-allocated GREGs, four relocs merged for each register
+ # allocated.
+
+ .*: file format mmo
+
+ SYMBOL TABLE:
+ 0+ g \.text Main
+ 0+ g \.text _start
+
+ Contents of section \.text:
+ 0000 e3fd0001 230b2000 230b2040 230b2080 .*
+ 0010 230b20c0 230b2100 230b2140 230b2180 .*
+ 0020 230b21c0 230b2200 230b2240 230b2280 .*
+ #...
+ 0dd0 230bfcc0 230bfd00 230bfd40 230bfd80 .*
+ 0de0 230bfdc0 230bfe00 230bfe40 230bfe80 .*
+ 0df0 230bfec0 .*
+ Contents of section \.MMIX\.reg_contents:
+ 0100 00000000 00000000 00000000 00000100 .*
+ 0110 00000000 00000200 00000000 00000300 .*
+ #...
+ 07d0 00000000 0000da00 00000000 0000db00 .*
+ 07e0 00000000 0000dc00 00000000 0000dd00 .*
+ 07f0 00000000 0000de00 .*
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-10.s Mon Feb 4 01:54:54 2002
***************
*** 0 ****
--- 1,6 ----
+ # Overflow; specify 223*8 registers.
+ .set i,0
+ .rept 223*4*8
+ LDA $11,_start+i*64
+ .set i,i+1
+ .endr
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-20.d Mon Feb 4 02:04:10 2002
***************
*** 0 ****
--- 1,8 ----
+ #source: start.s
+ #source: bpo-10.s
+ #as: -linker-allocated-gregs
+ #ld: -m elf64mmix
+ #error: Too many global registers
+
+ # Check that many too many gregs are recognized (and not signed/unsigned
+ # bugs with checks for < 32 appear).
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-mmix/bpo-20m.d Mon Feb 4 02:04:02 2002
***************
*** 0 ****
--- 1,8 ----
+ #source: start.s
+ #source: bpo-10.s
+ #as: -linker-allocated-gregs
+ #ld: -m mmo
+ #error: Too many global registers
+
+ # Check that many too many gregs are recognized (and not signed/unsigned
+ # bugs with checks for < 32 appear).
brgds, H-P