Bug 21000 - hppa-linux does not support -z relro
Summary: hppa-linux does not support -z relro
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: 2.28
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-12-28 23:15 UTC by Alan Modra
Modified: 2017-02-16 15:19 UTC (History)
2 users (show)

See Also:
Host:
Target: hppa-linux
Build:
Last reconfirmed:


Attachments
fix (1007 bytes, patch)
2016-12-30 00:03 UTC, Alan Modra
Details | Diff
Implement no_page_alias (1.89 KB, patch)
2017-02-14 06:03 UTC, Alan Modra
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alan Modra 2016-12-28 23:15:55 UTC
The fix for pr12376 results in no -z relro support for hppa-linux.  You can't force DATA_ADDR and have relro support.
Comment 1 dave.anglin 2016-12-29 16:29:50 UTC
Is there a testcase?

It seems to me we need to either pad the text or align data to a page boundary to avoid
non equivalent aliases.  We continue to struggle with this issue on SMP machines in the
Linux kernel, so I would be very hesitant to not align data to a page boundary.

Happy Holidays,
Dave
--
John David Anglin	dave.anglin@bell.net
Comment 2 Alan Modra 2016-12-29 23:00:03 UTC
Hi Dave, ld-elf/pr20995-2 is what brought this to my attention.  Also, any of the following.

Running /home/alan/src/binutils-gdb-2.28/ld/testsuite/ld-elf/binutils.exp ...
FAIL: strip -z relro (relro1)
FAIL: strip -z relro -shared (relro1)
FAIL: objcopy -z relro (relro1)
FAIL: objcopy -z relro -shared (relro1)
FAIL: objcopy -z relro (tdata1)
FAIL: objcopy -shared -z relro (tdata1)
FAIL: objcopy -z relro (tdata2)
FAIL: objcopy -shared -z relro (tdata2)
FAIL: objcopy -z relro (tdata3)
FAIL: objcopy -shared -z relro (tdata3)
FAIL: objcopy -shared -z relro (tbss1)
FAIL: objcopy -shared -z relro (tbss2)
FAIL: objcopy -shared -z relro (tbss3)

As far as a fix for this goes, if you're sure that pr12376 isn't really just a kernel issue (see https://sourceware.org/bugzilla/show_bug.cgi?id=12376#c8) then hppa can still support relro by page aligning data then following that with DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE}).  This will waste up to 2*MAXPAGESIZE-2 bytes of memory before the start of the relro area, the first page for the hardware/kernel issue, the second to align the end of the relro area to a page.
Comment 3 Alan Modra 2016-12-30 00:03:09 UTC
Created attachment 9734 [details]
fix

This seems to do the trick, but I haven't tested native hppa-linux builds.  I gave away my hppa hardware a long time ago.  Dave, could you do some checking for me please?  It would be nice to have this fix in the 2.28 release.
Comment 4 dave.anglin 2016-12-30 00:22:28 UTC
On 2016-12-29, at 6:00 PM, amodra at gmail dot com wrote:

> As far as a fix for this goes, if you're sure that pr12376 isn't really just a
> kernel issue (see https://sourceware.org/bugzilla/show_bug.cgi?id=12376#c8)
> then hppa can still support relro by page aligning data then following that
> with DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE}).  This will waste
> up to 2*MAXPAGESIZE-2 bytes of memory before the start of the relro area, the
> first page for the hardware/kernel issue, the second to align the end of the
> relro area to a page.

The fine print on the aliasing restrictions is described in the PA-RISC 2.0 Architecture manual
starting on page F-5.  In practice, this is only a limitation on machines with PA8800 and PA8900
processors.  There is code in pacache.S where we use equivalently mapped pages in the kernel
for certain operations.

I'll give your fix a whirl.

Dave
--
John David Anglin	dave.anglin@bell.net
Comment 5 dave.anglin 2016-12-30 00:55:38 UTC
On 2016-12-29, at 7:03 PM, amodra at gmail dot com wrote:

> I
> gave away my hppa hardware a long time ago.

Helge has been testing a user-only target of hppa to qemu being developed by Richard Henderson.  It's here:
 git://github.com/rth7680/qemu.git tgt-hppa

