bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gas/24896] New: [powerpc] gas should emit R_PPC_UADDR32/R_PPC64_UAD


From: maskray at google dot com
Subject: [Bug gas/24896] New: [powerpc] gas should emit R_PPC_UADDR32/R_PPC64_UADDR64 at unaligned locations if the section is sufficiently aligned
Date: Mon, 12 Aug 2019 03:35:48 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=24896

            Bug ID: 24896
           Summary: [powerpc] gas should emit
                    R_PPC_UADDR32/R_PPC64_UADDR64 at unaligned locations
                    if the section is sufficiently aligned
           Product: binutils
           Version: 2.33 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gas
          Assignee: unassigned at sourceware dot org
          Reporter: maskray at google dot com
  Target Milestone: ---

Related to both gas and ld.

gas emits R_PPC_ADDR32 and R_PPC64_ADDR64 at unaligned locations.
ld converts R_PPC64_ADDR64 to R_PPC64_UADDR64 if unaligned, and R_PPC64_UADDR64
to R_PPC64_ADDR64 if aligned.

  bfd/elf64-ppc.c:ppc64_elf_relocate_section

    /* 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;

% d.c
char y;
struct{char _; const char *x; char *y;} __attribute__((packed)) _ = {'_', "a",
&y};
void _start() {}

% powerpc64le-linux-gnu-gcc -c -fpic d.c; readelf -Wr d.o | grep R_PPC64
0000000000000001  0000000500000026 R_PPC64_ADDR64         0000000000000000
.rodata + 0
0000000000000009  0000000900000026 R_PPC64_ADDR64         0000000000000001 y +
0
% powerpc64le-linux-gnu-ld -pie d.o -o d; readelf -Wr d | grep R_PPC64
0000000000020001  000000010000002b R_PPC64_UADDR64        0000000000000298
.text + 28
0000000000020009  000000020000002b R_PPC64_UADDR64        0000000000020000
.data + 11
% powerpc64le-linux-gnu-ld -shared d.o -o d.so; readelf -Wr d.so | grep R_PPC64
0000000000020001  000000010000002b R_PPC64_UADDR64        0000000000000288
.text + 28
0000000000020009  000000040000002b R_PPC64_UADDR64        0000000000020011 y +
0

This is not the case on powerpc. ld doesn't do such unaligned reloc
optimization:

% powerpc-linux-gnu-gcc -c -fpic d.c; readelf -Wr d.o | grep R_PPC
00000001  00000501 R_PPC_ADDR32           00000000   .rodata + 0
00000005  00000901 R_PPC_ADDR32           00000001   y + 0
% powerpc-linux-gnu-ld -pie d.o -o d; re -Wr d | grep R_PPC
00020001  00000016 R_PPC_RELATIVE                    1b8
00020005  00000016 R_PPC_RELATIVE                    2001c
% powerpc-linux-gnu-ld -shared d.o -o d.so; re -Wr d.so | grep R_PPC
00020001  00000016 R_PPC_RELATIVE                    1c4
00020005  00000301 R_PPC_ADDR32           0002001c   y + 0


* gcc/as: R_PPC_UADDR32 and R_PPC64_UADDR64 should be produced.
  If sh_addralign is sufficiently aligned, gas should emit UADDR at an
unaligned location.
  Otherwise (e.g. sh_addralign=1), gas probably can't reasonably decide whether
ADDR/UADDR should be used at an unaligned location. Maybe gcc should emit more
information to help gas?
* ld: I am still not clear whether the ADDR -> UADDR conversion is reasonable,
      but 64-bit UADDR -> ADDR conversion can probably be dropped, it has very
little benefit.

The expected result:

% powerpc-linux-gnu-gcc -c -fpic d.c; readelf -Wr d.o | grep R_PPC
...  R_PPC_UADDR32
...  R_PPC_UADDR32
% powerpc-linux-gnu-ld -pie d.o -o d; re -Wr d | grep R_PPC
...  R_PPC_UADDR32   # ADDR can use RELATIVE if the target symbol is
non-preemptable but UADDR can't.
...  R_PPC_UADDR32
% powerpc-linux-gnu-ld -shared d.o -o d.so; re -Wr d.so | grep R_PPC
...  R_PPC_UADDR32
...  R_PPC_UADDR32

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]