This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ppc64 (elf), .long vs .4byte, R_PPC64_ADDR32 vs R_PPC64_UADDR32
- From: Doug Evans <dje at transmeta dot com>
- To: binutils at sourceware dot org
- Date: Mon, 20 Nov 2006 12:38:16 -0800
- Subject: ppc64 (elf), .long vs .4byte, R_PPC64_ADDR32 vs R_PPC64_UADDR32
Way back when, I remember working on a port where reloc alignment
was important. One could not use .long, for example, if the value
might be unaligned, and one needed to use .4byte instead.
While browsing elf64-ppc.c, I noticed R_PPC64_UADDR32,
and I got to wondering whether anything similar applied to
ppc64 (or will apply to ppc64 some day in the future).
Currently, .long and .4byte both emit R_PPC64_ADDR32.
Scanning the gas sources I can't find anything that will
cause R_PPC64_UADDR32 to be used.
Given the code appended below I'm guessing it's some sort of
linker-assisted optimization and nothing more.
So I guess my question is, why does R_PPC64_UADDR32 exist?
And, can someone explain what this code is for?
[E.g., Optimize for what?.]
I can see what it does and when it's used, I think, but what program
takes advantage of it? ld.so? How?
TIA.
ppc64_elf_relocate_section:
/* Relocations that may need to be propagated if this is a
dynamic object. */
[...]
/* Optimize unaligned reloc use. */
if ((r_type == R_PPC64_ADDR64 && (out_off & 7) != 0)
|| (r_type == R_PPC64_UADDR64 && (out_off & 7) == 0))
r_type ^= R_PPC64_ADDR64 ^ R_PPC64_UADDR64;
else if ((r_type == R_PPC64_ADDR32 && (out_off & 3) != 0)
|| (r_type == R_PPC64_UADDR32 && (out_off & 3) == 0))
r_type ^= R_PPC64_ADDR32 ^ R_PPC64_UADDR32;
else if ((r_type == R_PPC64_ADDR16 && (out_off & 1) != 0)
|| (r_type == R_PPC64_UADDR16 && (out_off & 1) == 0))
r_type ^= R_PPC64_ADDR16 ^ R_PPC64_UADDR16;