Dave
--
John David Anglin	dave.anglin@bell.net
Comment 6 dave.anglin 2016-12-30 18:22:45 UTC
On 2016-12-29, at 7:22 PM, dave.anglin at bell dot net wrote:

> I'll give your fix a whirl.

With trunk and your fix, I see the following fails in the ld suite:

FAIL: PIE PR ld/14525

FAIL: Run with libpr18720c.so 1
FAIL: Run with libpr18720c.so 2
FAIL: Run with libpr18720c.so 3
FAIL: Run with libpr18720c.so 4
FAIL: Run with libpr18720c.so 5

FAIL: Build warn libbar.so
FAIL: Run pr2404 with PIE
FAIL: Run pr18718
FAIL: Run pr18718 with PIE (1)
FAIL: Run pr18718 with PIE (2)
FAIL: Run pr18718 with PIC (1)
FAIL: Run pr18718 with PIC (2)

FAIL: Object NOT containing unique does not have an OS/ABI field of System V
FAIL: Executable NOT containing unique does not have an OS/ABI field of System V

Running: tmpdir/pr14525 > tmpdir/pr14525.out
tmpdir/pr14525: symbol lookup error: tmpdir/pr14525: undefined symbol: __executable_start
FAIL: PIE PR ld/14525

Running: tmpdir/pr18720a > tmpdir/pr18720a.out
child killed: SIGABRT
FAIL: Run with libpr18720c.so 1

/home/dave/gnu/binutils/objdir/ld/../binutils/readelf -S --wide tmpdir/libbarw.so > dump.out
readelf: Warning: [14]: Unexpected value (10) in info field.
FAIL: Build warn libbar.so

Running: tmpdir/pr2404pie > tmpdir/pr2404pie.out
child killed: illegal instruction
FAIL: Run pr2404 with PIE

Running: tmpdir/pr18718 > tmpdir/pr18718.out
child killed: SIGABRT
FAIL: Run pr18718

Executing on host: sh -c {/home/dave/gnu/binutils/objdir/ld/ld-new   -o tmpdir/l
ibunique_shared_ref.so -shared tmpdir/unique_shared.o tmpdir/unique_empty.o 2>&1}  /dev/null ld.tmp (timeout = 300)
spawn [open ...]
PASS: Checking unique objectPASS: Checking unique executable
FAIL: Object NOT containing unique does not have an OS/ABI field of System V
FAIL: Executable NOT containing unique does not have an OS/ABI field of System Vtestcase /home/dave/gnu/binutils/src/ld/testsuite/ld-unique/unique.exp completed
 in 4 seconds

Dave
--
John David Anglin	dave.anglin@bell.net
Comment 7 dave.anglin 2016-12-30 19:14:27 UTC
On 2016-12-29, at 7:21 PM, John David Anglin wrote:

> I'll give your fix a whirl.


I should have mentioned that there were no unexpected errors in binutils and gas suites:

                === binutils Summary ===

# of expected passes            148
# of expected failures          2
# of unsupported tests          4

Dave
--
John David Anglin	dave.anglin@bell.net
Comment 8 cvs-commit@gcc.gnu.org 2017-01-02 13:36:24 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f5657270bd9353db74ba802ebed62b7133f7c2a0

commit f5657270bd9353db74ba802ebed62b7133f7c2a0
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Jan 2 22:33:47 2017 +1030

    Support -z relro on hppa
    
    	PR ld/21000
    	* emulparams/hppalinux.sh (DATA_ADDR, SHLIB_DATA_ADDR): Don't define.
    	(DATA_SEGMENT_ALIGN, DATA_SEGMENT_END, DATA_SEGMENT_RELRO_END): Define.
    	* scripttempl/elf.sc: Don't define the above if DATA_SEGMENT_ALIGN
    	is already defined.
Comment 9 Alan Modra 2017-01-02 13:56:23 UTC
Some of the fails should now be fixed.  I trust there were no regressions on a native build?  Incidentally, latest glibc doesn't build on hppa-linux due to https://sourceware.org/ml/libc-alpha/2016-05/msg00605.html
Comment 10 dave.anglin 2017-01-02 16:17:25 UTC
On 2017-01-02, at 8:56 AM, amodra at gmail dot com wrote:

