4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
32 #include "_inline_gen.h"
36 static Dl_amd64_unwindinfo
*
37 getunwind_core(Lm_list
*lml
, void *pc
, Dl_amd64_unwindinfo
*unwindinfo
)
42 * Validate the version information.
44 if (unwindinfo
== NULL
) {
45 eprintf(lml
, ERR_FATAL
, MSG_INTL(MSG_ARG_ILLVAL
));
48 if ((unwindinfo
->dlui_version
< DLUI_VERS_1
) ||
49 (unwindinfo
->dlui_version
> DLUI_VERS_CURRENT
)) {
50 eprintf(lml
, ERR_FATAL
, MSG_INTL(MSG_UNW_BADVERS
),
51 unwindinfo
->dlui_version
, DLUI_VERS_CURRENT
);
56 * Clean out the structure.
58 unwindinfo
->dlui_flags
= 0;
59 unwindinfo
->dlui_objname
= 0;
60 unwindinfo
->dlui_unwindstart
= 0;
61 unwindinfo
->dlui_unwindend
= 0;
62 unwindinfo
->dlui_segstart
= 0;
63 unwindinfo
->dlui_segend
= 0;
66 * Identify the link-map associated with the exception "pc". Note,
67 * the "pc" might not correspond to a link-map (as can happen with a
68 * "pc" fabricated by a debugger such as dbx). In this case, the
69 * unwind data buffer will be filled with flags set to indicate an
72 lmp
= _caller(pc
, CL_NONE
);
75 mmapobj_result_t
*mpp
;
78 * Determine the associated segment.
80 if ((mpp
= find_segment(pc
, lmp
)) == NULL
)
83 unwindinfo
->dlui_objname
= (char *)PATHNAME(lmp
);
84 unwindinfo
->dlui_segstart
= mpp
->mr_addr
;
85 unwindinfo
->dlui_segend
= mpp
->mr_addr
+ mpp
->mr_msize
;
87 if (PTUNWIND(lmp
) && (mpp
->mr_addr
)) {
90 if (FLAGS(lmp
) & FLG_RT_FIXED
)
95 unwindinfo
->dlui_unwindstart
=
96 (void *)(PTUNWIND(lmp
)->p_vaddr
+ base
);
97 unwindinfo
->dlui_unwindend
=
98 (void *)(PTUNWIND(lmp
)->p_vaddr
+
99 PTUNWIND(lmp
)->p_memsz
+ base
);
101 } else if (mpp
->mr_addr
)
102 unwindinfo
->dlui_flags
|= DLUI_FLG_NOUNWIND
;
104 unwindinfo
->dlui_flags
|=
105 DLUI_FLG_NOUNWIND
| DLUI_FLG_NOOBJ
;
110 unwindinfo
->dlui_flags
= DLUI_FLG_NOOBJ
| DLUI_FLG_NOUNWIND
;
115 #pragma weak _dlamd64getunwind = dlamd64getunwind
117 Dl_amd64_unwindinfo
*
118 dlamd64getunwind(void *pc
, Dl_amd64_unwindinfo
*unwindinfo
)
122 int entry
= enter(0);
124 lmp
= _caller(caller(), CL_EXECDEF
);
127 unwindinfo
= getunwind_core(lml
, pc
, unwindinfo
);