This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: [MIPS][bfd] Merging mips .reginfo sections
- From: Matthew Fortune <Matthew dot Fortune at imgtec dot com>
- To: Simon Atanasyan <simon at atanasyan dot com>, "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Wed, 1 Apr 2015 07:46:49 +0000
- Subject: RE: [MIPS][bfd] Merging mips .reginfo sections
- Authentication-results: sourceware.org; auth=none
- References: <CAGyS+DRBLzUHvMzw64A3mgBjjzxhZTieLfFL8BdpSbaTj+gOMQ at mail dot gmail dot com>
> It looks like the ld.bfd linker does not merge .reginfo sections from
> input object files and just writes registers masks
> (ri_gprmask/ri_cprmask) taken from the first object file.
>
> $ objdump -s -j.reginfo 1.o
> Contents of section .reginfo:
> 0000 04000000 00000000 00000000 00000000
>
> $ objdump -s -j.reginfo 2.o
> Contents of section .reginfo:
> 0000 02000000 00000000 00000000 00000000
>
> $ ld.bfd -m elf32ltsmip -shared 1.o 2.o
> $ objdump -s -j.reginfo a.out
> Contents of section .reginfo:
> 00d4 04000000 00000000 00000000 00000000
>
> $ ld.bfd -m elf32ltsmip -shared 2.o 1.o
> $ objdump -s -j.reginfo a.out
> Contents of section .reginfo:
> 00d4 08000000 00000000 00000000 00000000
>
> $ ld.bfd -version
> GNU ld (GNU Binutils) 2.25.51.20150318
>
> Could anybody explain why the ld.bfd uses this approach and takes
> ri_gprmask from the first object file and ignores other .reginfo
> sectons?
The code below (from bfd/elfxx-mips.c) is intended to do this merging.
I'm not sure why this appears to be failing according to your example
above. There is an inconsistency it seems in the output you show as
the 08000000 bit is not set in either input file.
I'm afraid I don't entirely understand how the map_head.link_order is
put together but it seems that either objects are missing from that
or the special case relating to bfd_data_link_order is kicking in.
What is the source/content of the 1.o/2.o?
Thanks,
Matthew
/* We have found the .reginfo section in the output file.
Look through all the link_orders comprising it and merge
the information together. */
for (p = o->map_head.link_order; p != NULL; p = p->next)
{
asection *input_section;
bfd *input_bfd;
Elf32_External_RegInfo ext;
Elf32_RegInfo sub;
if (p->type != bfd_indirect_link_order)
{
if (p->type == bfd_data_link_order)
continue;
abort ();
}
input_section = p->u.indirect.section;
input_bfd = input_section->owner;
if (! bfd_get_section_contents (input_bfd, input_section,
&ext, 0, sizeof ext))
return FALSE;
bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub);
reginfo.ri_gprmask |= sub.ri_gprmask;
reginfo.ri_cprmask[0] |= sub.ri_cprmask[0];
reginfo.ri_cprmask[1] |= sub.ri_cprmask[1];
reginfo.ri_cprmask[2] |= sub.ri_cprmask[2];
reginfo.ri_cprmask[3] |= sub.ri_cprmask[3];
/* ri_gp_value is set by the function
mips_elf32_section_processing when the section is
finally written out. */
/* Hack: reset the SEC_HAS_CONTENTS flag so that
elf_link_input_bfd ignores this section. */
input_section->flags &= ~SEC_HAS_CONTENTS;
}