Bug 16177 - R_ARM_COPY reloc generated for reference in writable section
Summary: R_ARM_COPY reloc generated for reference in writable section
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2013-11-15 20:51 UTC by Roland McGrath
Modified: 2020-11-08 16:03 UTC (History)
7 users (show)

See Also:
Last reconfirmed:

Proposed patch (525 bytes, patch)
2016-04-20 13:00 UTC, Nick Clifton
Details | Diff
Rebased patch (667 bytes, patch)
2018-01-10 02:55 UTC, John Ericson
Details | Diff
Updated/fixed patch (1.16 KB, patch)
2018-07-12 22:17 UTC, Jessica Clarke
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Roland McGrath 2013-11-15 20:51:34 UTC
When a writable input section (i.e. data) refers to a symbol defined in an
ET_DYN object, BFD ld for ARM targets generates a COPY dynamic reloc.  For
other targets like x86, this situation generates a plain data dynamic
reloc.  Gold for ARM also generates the plain data dynamic reloc.

I can't understand any rationale for generating a synthetic data object and
copy reloc for it in this situation.  A copy reloc is only appropriate when
the reference is from a read-only input section (e.g. from an instruction).

	$ cat data-ref.s
	.globl _start
		.p2align 4

		.globl data_object
		.long data_object
		.size object_reference,4
	$ cat libdata.s
		.globl data_object
		.type data_object, %object
		.size data_object, 4
		  .long 123
	$ ./gas/as-new -o data-ref.o data-ref.s 
	$ ./gas/as-new -o libdata.o libdata.s
	$ ./ld/ld-new -shared -o libdata.so libdata.o
	$ ./ld/ld-new -o data-ref data-ref.o libdata.so
	$ readelf -r data-ref

	Relocation section '.rel.dyn' at offset 0x224 contains 1 entries:
	 Offset     Info    Type            Sym.Value  Sym. Name
	100302bc  00000314 R_ARM_COPY        100302bc   data_object
	$ ./gold/ld-new -o data-ref-gold data-ref.o libdata.so
	$ readelf -r data-ref-gold

	Relocation section '.rel.dyn' at offset 0x190 contains 1 entries:
	 Offset     Info    Type            Sym.Value  Sym. Name
	00009230  00000102 R_ARM_ABS32       00000000   data_object
Comment 1 Ben Gamari 2014-01-20 18:19:58 UTC
This appears to be responsible for brokenness on ARM when the Glasgow Haskell Compiler is used to produce dynamically linked executables https://ghc.haskell.org/trac/ghc/ticket/4210#comment:29.
Comment 2 Nick Clifton 2016-04-20 13:00:19 UTC
Created attachment 9207 [details]
Proposed patch

Hi Ben,

  Please try this patch.

Comment 3 Nick Clifton 2016-04-20 13:01:45 UTC
Ben or Roland that is...
Comment 4 Ben Gamari 2017-04-07 00:23:53 UTC
Unfortunately my ARM hardware bit the dust. I'm waiting to take shipment of a new board and will test when it arrives.
Comment 5 Ben Gamari 2017-07-01 22:57:34 UTC
My new hardware arrived. Naturally the patch required a bit of rebasing. My guess can be found here, https://github.com/bgamari/binutils-gdb/commit/539f59256dd8b503b1188eecb30a338ee38616f8. I've started a GHC build linking with the linker from this commit. I'll let you know when it's finished and I've verified that it works.
Comment 6 John Ericson 2018-01-10 02:55:57 UTC
Created attachment 10727 [details]
Rebased patch

This is Ben Gamari's rebase of the original patch, included here for posterity.
Comment 7 Nick Clifton 2018-01-10 09:17:14 UTC
The question is - does the patch work ?

I am happy to apply it, provided that it can be confirmed that it works
in a real ARM-based system.

Comment 8 John Ericson 2018-01-12 23:03:40 UTC
I just copied it, but think I'll be able to confirm that for you by end of next week.


Comment 9 Jessica Clarke 2018-07-12 22:17:06 UTC
Created attachment 11124 [details]
Updated/fixed patch

The original patch on this bug report looks at whether the symbol in question is in a read-only section, but that should have no effect on whether this symbol needs to be copied into the executable. Instead, it should be checking whether there are any relocations in read-only sections referring to the symbol, as that determines whether we are able to leave in dynamic relocations. Ben's rebased version also has the issue of messing with the SEC_READONLY check currently present; that should stay, as SEC_READONLY determines where the copied symbol should go, but only matters if we are doing a copy in the first place. This patch hasn't even been compile tested, but I'm 90% confident it works!
Comment 10 Joe Hermaszewski 2020-11-08 13:56:25 UTC
Hi Jessica, I tried out the patch, thank you! It still applies cleanly, however
when building ncurses it fails, here are the last few lines:

    armv7l-unknown-linux-musleabihf-ranlib ../lib/libncurses++w.a
    compiling demo (obj_s)
    armv7l-unknown-linux-musleabihf-g++  -o demo ../obj_s/demo.o -L../lib -lncurses++w -L../lib -lformw -lmenuw -lpanelw -lncursesw    -lutil     -DHAVE_CONFIG_H -I../c++ -I. -I../include  -DNDEBUG -O2  -fPIC
    armv7l-unknown-linux-musleabihf-ld: ../obj_s/demo.o(.data.rel.ro._ZTI16NCursesFieldType[_ZTI16NCursesFieldType]+0): unresolvable R_ARM_ABS32 relocation against symbol `_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3'
    armv7l-unknown-linux-musleabihf-ld: final link failed: nonrepresentable section on output
    collect2: error: ld returned 1 exit status

The complete log (against musl) is here: https://gist.github.com/2dcd79254db6a00e9d9b99f7f556e56e
And against glibc: https://gist.github.com/3d744762e20df5bad9652f20d8f1a06e
Comment 11 Joe Hermaszewski 2020-11-08 14:53:00 UTC
To reproduce,

- Get a copy of the ncurses 6.2 source
- With binutils (with the patch), and gcc in PATH (both cross compiling to armv7l-unknown-linux-gnueabihf)
- CXX=armv7l-unknown-linux-gnueabihf-g++ CC=armv7l-unknown-linux-gnueabihf-gcc ...
- ./configure --build=x86_64-unknown-linux-gnu --host=armv7l-unknown-linux-gnueabihf
- make all -j
- Observe the mentioned failure
Comment 12 Joe Hermaszewski 2020-11-08 16:03:55 UTC
A much more simple reproducer for the error message I mentioned (from GHC's configure script):

cat >actest.s <<-EOF
  .globl _start
  .p2align 4

  .globl data_object
  .long data_object
  .size object_reference, 4

cat >aclib.s <<-EOF
  .globl data_object
  .type data_object, %object
  .size data_object, 4
    .long 123

$AS -o aclib.o aclib.s
$LD -shared -o aclib.so aclib.o

$AS -o actest.o actest.s
$LD -o actest actest.o aclib.so