This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix objdump output of R_SPARC_OLO10


On Tue, Jan 18, 2011 at 8:51 PM, David Miller <davem@davemloft.net> wrote:
>
> This bug in relocation reporting on sparc has bitten me at least
> twice, and just recently has sent several folks on a wild goose chase
> again.
>
> R_SPARC_OLO10 relocations exist only on 64-bit sparc, and use the
> extra bits in the R_INFO field of the relocation to store a second,
> constant, 24-bit signed addend.
>
> BFD internally does not have enough space to store two addends in
> it's 'arelent' structure.
>
> Therefore, the 64-bit ELF Sparc backend transforms every R_SPARC_OLO10
> relocation into a sequence of two BFD internal relocs:
>
> ? ? ? ?R_SPARC_LO10
> ? ? ? ?R_SPARC_13
>
> both pointing at the same address.
>
> The primary addend of the R_SPARC_OLO10 relocation is stored in the
> R_SPARC_LO10 reloc, and the second addend is stored in the R_SPARC_13
> reloc.
>
> This internal transformed form is therefore what 'objdump' ends up
> reporting. ?Being a full mis-representation of what's actually in the
> binary, it will confuse and has confused developers trying to use
> objdump to analyze binaries.
>
> 'readelf' handles it properly, by way of not using BFD along with some
> sparc specific tests.
>
> On the one hand the fix I'm proposing here is a bit of a hack, but on
> the other hand it's the best thing I've been able to come up with and
> this bug has wasted developer time unnecessarily.
>
> Any better ideas?
>
> binutils/
>
> 2011-01-18 ?David S. Miller ?<davem@sunset.davemloft.net>
>
> ? ? ? ?* objdump.c (dump_reloc_set): Output R_SPARC_OLO10 relocations
> ? ? ? ?accurately, rather than how they are represented internally.
>
> diff --git a/binutils/objdump.c b/binutils/objdump.c
> index 0be662f..99d1279 100644
> --- a/binutils/objdump.c
> +++ b/binutils/objdump.c
> @@ -2829,6 +2829,7 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
> ? ? ? unsigned int linenumber;
> ? ? ? const char *sym_name;
> ? ? ? const char *section_name;
> + ? ? ?bfd_vma addend2 = 0;
>
> ? ? ? if (start_address != (bfd_vma) -1
> ? ? ? ? ?&& q->address < start_address)
> @@ -2884,7 +2885,34 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
> ? ? ? if (q->howto == NULL)
> ? ? ? ?printf (" *unknown* ? ? ? ? ");
> ? ? ? else if (q->howto->name)
> - ? ? ? printf (" %-16s ?", q->howto->name);
> + ? ? ? {
> + ? ? ? ? const char *name = q->howto->name;
> +
> + ? ? ? ? /* R_SPARC_OLO10 relocations contain two addends.
> + ? ? ? ? ? ?But because 'arelent' lacks enough storage to
> + ? ? ? ? ? ?store them both, the 64-bit ELF Sparc backend
> + ? ? ? ? ? ?records this as two relocations. ?One R_SPARC_LO10
> + ? ? ? ? ? ?and one R_SPARC_13, both pointing to the same
> + ? ? ? ? ? ?address. ?This is merely so that we have some
> + ? ? ? ? ? ?place to store both addend fields.
> +
> + ? ? ? ? ? ?Undo this transformation, otherwise the output
> + ? ? ? ? ? ?will be confusing. ?*/
> + ? ? ? ? if (relcount
> + ? ? ? ? ? ? && !strcmp (q->howto->name, "R_SPARC_LO10"))
> + ? ? ? ? ? {
> + ? ? ? ? ? ? arelent *q2 = *(p + 1);
> + ? ? ? ? ? ? if (q2->howto
> + ? ? ? ? ? ? ? ? && q->address == q2->address
> + ? ? ? ? ? ? ? ? && !strcmp (q2->howto->name, "R_SPARC_13"))
> + ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? name = "R_SPARC_OLO10";
> + ? ? ? ? ? ? ? ? addend2 = q2->addend;
> + ? ? ? ? ? ? ? ? p++;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? }
> + ? ? ? ? printf (" %-16s ?", name);
> + ? ? ? }
> ? ? ? else
> ? ? ? ?printf (" %-16d ?", q->howto->type);
>
> @@ -2904,6 +2932,11 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
> ? ? ? ? ?printf ("+0x");
> ? ? ? ? ?bfd_printf_vma (abfd, q->addend);
> ? ? ? ?}
> + ? ? ?if (addend2)
> + ? ? ? {
> + ? ? ? ? printf ("+0x");
> + ? ? ? ? bfd_printf_vma (abfd, addend2);
> + ? ? ? }
>
> ? ? ? printf ("\n");
> ? ? }
>

Are you checking R_SPARC_LO10 even on x86 input?


-- 
H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]