> Some of the fails should now be fixed.  I trust there were no regressions on a
> native build?  Incidentally, latest glibc doesn't build on hppa-linux due to
> https://sourceware.org/ml/libc-alpha/2016-05/msg00605.html

I don't believe there were any regressions.   Will retest ,

I believe the glibc issue must be fixed as I had successful builds in the latter part of
last October when I was hacking on it.

Happy New Years,
Dave
--
John David Anglin	dave.anglin@bell.net
Comment 11 cvs-commit@gcc.gnu.org 2017-02-03 09:38:54 UTC
The binutils-2_28-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fcbac04dd1e3dcfc0cba170915ac28a8a1058239

commit fcbac04dd1e3dcfc0cba170915ac28a8a1058239
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Feb 3 16:49:47 2017 +1030

    Support -z relro on hppa
    
    	PR ld/21000
    	* emulparams/hppalinux.sh (DATA_ADDR, SHLIB_DATA_ADDR): Don't define.
    	(DATA_SEGMENT_ALIGN, DATA_SEGMENT_END, DATA_SEGMENT_RELRO_END): Define.
    	* scripttempl/elf.sc: Don't define the above if DATA_SEGMENT_ALIGN
    	is already defined.
Comment 12 Alan Modra 2017-02-03 12:59:24 UTC
Fixed.
Comment 13 John David Anglin 2017-02-12 23:04:17 UTC
If I compile the trivial main program

int main() { return 0 }

with "gcc -o main -Wl,-z,relro main.c" and run main using gdb with
a break at _start

dave@mx3210:~/ffmpeg$ gdb main
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "hppa-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from main...(no debugging symbols found)...done.
(gdb) break _start
Breakpoint 1 at 0x10350
(gdb) r
Starting program: /home/dave/ffmpeg/main 

Breakpoint 1, 0x00010350 in _start ()

I get a bunch of inequivalent alias messages on the console:

mx3210 login: INEQUIVALENT ALIASES 0x10000 and 0x11000 in file main
INEQUIVALENT ALIASES 0x10000 and 0x11000 in file main
INEQUIVALENT ALIASES 0x10000 and 0x11000 in file main
INEQUIVALENT ALIASES 0x10000 and 0x11000 in file main
INEQUIVALENT ALIASES 0x10000 and 0x11000 in file main
INEQUIVALENT ALIASES 0x10000 and 0x11000 in file main
...

This doesn't happen without "-Wl,-z,relro".
Comment 14 Alan Modra 2017-02-13 01:34:14 UTC
I obviously didn't understand the alias problem..  If I am grasping it correctly now, is the complaint about INEQUIVALENT ALIASES really that in the following load map from a trivial -z relro main.c we have file offsets in the same page?

  LOAD           0x000000 0x00010000 0x00010000 0x00898 0x00898 R E 0x1000
  LOAD           0x000f20 0x00011f20 0x00011f20 0x0014c 0x0015c RWE 0x1000

In which case the fix for this will involve changing assign_file_positions_for_load_sections
Comment 15 dave.anglin 2017-02-13 02:29:49 UTC
On 2017-02-12, at 8:34 PM, amodra at gmail dot com wrote:

> https://sourceware.org/bugzilla/show_bug.cgi?id=21000
> 
> --- Comment #14 from Alan Modra <amodra at gmail dot com> ---
> I obviously didn't understand the alias problem..  If I am grasping it
> correctly now, is the complaint about INEQUIVALENT ALIASES really that in the
> following load map from a trivial -z relro main.c we have file offsets in the
> same page?
> 
>  LOAD           0x000000 0x00010000 0x00010000 0x00898 0x00898 R E 0x1000
>  LOAD           0x000f20 0x00011f20 0x00011f20 0x0014c 0x0015c RWE 0x1000

Yes, I believe that is correct.  I think the file offsets need to be page aligned so that the
segments don't overlap when they are mapped to virtual addresses.  In a general sense,
we can't have two different cache lines mapping to the same location in physical memory,
particularly when they are both writeable.

