+2018-04-25 Christophe Lyon <christophe.lyon@st.com>
+ Mickaël Guêné <mickael.guene@st.com>
+
+ * testsuite/ld-arm/arm-elf.exp: Execute the new FDPIC tests.
+ * testsuite/ld-arm/fdpic-main.d: New test.
+ * testsuite/ld-arm/fdpic-main.ld: New.
+ * testsuite/ld-arm/fdpic-main.r: New.
+ * testsuite/ld-arm/fdpic-main.s: New.
+ * testsuite/ld-arm/fdpic-main.sym: New.
+ * testsuite/ld-arm/fdpic-shared.d: New test.
+ * testsuite/ld-arm/fdpic-shared.ld: New.
+ * testsuite/ld-arm/fdpic-shared.r: New.
+ * testsuite/ld-arm/fdpic-shared.s: New.
+ * testsuite/ld-arm/fdpic-shared.sym: New.
+
2018-04-25 Christophe Lyon <christophe.lyon@st.com>
Mickaël Guêné <mickael.guene@st.com>
"preempt-app"}
}
+set armfdpiceabitests {
+ {"FDPIC ARM shared library little endian"
+ "-shared -T fdpic-shared.ld --hash-style=sysv -EL -m armelf_linux_fdpiceabi" ""
+ "-EL -fdpic" {fdpic-shared.s}
+ {{objdump -fdw fdpic-shared.d} {objdump -Rw fdpic-shared.r}
+ {readelf -Ds fdpic-shared.sym}}
+ "fdpic-shared.so"}
+ {"FDPIC ARM dynamic executable little endian"
+ "tmpdir/fdpic-shared.so -T fdpic-main.ld --hash-style=sysv -EL -m armelf_linux_fdpiceabi" ""
+ "-EL -fdpic" {fdpic-main.s}
+ {{objdump -fdw fdpic-main.d} {objdump -Rw fdpic-main.r}
+ {readelf -Ds fdpic-main.sym}}
+ "fdpic-main"}
+ {"FDPIC ARM shared library big endian"
+ "-shared -T fdpic-shared.ld --hash-style=sysv -EB -m armelfb_linux_fdpiceabi" ""
+ "-EB -fdpic" {fdpic-shared.s}
+ {{objdump -fdw fdpic-shared.d} {objdump -Rw fdpic-shared.r}
+ {readelf -Ds fdpic-shared.sym}}
+ "fdpic-shared.so"}
+ {"FDPIC ARM dynamic executable big endian"
+ "tmpdir/fdpic-shared.so -T fdpic-main.ld --hash-style=sysv -EB -m armelfb_linux_fdpiceabi" ""
+ "-EB -fdpic" {fdpic-main.s}
+ {{objdump -fdw fdpic-main.d} {objdump -Rw fdpic-main.r}
+ {readelf -Ds fdpic-main.sym}}
+ "fdpic-main"}
+}
+
# Massage the $armeabitests_common list into run_ld_link_tests standard form.
# See the comment before 'set armeabitests_common', above.
set elide_action_elt 3
run_ld_link_tests $armeabitests_nonacl
}
+if { [istarget "arm*-*-uclinuxfdpiceabi"] } {
+ run_ld_link_tests $armfdpiceabitests
+}
+
run_dump_test "attr-merge-div-00"
run_dump_test "attr-merge-div-01"
run_dump_test "attr-merge-div-10"
--- /dev/null
+
+tmpdir/fdpic-main: file format elf32-(little|big)arm
+architecture: arm.*, flags 0x00000112:
+EXEC_P, HAS_SYMS, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ .*: e59fc008 ldr ip, \[pc, #8\] ; .* <.plt\+0x10>
+ .*: e08cc009 add ip, ip, r9
+ .*: e59c9004 ldr r9, \[ip, #4\]
+ .*: e59cf000 ldr pc, \[ip\]
+ .*: 0000000c .word 0x0000000c
+ .*: 00000000 .word 0x00000000
+ .*: e51fc00c ldr ip, \[pc, #-12\] ; .* <.plt\+0x14>
+ .*: e92d1000 stmfd sp!, {ip}
+ .*: e599c004 ldr ip, \[r9, #4\]
+ .*: e599f000 ldr pc, \[r9\]
+ .*: e59fc008 ldr ip, \[pc, #8\] ; .* <.plt\+0x38>
+ .*: e08cc009 add ip, ip, r9
+ .*: e59c9004 ldr r9, \[ip, #4\]
+ .*: e59cf000 ldr pc, \[ip]
+ .*: 00000014 .word 0x00000014
+ .*: 00000008 .word 0x00000008
+ .*: e51fc00c ldr ip, \[pc, #-12\] ; .* <.plt\+0x3c>
+ .*: e92d1000 stmfd sp!, {ip}
+ .*: e599c004 ldr ip, \[r9, #4\]
+ .*: e599f000 ldr pc, \[r9\]
+
+Disassembly of section .text:
+
+.* <_start>:
+ .*: eaffffff b .* <main>
+
+.* <main>:
+ .*: e59f206c ldr r2, \[pc, #108\] ; .* <main\+0x74>
+ .*: e59f306c ldr r3, \[pc, #108\] ; .* <main\+0x78>
+ .*: e92d4070 push {r4, r5, r6, lr}
+ .*: e7995002 ldr r5, \[r9, r2\]
+ .*: e1a04009 mov r4, r9
+ .*: e7993003 ldr r3, \[r9, r3\]
+ .*: e5853000 str r3, \[r5\]
+ .*: ebffffe2 bl .* <.plt>
+ .*: e1a06000 mov r6, r0
+ .*: e1a09004 mov r9, r4
+ .*: e5950000 ldr r0, \[r5\]
+ .*: e1a09004 mov r9, r4
+ .*: ebffffe7 bl .* <.plt\+0x28>
+ .*: e59f3040 ldr r3, \[pc, #64\] ; .* <main\+0x7c>
+ .*: e1a09004 mov r9, r4
+ .*: e0833009 add r3, r3, r9
+ .*: e1a00003 mov r0, r3
+ .*: e5853000 str r3, \[r5\]
+ .*: e1a09004 mov r9, r4
+ .*: ebffffe0 bl .* <.plt\+0x28>
+ .*: e59f3028 ldr r3, \[pc, #40\] ; .* <main\+0x80>
+ .*: e1a09004 mov r9, r4
+ .*: e7993003 ldr r3, \[r9, r3\]
+ .*: e5930000 ldr r0, \[r3\]
+ .*: e1a09004 mov r9, r4
+ .*: ebffffda bl .* <.plt\+0x28>
+ .*: e1a00006 mov r0, r6
+ .*: e1a09004 mov r9, r4
+ .*: e8bd8070 pop {r4, r5, r6, pc}
+ .*: 0000002c .word 0x0000002c
+ .*: 00000024 .word 0x00000024
+ .*: 0000001c .word 0x0000001c
+ .*: 00000028 .word 0x00000028
+
+.* <my_local_func>:
+ .*: e12fff1e bx lr
--- /dev/null
+/* Script for -z combreloc: combine and sort reloc sections */
+OUTPUT_FORMAT("elf32-littlearm-fdpic", "elf32-bigarm-fdpic",
+ "elf32-littlearm-fdpic")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x00008000)); . = SEGMENT_START("text-segment", 0x00008000) + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ .hash : { *(.hash) }
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ PROVIDE_HIDDEN (__rel_iplt_start = .);
+ *(.rel.iplt)
+ PROVIDE_HIDDEN (__rel_iplt_end = .);
+ PROVIDE_HIDDEN (__rela_iplt_start = .);
+ PROVIDE_HIDDEN (__rela_iplt_end = .);
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ PROVIDE_HIDDEN (__rel_iplt_start = .);
+ PROVIDE_HIDDEN (__rel_iplt_end = .);
+ PROVIDE_HIDDEN (__rela_iplt_start = .);
+ *(.rela.iplt)
+ PROVIDE_HIDDEN (__rela_iplt_end = .);
+ }
+ .rel.plt :
+ {
+ *(.rel.plt)
+ }
+ .rela.plt :
+ {
+ *(.rela.plt)
+ }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ .plt : { *(.plt) }
+ .iplt : { *(.iplt) }
+ .text :
+ {
+ *(.text.unlikely .text.*_unlikely)
+ *(.text.exit .text.exit.*)
+ *(.text.startup .text.startup.*)
+ *(.text.hot .text.hot.*)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
+ PROVIDE_HIDDEN (__exidx_start = .);
+ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+ PROVIDE_HIDDEN (__exidx_end = .);
+ .rofixup : {
+ __ROFIXUP_LIST__ = .;
+ *(.rofixup)
+ __ROFIXUP_END__ = .;
+}
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
+ .gcc_except_table.*) }
+ /* These sections are generated by the Sun/Oracle C++ compiler. */
+ .exception_ranges : ONLY_IF_RO { *(.exception_ranges
+ .exception_ranges*) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
+ /* Exception handling */
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+ .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
+ /* Thread Local Storage sections */
+ .tdata :
+ {
+ PROVIDE_HIDDEN (__tdata_start = .);
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ }
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ }
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+ .dynamic : { *(.dynamic) }
+ . = DATA_SEGMENT_RELRO_END (0, .);
+ .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+ .data :
+ {
+ PROVIDE (__data_start = .);
+ *(.data .data.* .gnu.linkonce.d.*)
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ _edata = .; PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections.
+ FIXME: Why do we need it? When there is no .bss section, we don't
+ pad the .data section. */
+ . = ALIGN(. != 0 ? 32 / 8 : 1);
+ }
+ _bss_end__ = . ; __bss_end__ = . ;
+ . = ALIGN(32 / 8);
+ . = ALIGN(32 / 8);
+ __end__ = . ;
+ _end = .; PROVIDE (end = .);
+ . = DATA_SEGMENT_END (.);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
--- /dev/null
+
+tmpdir/fdpic-main.*: file format elf32-(little|big)arm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET TYPE VALUE
+.* R_ARM_FUNCDESC my_shared_func1
+.* R_ARM_FUNCDESC my_shared_func1
+.* R_ARM_FUNCDESC_VALUE my_shared_func1
+.* R_ARM_FUNCDESC_VALUE my_shared_func2
+
+
--- /dev/null
+ .arch armv7-r
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 2
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ .file "hello.c"
+ .text
+ .align 2
+ .syntax unified
+ .arm
+ .fpu softvfp
+ .type my_local_func, %function
+my_local_func:
+ @ args = 0, pretend = 0, frame = 0
+ @ frame_needed = 0, uses_anonymous_args = 0
+ @ link register save eliminated.
+ bx lr
+ .size my_local_func, .-my_local_func
+ .section .text.startup,"ax",%progbits
+ .align 2
+ .global _start
+ .syntax unified
+ .arm
+ .fpu softvfp
+ .type _start, %function
+_start:
+ b main
+
+ .global main
+ .syntax unified
+ .arm
+ .fpu softvfp
+ .type main, %function
+main:
+ @ args = 0, pretend = 0, frame = 0
+ @ frame_needed = 0, uses_anonymous_args = 0
+ ldr r2, .L4
+ ldr r3, .L4+4
+ push {r4, r5, r6, lr}
+ ldr r5, [r9, r2]
+ mov r4, r9
+ ldr r3, [r9, r3]
+ str r3, [r5]
+ bl my_shared_func1(PLT)
+ mov r6, r0
+ mov r9, r4
+ ldr r0, [r5]
+ mov r9, r4
+ bl my_shared_func2(PLT)
+ ldr r3, .L4+8
+ mov r9, r4
+ add r3, r3, r9
+ mov r0, r3
+ str r3, [r5]
+ mov r9, r4
+ bl my_shared_func2(PLT)
+ ldr r3, .L4+12
+ mov r9, r4
+ ldr r3, [r9, r3]
+ ldr r0, [r3]
+ mov r9, r4
+ bl my_shared_func2(PLT)
+ mov r0, r6
+ mov r9, r4
+ pop {r4, r5, r6, pc}
+.L5:
+ .align 2
+.L4:
+ .word funcptr(GOT)
+ .word my_shared_func1(GOTFUNCDESC)
+ .word my_local_func(GOTOFFFUNCDESC)
+ .word funcptr2(GOT)
+ .size main, .-main
+ .global funcptr2
+ .comm funcptr,4,4
+ .section .data.rel,"aw",%progbits
+ .align 2
+ .type funcptr2, %object
+ .size funcptr2, 4
+funcptr2:
+ .word my_shared_func1(FUNCDESC)
--- /dev/null
+
+Symbol table for image:
+ +Num +Buc: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 _edata
+ +.. +..: ........ +0 +FUNC +GLOBAL +DEFAULT +UND my_shared_func2
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 __bss_start__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +13 _end
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +13 __bss_end__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +13 __end__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT + 9 __ROFIXUP_LIST__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +12 __bss_start
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT + 9 __ROFIXUP_END__
+ +.. +..: ........ +0 +FUNC +GLOBAL +DEFAULT +UND my_shared_func1
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +13 _bss_end__
--- /dev/null
+
+tmpdir/fdpic-shared.so: file format elf32-(little|big)arm
+architecture: arm.*, flags 0x00000150:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x.*
+
+Disassembly of section .plt:
+
+.* <.plt>:
+ .*: e59fc008 ldr ip, \[pc, #8\] ; .* <.plt\+0x10>
+ .*: e08cc009 add ip, ip, r9
+ .*: e59c9004 ldr r9, \[ip, #4\]
+ .*: e59cf000 ldr pc, \[ip\]
+ .*: 0000000c .word 0x0000000c
+ .*: 00000000 .word 0x00000000
+ .*: e51fc00c ldr ip, \[pc, #-12\] ; .* <.plt\+0x14>
+ .*: e92d1000 stmfd sp!, {ip}
+ .*: e599c004 ldr ip, \[r9, #4\]
+ .*: e599f000 ldr pc, \[r9\]
+
+Disassembly of section .text:
+
+.* <my_shared_func1>:
+ .*: e12fff1e bx lr
+
+.* <my_shared_func3>:
+ .*: e3a00000 mov r0, #0
+ .*: e12fff1e bx lr
+
+.* <my_shared_func2>:
+ .*: e92d4010 push {r4, lr}
+ .*: e1a04009 mov r4, r9
+ .*: ebffffef bl .* <.plt>
+ .*: e1a09004 mov r9, r4
+ .*: e8bd8010 pop {r4, pc}
--- /dev/null
+/* Script for --shared -z combreloc: shared library, combine & sort relocs */
+OUTPUT_FORMAT("elf32-littlearm-fdpic", "elf32-bigarm-fdpic",
+ "elf32-littlearm-fdpic")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = SEGMENT_START("text-segment", 0) + SIZEOF_HEADERS;
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ .hash : { *(.hash) }
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ *(.rel.iplt)
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ *(.rela.iplt)
+ }
+ .rel.plt :
+ {
+ *(.rel.plt)
+ }
+ .rela.plt :
+ {
+ *(.rela.plt)
+ }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ .plt : { *(.plt) }
+ .iplt : { *(.iplt) }
+ .text :
+ {
+ *(.text.unlikely .text.*_unlikely)
+ *(.text.exit .text.exit.*)
+ *(.text.startup .text.startup.*)
+ *(.text.hot .text.hot.*)
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) }
+ PROVIDE_HIDDEN (__exidx_start = .);
+ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+ PROVIDE_HIDDEN (__exidx_end = .);
+ .rofixup : {
+ __ROFIXUP_LIST__ = .;
+ *(.rofixup)
+ __ROFIXUP_END__ = .;
+ }
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
+ .gcc_except_table.*) }
+ /* These sections are generated by the Sun/Oracle C++ compiler. */
+ .exception_ranges : ONLY_IF_RO { *(.exception_ranges
+ .exception_ranges*) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
+ /* Exception handling */
+ .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+ .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+ .exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
+ /* Thread Local Storage sections */
+ .tdata :
+ {
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ .preinit_array :
+ {
+ KEEP (*(.preinit_array))
+ }
+ .init_array :
+ {
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ }
+ .fini_array :
+ {
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+ .dynamic : { *(.dynamic) }
+ . = DATA_SEGMENT_RELRO_END (0, .);
+ .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+ .data :
+ {
+ PROVIDE (__data_start = .);
+ *(.data .data.* .gnu.linkonce.d.*)
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ _edata = .; PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections.
+ FIXME: Why do we need it? When there is no .bss section, we don't
+ pad the .data section. */
+ . = ALIGN(. != 0 ? 32 / 8 : 1);
+ }
+ _bss_end__ = . ; __bss_end__ = . ;
+ . = ALIGN(32 / 8);
+ . = ALIGN(32 / 8);
+ __end__ = . ;
+ _end = .; PROVIDE (end = .);
+ . = DATA_SEGMENT_END (.);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
--- /dev/null
+
+tmpdir/fdpic-shared.so: file format elf32-(little|big)arm
+
+DYNAMIC RELOCATION RECORDS
+OFFSET TYPE VALUE
+.* R_ARM_FUNCDESC_VALUE my_shared_func3
+
+
--- /dev/null
+ .arch armv7-r
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 2
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ .file "shared.c"
+ .text
+ .align 2
+ .global my_shared_func1
+ .syntax unified
+ .arm
+ .fpu softvfp
+ .type my_shared_func1, %function
+my_shared_func1:
+ @ args = 0, pretend = 0, frame = 0
+ @ frame_needed = 0, uses_anonymous_args = 0
+ @ link register save eliminated.
+ bx lr
+ .size my_shared_func1, .-my_shared_func1
+ .align 2
+ .global my_shared_func3
+ .syntax unified
+ .arm
+ .fpu softvfp
+ .type my_shared_func3, %function
+my_shared_func3:
+ @ args = 0, pretend = 0, frame = 0
+ @ frame_needed = 0, uses_anonymous_args = 0
+ @ link register save eliminated.
+ mov r0, #0
+ bx lr
+ .size my_shared_func3, .-my_shared_func3
+ .align 2
+ .global my_shared_func2
+ .syntax unified
+ .arm
+ .fpu softvfp
+ .type my_shared_func2, %function
+my_shared_func2:
+ @ args = 0, pretend = 0, frame = 0
+ @ frame_needed = 0, uses_anonymous_args = 0
+ push {r4, lr}
+ mov r4, r9
+ bl my_shared_func3(PLT)
+ mov r9, r4
+ pop {r4, pc}
+ .size my_shared_func2, .-my_shared_func2
--- /dev/null
+
+Symbol table for image:
+ +Num +Buc: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +9 _edata
+ +.. +..: ........ +20 +FUNC +GLOBAL +DEFAULT +6 my_shared_func2
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +9 __bss_start__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +9 _end
+ +.. +..: ........ +8 +FUNC +GLOBAL +DEFAULT +6 my_shared_func3
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +9 __bss_end__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +9 __end__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +7 __ROFIXUP_LIST__
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +9 __bss_start
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +7 __ROFIXUP_END__
+ +.. +..: ........ +4 +FUNC +GLOBAL +DEFAULT +6 my_shared_func1
+ +.. +..: ........ +0 +NOTYPE +GLOBAL +DEFAULT +9 _bss_end__