__EH_FRAME_BEGIN__:
.section .sdata
-5: data8 @segrel(6f)
.type dtor_ptr#,@object
.size dtor_ptr#,8
dtor_ptr:
data8 __DTOR_LIST__# + 8
-/* A handle for __cxa_finalize to manage c++ local destructors. */
+ .type segrel_ofs#,@object
+ .size segrel_ofs#,8
+segrel_ofs:
+ data8 @segrel(.Lsegrel_ref#)
+
+ /* A handle for __cxa_finalize to manage c++ local destructors. */
.global __dso_handle#
.type __dso_handle#,@object
.size __dso_handle#,8
#ifdef SHARED
-.section .data
+ .section .data
__dso_handle:
data8 __dso_handle#
#else
-.section .bss
+ .section .bss
__dso_handle:
data8 0
#endif
+#ifdef HAVE_GAS_HIDDEN
+ .hidden __dso_handle#
+#endif
-/* The frame object. */
-/* ??? How can we rationally keep this size correct? */
-
+ /* The frame object. */
+ /* ??? How can we rationally keep this size correct? */
.section .bss
.type frame_object#,@object
.size frame_object#,56
/*
* Fragment of the ELF _fini routine that invokes our dtor cleanup.
*
- * The code going into .fini is spread all over the place, thus we need
- * to save gp in order to make sure that other bits don't get into any
- * nasty surprises by expecting a gp that has suddenly changed.
+ * We make the call by indirection, because in large programs the
+ * .fini and .init sections are not in range of the destination, and
+ * we cannot allow the linker to insert a stub at the end of this
+ * fragment of the _fini function. Further, Itanium does not implement
+ * the long branch instructions, and we do not wish every program to
+ * trap to the kernel for emulation.
+ *
+ * Note that we require __do_global_dtors_aux to preserve the GP,
+ * so that the next fragment in .fini gets the right value.
*/
.section .fini,"ax","progbits"
- { .mfb
- st8 [r12] = gp, -16
- br.call.sptk.many b0 = __do_global_dtors_aux#
+ { .mlx
+ movl r2 = @gprel(__do_global_dtors_aux#)
;;
}
- { .mmi
- adds r12 = 16, r12
+ { .mii
+ nop.m 0
+ add r2 = r2, gp
;;
- ld8 gp = [r12]
+ mov b6 = r2
+ }
+ { .bbb
+ br.call.sptk.many b0 = b6
;;
}
*/
.section .init,"ax","progbits"
- { .mfb
- st8 [r12] = gp, -16
- br.call.sptk.many b0 = __do_frame_setup#
+ { .mlx
+ movl r2 = @gprel(__do_frame_setup#)
;;
}
- { .mmi
- adds r12 = 16, r12
+ { .mii
+ nop.m 0
+ add r2 = r2, gp
;;
- ld8 gp = [r12]
+ mov b6 = r2
+ }
+ { .bbb
+ br.call.sptk.many b0 = b6
;;
}
addl loc0 = @gprel(dtor_ptr#), gp
mov loc1 = b0
}
- mov loc2 = gp
+ { .mib
+ mov loc2 = gp
+ br.sptk.few 1f
+ ;;
+ }
#else
/*
if (__cxa_finalize)
addl r16 = @ltoff(@fptr(__cxa_finalize#)), gp
;;
}
- mov loc2 = gp
{ .mmi
ld8 r16 = [r16]
;;
mov loc1 = b0
;;
}
- { .mib
-(p7) ld8 gp = [r16]
+ { .mfi
+ mov loc2 = gp
(p7) mov b6 = r18
+ }
+ {
+ .mfb
+(p7) ld8 gp = [r16]
(p7) br.call.sptk.many b0 = b6
}
+ { .mfb
+ br.sptk.few 1f
+ }
#endif
/*
do {
(*(dtor_ptr-1)) ();
} while (dtor_ptr);
*/
- { .bbb
- br.sptk.few 1f
- ;;
- }
0:
{ .mmi
st8 [loc0] = r15
cmp.ne p6, p0 = r0, r16
(p6) br.cond.sptk.few 0b
}
- mov gp = loc2
- ;;
/*
if (__deregister_frame_info)
__deregister_frame_info(__EH_FRAME_BEGIN__)
*/
- { .mii
+ { .mmi
+ mov gp = loc2
+ ;;
addl r16 = @ltoff(@fptr(__deregister_frame_info#)), gp
addl out0 = @ltoff(__EH_FRAME_BEGIN__#), gp
;;
(p7) br.call.sptk.many b0 = b6
}
{ .mii
+ mov gp = loc2
mov b0 = loc1
mov ar.pfs = loc3
}
__register_frame_info(__EH_FRAME_BEGIN__)
*/
{ .mii
- alloc loc3 = ar.pfs, 0, 4, 2, 0
+ alloc loc2 = ar.pfs, 0, 3, 2, 0
addl r16 = @ltoff(@fptr(__register_frame_info#)), gp
addl out0 = @ltoff(__EH_FRAME_BEGIN__#), gp
- ;;
}
- addl out1 = @ltoff(frame_object#), gp
- ;;
/* frame_object.pc_base = segment_base_offset;
- pc_base is at offset 0 within frame_object. */
-6:
- mov loc0 = ip
- addl loc1 = @gprel(5b), gp
- ;;
- ld8 loc1 = [loc1]
- ld8 out1 = [out1]
- ;;
- sub loc2 = loc0, loc1
- ;;
- st8 [out1] = loc2
+ pc_base is at offset 0 within frame_object. */
+.Lsegrel_ref:
+ { .mmi
+ addl out1 = @ltoff(frame_object#), gp
+ ;;
+ addl r2 = @gprel(segrel_ofs#), gp
+ mov r3 = ip
+ ;;
+ }
{ .mmi
+ ld8 r2 = [r2]
ld8 r16 = [r16]
- ld8 out0 = [out0]
mov loc0 = b0
;;
}
- { .mmi
+ { .mii
+ ld8 out1 = [out1]
cmp.ne p7, p0 = r0, r16
+ sub r3 = r3, r2
;;
+ }
+ { .mmi
+ st8 [out1] = r3
(p7) ld8 r18 = [r16], 8
+ mov loc1 = gp
;;
}
+ { .mfb
+ ld8 out0 = [out0]
+ }
{ .mib
(p7) ld8 gp = [r16]
(p7) mov b6 = r18
(p7) br.call.sptk.many b0 = b6
}
{ .mii
+ mov gp = loc1
mov b0 = loc0
- mov ar.pfs = loc3
+ mov ar.pfs = loc2
}
{ .bbb
br.ret.sptk.many b0
.section .IA_64.unwind
__EH_FRAME_END__:
- data8 -1
/*
* Fragment of the ELF _init routine that invokes our dtor cleanup.
*
- * The code going into .init is spread all over the place, thus we need
- * to save gp in order to make sure that other bits don't get into any
- * nasty surprises by expecting a gp that has suddenly changed.
+ * We make the call by indirection, because in large programs the
+ * .fini and .init sections are not in range of the destination, and
+ * we cannot allow the linker to insert a stub at the end of this
+ * fragment of the _fini function. Further, Itanium does not implement
+ * the long branch instructions, and we do not wish every program to
+ * trap to the kernel for emulation.
+ *
+ * Note that we require __do_global_ctors_aux to preserve the GP,
+ * so that the next fragment in .fini gets the right value.
*/
.section .init,"ax","progbits"
- { .mfb
- st8 [r12] = gp, -16
- br.call.sptk.many b0 = __do_global_ctors_aux
+ { .mlx
+ movl r2 = @gprel(__do_global_ctors_aux#)
;;
}
- { .mmi
- adds r12 = 16, r12
+ { .mii
+ nop.m 0
+ add r2 = r2, gp
;;
- ld8 gp = [r12]
+ mov b6 = r2
+ }
+ { .bbb
+ br.call.sptk.many b0 = b6
;;
}
(*p) ();
*/
{ .mii
- alloc loc2 = ar.pfs, 0, 4, 0, 0
+ alloc loc4 = ar.pfs, 0, 5, 0, 0
addl loc0 = @ltoff(__CTOR_END__# - 8), gp
- cmp.ne p6, p0 = r0, r0
+ mov loc1 = b0
;;
}
- { .mfi
+ { .mmi
ld8 loc0 = [loc0]
- mov loc1 = b0
+ ;;
+ ld8 loc3 = [loc0], -8
+ mov loc2 = gp
+ ;;
+ }
+ { .mfb
+ cmp.eq p6, p0 = -1, loc3
+(p6) br.cond.spnt.few 2f
}
0:
{ .mmi
-(p6) ld8 r15 = [loc3], 8
+ ld8 r15 = [loc3], 8
;;
-(p6) ld8 gp = [loc3]
-(p6) mov b6 = r15
+ ld8 gp = [loc3]
+ mov b6 = r15
}
{ .mfb
ld8 loc3 = [loc0], -8
-(p6) br.call.sptk.many b0 = b6
+ br.call.sptk.many b0 = b6
;;
}
{ .mfb
cmp.ne p6, p0 = -1, loc3
(p6) br.cond.sptk.few 0b
}
+2:
{ .mii
- mov ar.pfs = loc2
+ mov gp = loc2
mov b0 = loc1
+ mov ar.pfs = loc4
}
{ .bbb
br.ret.sptk.many b0