This is what we have without the option:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00010034 0x00010034 0x000c0 0x000c0 R E 0x4
  INTERP         0x0000f4 0x000100f4 0x000100f4 0x0000d 0x0000d R   0x1
      [Requesting program interpreter: /lib/ld.so.1]
  LOAD           0x000000 0x00010000 0x00010000 0x0094c 0x0094c R E 0x1000
  LOAD           0x001000 0x00011000 0x00011000 0x00188 0x00198 RWE 0x1000
  DYNAMIC        0x001028 0x00011028 0x00011028 0x000d8 0x000d8 RW  0x4

> 
> In which case the fix for this will involve changing
> assign_file_positions_for_load_sections

--
John David Anglin	dave.anglin@bell.net
Comment 16 dave.anglin 2017-02-13 13:19:42 UTC
On 2017-02-12, at 8:34 PM, amodra at gmail dot com wrote:

> I obviously didn't understand the alias problem..  If I am grasping it
> correctly now, is the complaint about INEQUIVALENT ALIASES really that in the
> following load map from a trivial -z relro main.c we have file offsets in the
> same page?
> 
>  LOAD           0x000000 0x00010000 0x00010000 0x00898 0x00898 R E 0x1000
>  LOAD           0x000f20 0x00011f20 0x00011f20 0x0014c 0x0015c RWE 0x1000

I think the issue is easiest to understand by looking at the maps file for the process.
For the trivial -z relro main we have

dave@mx3210:/proc/19876$ cat maps
00010000-00011000 r-xp 00000000 08:11 11799480                           /home/dave/ffmpeg/main
00011000-00012000 r--p 00000000 08:11 11799480                           /home/dave/ffmpeg/main
00012000-00013000 rwxp 00001000 08:11 11799480                           /home/dave/ffmpeg/main
f9ffb000-fa167000 r-xp 00000000 08:25 33770753                           /lib/hppa-linux-gnu/libc-2.24.so
fa167000-fa16e000 rwxp 0016c000 08:25 33770753                           /lib/hppa-linux-gnu/libc-2.24.so
fa16e000-fa170000 rwxp 00000000 00:00 0 
fa3f8000-fa41b000 r-xp 00000000 08:25 33710119                           /lib/hppa-linux-gnu/ld-2.24.so
fa41b000-fa41f000 rwxp 00023000 08:25 33710119                           /lib/hppa-linux-gnu/ld-2.24.so
fa4fc000-fa501000 rw-p 00000000 00:00 0 
fa501000-fa523000 rwxp 00000000 00:00 0                                  [stack]

Without -z relro, we have

dave@mx3210:/proc/25080$ cat maps
00010000-00011000 r-xp 00000000 08:11 11799480                           /home/dave/ffmpeg/main
00011000-00012000 rwxp 00001000 08:11 11799480                           /home/dave/ffmpeg/main
f9ffb000-fa167000 r-xp 00000000 08:25 33770753                           /lib/hppa-linux-gnu/libc-2.24.so
fa167000-fa16e000 rwxp 0016c000 08:25 33770753                           /lib/hppa-linux-gnu/libc-2.24.so
fa16e000-fa170000 rwxp 00000000 00:00 0 
fa3f8000-fa41b000 r-xp 00000000 08:25 33710119                           /lib/hppa-linux-gnu/ld-2.24.so
fa41b000-fa41f000 rwxp 00023000 08:25 33710119                           /lib/hppa-linux-gnu/ld-2.24.so
fa4fc000-fa501000 rw-p 00000000 00:00 0 
fa501000-fa523000 rwxp 00000000 00:00 0                                  [stack]

--
John David Anglin	dave.anglin@bell.net
Comment 17 Alan Modra 2017-02-14 06:03:00 UTC
Created attachment 9820 [details]
Implement no_page_alias

This wastes a page in order to avoid the page aliasing problem
Comment 18 dave.anglin 2017-02-14 13:08:27 UTC
On 2017-02-14, at 1:03 AM, amodra at gmail dot com wrote:

> Created attachment 9820 [details]
>  --> https://sourceware.org/bugzilla/attachment.cgi?id=9820&action=edit
> Implement no_page_alias

Thanks Alan.  Will test tonight.

