ppc64 (elf), .long vs .4byte, R_PPC64_ADDR32 vs R_PPC64_UADDR32
Mon Nov 20 22:43:00 GMT 2006
On Mon, Nov 20, 2006 at 12:38:16PM -0800, Doug Evans wrote:
> 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.
Yes. Relocatable ppc64 object files won't use the UADDR relocs.
> So I guess my question is, why does R_PPC64_UADDR32 exist?
Correct handling of unaligned 32-bit fields in executables and shared
libs. I don't know whether we generate any such fields at the moment,
but I believe it's possible to do so in degug/eh info.
> 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?
> /* 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;
glibc ld.so does byte by byte reads and writes for the UADDR relocs,
and a single full size access for the ADDR relocs. The latter is
faster if aligned, but may fail with alignment trap or be slower if
Admittedly, the code in ppc64_elf_relocate_section goes a bit
overboard in handling UADDR -> ADDR transitions since UADDR relocs
won't be in gas generated relocatable object files. Then again, we
have other producers of ppc64 object files (eg. xlc) and who knows
what they will use?
IBM OzLabs - Linux Technology Centre
More information about the Binutils