Bug 84553 - -rdynamic generates TEXTREL relocations on ia64
Summary: -rdynamic generates TEXTREL relocations on ia64
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-02-25 20:34 UTC by Sergei Trofimovich
Modified: 2021-11-28 00:22 UTC (History)
2 users (show)

See Also:
Host:
Target: ia64
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-02-26 00:00:00


Attachments
untested patch (451 bytes, patch)
2018-02-26 20:38 UTC, Jim Wilson
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2018-02-25 20:34:55 UTC
This is a trimmed-down version of gcc compiling itself with TEXTRELs on ia64:
    https://bugs.gentoo.org/566118

Minimal reproducer:

  // cat lto-lang.c 
  struct a {
    int (*b)(void);
    int c;
  };
  int d(void) {}
  const struct a e = { &d, 0, };

  int main(){}
    $ LANG=C ia64-unknown-linux-gnu-gcc -O0 -no-pie -fno-PIE lto-lang.c -o lto-lang -Wl,-z,text -rdynamic
    /usr/libexec/gcc/ia64-unknown-linux-gnu/ld: read-only segment has dynamic relocations.
    collect2: error: ld returned 1 exit status

Used version:
    binutils-2.30 (older 2.29 is also affected), gcc-HEAD (older 6.4.0 is also affected)

I'm not sure who exactly is at fault here: gcc or binutils.

What happens here is:
  'const struct e' (with .text pointer) is placed into '.rodata' by gcc and later is merged into '.text'.

What I suspect should happen:
  'const struct e' (with .text pointer) is placed into '.data.rel.ro' by gcc and later is merged into '.data'?
Comment 1 Jessica Clarke 2018-02-26 17:06:07 UTC
This is a GCC bug. The function "d" here is non-static and thus exported as a dynamic symbol. On ia64, function descriptors for dynamic symbols are always allocated by the dynamic linker at runtime for canonicalisation (yes, there are other things you could do, but this is what was chosen), and therefore are not link-time constants, even though the contents of this function descriptor can be determined at link-time (since this is linking an executable). GCC should instead be placing this in a relro section like you said.
Comment 2 Jim Wilson 2018-02-26 20:37:18 UTC
rdynamic is a linker option that the compiler ignores, except to pass on to the linker.  As far as the compiler knows, you are building a non-pic application, and hence the symbol is local.  We can't assume that -rdynamic will be used at compile time, and hence to make this work we must assume that any local symbol might become global at link time.

We can fix this my modifying the ia64_reloc_rw_mask function to return 3 when non-pic, same as it does when pic, to indicate that local symbols with relocs aren't read-only.

I don't have access to ia64 hardware, so I don't have any easy way to test this.
The symbol ends up in .data.rel.ro.local instead of .data.rel.ro, but presumably that is OK.
Comment 3 Jim Wilson 2018-02-26 20:38:32 UTC
Created attachment 43514 [details]
untested patch
Comment 4 Jessica Clarke 2018-02-26 20:40:08 UTC
(In reply to Jim Wilson from comment #2)
> rdynamic is a linker option that the compiler ignores, except to pass on to
> the linker.  As far as the compiler knows, you are building a non-pic
> application, and hence the symbol is local.  We can't assume that -rdynamic
> will be used at compile time, and hence to make this work we must assume
> that any local symbol might become global at link time.

Ah I see, that explains it.

> We can fix this my modifying the ia64_reloc_rw_mask function to return 3
> when non-pic, same as it does when pic, to indicate that local symbols with
> relocs aren't read-only.
> 
> I don't have access to ia64 hardware, so I don't have any easy way to test
> this.
> The symbol ends up in .data.rel.ro.local instead of .data.rel.ro, but
> presumably that is OK.

That's what happens on hppa which has similar function descriptor behaviour, so that should be fine.
Comment 5 Sergei Trofimovich 2018-03-01 22:15:43 UTC
I did not regression-test this patch on gcc testsuite but this patch fixes TEXTREL on gcc and still produces working glibc and kernel on ia64.
Comment 6 Sergei Trofimovich 2020-06-01 22:40:13 UTC
Gentoo runs the patch for a while system-wide and it seems to work fine. Worth submitting the patch for review?
Comment 7 Jim Wilson 2020-06-02 20:17:08 UTC
I was ia64 maintainer when I wrote the patch, but couldn't test it.  I'm not the ia64 maintainer anymore.  I suggest asking the current ia64 maintainer.  Though, oops, I see we don't have one listed in the MAINTAINER file.  I thought we had appointed one.  I'm a global maintainer, but that doesn't give me power to approve my own patch for things I don't maintain anymore.  I'm hopelessly overcommitted on RISC-V issues so unlikely to have time to do anything here.