#255191 [ARM] ld: does not set DT_TEXTREL on libs with R_ARM_PC24 relocations

Package:
binutils
Source:
binutils
Description:
GNU assembler, linker and binary utilities
Submitter:
Yann Dirson
Date:
2011-11-21 22:18:06 UTC
Severity:
important
Tags:
#255191#5
Date:
2004-06-19 12:30:19 UTC
From:
To:
The gc libs in the bigloo package, built as non-PIC for performance reason
on platforms that support mixing PIC and non-PIC, contain an R_ARM_PC24
relocation:

0000b328  0001a001 R_ARM_PC24        0000c134   GC_push_current_stack

However, the lib is not flagged as containing relocations in the text
segment:

  Flags:                             0x2, has entry point, GNU EABI


This appears to be the cause of ld-linux.so segfaulting when it processes
this relocation:

$ LD_TRACE_LOADED_OBJECTS=1 LD_WARN=yes LD_BIND_NOW=yes /usr/lib/debug/ld-linux.so.2 ./bin/bdb
        libbigloobdl_s-2.6d.so => /home/ydirson/bigloo-2.6d-32-O1-g/lib/2.6d/libbigloobdl_s-2.6d.so (0x40001000)
        libbigloo_s-2.6d.so => /home/ydirson/bigloo-2.6d-32-O1-g/lib/2.6d/libbigloo_s-2.6d.so (0x40038000)
        libbigloogc-2.6d.so => /home/ydirson/bigloo-2.6d-32-O1-g/lib/2.6d/libbigloogc-2.6d.so (0x401b2000)
        libdl.so.2 => /lib/libdl.so.2 (0x401e2000)
        libm.so.6 => /lib/libm.so.6 (0x401ec000)
        libc.so.6 => /lib/libc.so.6 (0x40266000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x4038c000)
        /lib/ld-linux.so.2 => /usr/lib/debug/ld-linux.so.2 (0x2aaaa000)
Segmentation fault (core dumped)

As a workaround, I'll force building PIC code on ARM.


Detailed analysis (from Philip Blundell):

$ gdb /usr/lib/debug/ld-linux.so.2 core
[...]
Core was generated by /usr/lib/debug/ld-linux.so.2 ./bin/bdb'.
Program terminated with signal 11, Segmentation fault.
Cannot access memory at address 0x2aab36bc


0x2aab36bc - 0x2aaaa000 = 96bc

and:

    96b4:       e3c034ff        bic     r3, r0, #-16777216      ; 0xff000000
    96b8:       e1824003        orr     r4, r2, r3
    96bc:       e58c4000        str     r4, [ip]
    96c0:       eaffffe6        b       9660 <_dl_relocate_object+0xcac>

Phil has identified this to be the code that relocates R_ARM_PC24 relocs.

#255191#10
Date:
2004-06-19 12:58:42 UTC
From:
To:
Here's a small testcase.

$ echo "f() { return g(); }" > t.c
$ gcc -shared -o t.so t.c
$ readelf -d t.so | grep TEXTREL

If the linker is behaving correctly, the last command should output a
line like:

 0x00000016 (TEXTREL)                    0x0

p.

#255191#19
Date:
2011-11-21 22:15:52 UTC
From:
To:
found 255191 binutils/2.22-1
quit

Philip Blundell wrote:

Reproduced with upstream ld.bfd and ld.gold from Binutils 2.22, assuming
the testcase is valid.

 $ readelf -d t.so | grep REL
 0x00000002 (PLTRELSZ)                   24 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x3b0
 0x00000011 (REL)                        0x380
 0x00000012 (RELSZ)                      48 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffa (RELCOUNT)                   3

The R_ARM_CALL is converted to an R_ARM_JUMP_SLOT when t.o gets linked
into the DSO, as described at [1].

I'm not familiar enough with the relevant conventions to say if this is
a bug or not (my vague suspicion is "not a bug").

Hope that helps,
Jonathan

[1] http://sources.redhat.com/ml/binutils/2004-01/msg00092.html