--- /dev/null
+# Checking that our relocations against the symbol __EH_FRAME_BEGIN__ are not
+# transformed into relocations against the section symbol .eh_frame.
+#as: -march=morello+c64
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+.* <get_eh_frame_begin>:
+ *[0-9a-f]+: ........ stp c29, c30, \[csp, #-64\]!
+ *[0-9a-f]+: ........ adrp c0, 0 <get_eh_frame_begin>
+ 4: R_MORELLO_ADR_PREL_PG_HI20 __EH_FRAME_BEGIN__
+ *[0-9a-f]+: ........ adrp c0, 0 <get_eh_frame_begin>
+ 8: R_MORELLO_ADR_PREL_PG_HI20 \.eh_frame
+ *[0-9a-f]+: ........ add c0, c0, #0x0
+ c: R_AARCH64_ADD_ABS_LO12_NC __EH_FRAME_BEGIN__
+ *[0-9a-f]+: ........ add c0, c0, #0x0
+ 10: R_AARCH64_ADD_ABS_LO12_NC \.eh_frame
+ *[0-9a-f]+: ........ ldp c29, c30, \[csp\], #64
+ *[0-9a-f]+: ........ ret c30
+
+#...
--- /dev/null
+.section .eh_frame,"a"
+.type __EH_FRAME_BEGIN__, %object
+__EH_FRAME_BEGIN__:
+
+.text
+.type get_eh_frame_begin, %function
+get_eh_frame_begin:
+ .cfi_startproc purecap
+ stp c29, c30, [csp, -64]!
+ .cfi_def_cfa_offset 64
+ .cfi_offset 227, -64
+ .cfi_offset 228, -48
+ adrp c0, __EH_FRAME_BEGIN__
+ adrp c0, .eh_frame
+ add c0, c0, :lo12:__EH_FRAME_BEGIN__
+ add c0, c0, :lo12:.eh_frame
+ ldp c29, c30, [csp], 64
+ .cfi_restore 228
+ .cfi_restore 227
+ .cfi_def_cfa_offset 0
+ ret
+ .cfi_endproc
+
+.global _start
+.type _start, %function
+_start:
+ mov x0, #0
+ ret
+
+# .zero 0xff0 - 0x38 - 0x78
+.zero 0xff0 - 0x38
continue;
}
+ /* Avoid adjusting a relocation against a symbol pointing into a
+ ".eh_frame" section in an ELF binary. The GNU bfd linker attempts
+ to de-duplicate CIE/FDE's in *output* .eh_frame sections in ELF
+ binaries and adjust any relocations pointing at the now removed
+ duplicate to point to the remaining entry.
+ Hence a symbol which had been adjusted to a section symbol plus
+ offset would end up pointing at something completely different.
+
+ We can not robustly match the exact linker-input sections that will
+ end up in the .eh_frame output section, since users may provide
+ their own linker scripts. However it does seem useful to avoid
+ transforming symbols in the sections that are expected to end up in
+ this linker output section. Rather than add a clause here to match
+ the current default linker script we use the same check based on
+ section name as is used in `gas/dw2gencfi.c` to check for .eh_frame
+ sections. */
+ if (IS_ELF
+ && strncmp (segment_name (symsec),
+ ".eh_frame", sizeof ".eh_frame" - 1) == 0
+ && segment_name (symsec)[9] != '_')
+ continue;
+
/* Never adjust a reloc against local symbol in a merge section
with non-zero addend. */
if ((symsec->flags & SEC_MERGE) != 0