Dave
--
John David Anglin	dave.anglin@bell.net
Comment 19 John David Anglin 2017-02-15 02:00:08 UTC
The LOAD headers for ld-new look good.  We had following ld testsuite fails on trunk with patch:

FAIL: PIE preinit array
FAIL: PIE init array
FAIL: PIE fini array
FAIL: PIE init array mixed
FAIL: PIE PR ld/14525
FAIL: Run with libpr18720c.so 1
FAIL: Run with libpr18720c.so 2
FAIL: Run with libpr18720c.so 3
FAIL: Run with libpr18720c.so 4
FAIL: Run with libpr18720c.so 5
FAIL: Run pr2404 with PIE
FAIL: Run pr18718
FAIL: Run pr18718 with PIE (1)
FAIL: Run pr18718 with PIE (2)
FAIL: Run pr18718 with PIC (1)
FAIL: Run pr18718 with PIC (2)
FAIL: Run pr19579
FAIL: Run pr19719pie fun defined
FAIL: Run pr19719pie fun undefined
FAIL: weak undefined
FAIL: weak undefined data

                === ld Summary ===

# of expected passes            1007
# of unexpected failures        21
# of expected failures          41
# of untested testcases         1# of unsupported tests          8
/home/dave/gnu/binutils/objdir/ld/ld-new 2.28.51.20170214

There were no unexpected failures in binutils and gas suites.
Comment 20 cvs-commit@gcc.gnu.org 2017-02-16 12:43:16 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a8c75b765e57aaebb99d4e32e0f228835cff2737

commit a8c75b765e57aaebb99d4e32e0f228835cff2737
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Feb 14 10:45:51 2017 +1030

    hppa -z relro again
    
    I misunderstood the hppa alias problem.  File offsets of segments need
    to be such that no page is mapped twice with different permissions.
    (Which still seems to me like something the kernel could fix, but
    anyhow, this is not so difficult to achieve in ld.)
    
    	PR 21000
    bfd/
    	* elf-bfd.h (struct elf_backend_data): Add no_page_alias.
    	* elfxx-target.h (elf_backend_no_page_alias): Define.
    	(elfNN_bed): Init new field.
    	* elf.c (assign_file_positions_for_load_sections): If no_page_alias
    	ensure PT_LOAD segment starts on a new page.
    	* elf32-hppa.c (elf_backend_no_page_alias): Define.
    ld/
    	* testsuite/ld-elf/loadaddr1.d: Adjust for hppa file offsets.
    	* testsuite/ld-elf/loadaddr2.d: Likewise.
    	* testsuite/ld-elf/loadaddr3a.d: Likewise.
    	* testsuite/ld-scripts/rgn-at5.d: Likewise.
Comment 21 cvs-commit@gcc.gnu.org 2017-02-16 15:16:12 UTC
The binutils-2_28-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a2db675b74394252dc8de30921f9064ebd2cdf0e

commit a2db675b74394252dc8de30921f9064ebd2cdf0e
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Feb 14 10:45:51 2017 +1030

    hppa -z relro again
    
    I misunderstood the hppa alias problem.  File offsets of segments need
    to be such that no page is mapped twice with different permissions.
    (Which still seems to me like something the kernel could fix, but
    anyhow, this is not so difficult to achieve in ld.)
    
    	PR 21000
    bfd/
    	* elf-bfd.h (struct elf_backend_data): Add no_page_alias.
    	* elfxx-target.h (elf_backend_no_page_alias): Define.
    	(elfNN_bed): Init new field.
    	* elf.c (assign_file_positions_for_load_sections): If no_page_alias
    	ensure PT_LOAD segment starts on a new page.
    	* elf32-hppa.c (elf_backend_no_page_alias): Define.
    ld/
    	* testsuite/ld-elf/loadaddr1.d: Adjust for hppa file offsets.
    	* testsuite/ld-elf/loadaddr2.d: Likewise.
    	* testsuite/ld-elf/loadaddr3a.d: Likewise.
    	* testsuite/ld-scripts/rgn-at5.d: Likewise.
Comment 22 Alan Modra 2017-02-16 15:19:48 UTC
Fixed.