+Sun Oct 26 11:41:49 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * dwarf2out.c (output_call_frame_info): The CIE pointer is now a 32
+ bit PC-relative offset. The exception range table pointer is now in
+ the CIE.
+ * frame.c (dwarf_cie, dwarf_fde): Rename CIE_pointer to CIE_delta.
+ (count_fdes, add_fdes, get_cie): Adjust.
+ (cie_info, extract_cie_info, __frame_state_for): Adjust eh_ptr uses.
+
+ From H.J. Lu:
+ * frame.c (count_fdes, add_fdes): Skip linked once FDE entries.
+
Sun Oct 26 11:52:01 1997 Richard Henderson <rth@cygnus.com>
* alias.c (memrefs_conflict_p): Treat arg_pointer_rtx just
fputc ('\n', asm_out_file);
ASM_OUTPUT_LABEL (asm_out_file, l1);
- ASM_OUTPUT_DWARF_DATA4 (asm_out_file, DW_CIE_ID);
+ if (for_eh)
+ /* Now that the CIE pointer is PC-relative for EH,
+ use 0 to identify the CIE. */
+ ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
+ else
+ ASM_OUTPUT_DWARF_DATA4 (asm_out_file, DW_CIE_ID);
+
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s CIE Identifier Tag", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- if (for_eh ? PTR_SIZE == 8 : DWARF_OFFSET_SIZE == 8)
+ if (! for_eh && DWARF_OFFSET_SIZE == 8)
{
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, DW_CIE_ID);
fputc ('\n', asm_out_file);
fputc ('\n', asm_out_file);
if (eh_ptr)
{
- /* The FDE contains a pointer
- to the exception region info for the frame. */
- ASM_OUTPUT_DWARF_STRING (asm_out_file, "e");
+ /* The CIE contains a pointer to the exception region info for the
+ frame. Make the augmentation string three bytes (including the
+ trailing null) so the pointer is 4-byte aligned. The Solaris ld
+ can't handle unaligned relocs. */
+ ASM_OUTPUT_DWARF_STRING (asm_out_file, "eh");
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s CIE Augmentation", ASM_COMMENT_START);
+ fputc ('\n', asm_out_file);
+
+ ASM_OUTPUT_DWARF_ADDR (asm_out_file, "__EXCEPTION_TABLE__");
+ if (flag_debug_asm)
+ fprintf (asm_out_file, "\t%s pointer to exception region info",
+ ASM_COMMENT_START);
}
else
{
ASM_OUTPUT_LABEL (asm_out_file, l1);
if (for_eh)
- ASM_OUTPUT_DWARF_ADDR (asm_out_file, "__FRAME_BEGIN__");
+ ASM_OUTPUT_DWARF_DELTA (asm_out_file, ".", "__FRAME_BEGIN__");
else
ASM_OUTPUT_DWARF_OFFSET (asm_out_file, stripattributes (FRAME_SECTION));
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s FDE address range", ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- if (eh_ptr)
- {
- /* For now, a pointer to the translation unit's info will do.
- ??? Eventually this should point to the function's info. */
- ASM_OUTPUT_DWARF_ADDR (asm_out_file, "__EXCEPTION_TABLE__");
- if (flag_debug_asm)
- fprintf (asm_out_file, "\t%s pointer to exception region info",
- ASM_COMMENT_START);
- fputc ('\n', asm_out_file);
- }
/* Loop through the Call Frame Instructions associated with
this FDE. */
/* Some types used by the DWARF 2 spec. */
-typedef unsigned int uword __attribute__ ((mode (SI)));
-typedef unsigned int uaddr __attribute__ ((mode (pointer)));
-typedef int saddr __attribute__ ((mode (pointer)));
+typedef int sword __attribute__ ((mode (SI)));
+typedef unsigned int uword __attribute__ ((mode (SI)));
+typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+typedef int saddr __attribute__ ((mode (pointer)));
typedef unsigned char ubyte;
/* The first few fields of a CIE. The CIE_id field is 0xffffffff for a CIE,
struct dwarf_cie {
uword length;
- uaddr CIE_id;
+ sword CIE_id;
ubyte version;
char augmentation[0];
} __attribute__ ((packed, aligned (__alignof__ (void *))));
struct dwarf_fde {
uword length;
- struct dwarf_cie* CIE_pointer;
+ sword CIE_delta;
void* pc_begin;
uaddr pc_range;
} __attribute__ ((packed, aligned (__alignof__ (void *))));
struct cie_info {
char *augmentation;
+ void *eh_ptr;
int code_align;
int data_align;
unsigned ra_regno;
for (count = 0; this_fde->length != 0; this_fde = next_fde (this_fde))
{
- /* Skip CIEs. */
- if ((uaddr)(this_fde->CIE_pointer) == (uaddr)-1)
+ /* Skip CIEs and linked once FDE entries. */
+ if (this_fde->CIE_delta == 0 || this_fde->pc_range == 0)
continue;
++count;
for (; this_fde->length != 0; this_fde = next_fde (this_fde))
{
- /* Skip CIEs. */
- if ((uaddr)(this_fde->CIE_pointer) == (uaddr)-1)
+ /* Skip CIEs and linked once FDE entries. */
+ if (this_fde->CIE_delta == 0 || this_fde->pc_range == 0)
continue;
fde_insert (array, i++, this_fde);
return 0;
}
\f
+static inline struct dwarf_cie *
+get_cie (fde *f)
+{
+ return ((void *)&f->CIE_delta) - f->CIE_delta;
+}
+
/* Extract any interesting information from the CIE for the translation
unit F belongs to. */
void *p;
int i;
- c->augmentation = f->CIE_pointer->augmentation;
+ c->augmentation = get_cie (f)->augmentation;
if (strcmp (c->augmentation, "") != 0
- && strcmp (c->augmentation, "e") != 0
+ && strcmp (c->augmentation, "eh") != 0
&& c->augmentation[0] != 'z')
return 0;
p = c->augmentation + strlen (c->augmentation) + 1;
+ if (strcmp (c->augmentation, "eh") == 0)
+ {
+ c->eh_ptr = read_pointer (p);
+ p += sizeof (void *);
+ }
+ else
+ c->eh_ptr = 0;
+
p = decode_uleb128 (p, &c->code_align);
p = decode_sleb128 (p, &c->data_align);
c->ra_regno = *(unsigned char *)p++;
memset (&state, 0, sizeof (state));
state.s.retaddr_column = info.ra_regno;
+ state.s.eh_ptr = info.eh_ptr;
/* First decode all the insns in the CIE. */
- end = next_fde ((fde*) f->CIE_pointer);
+ end = next_fde ((fde*) get_cie (f));
while (insn < end)
insn = execute_cfa_insn (insn, &state, &info, 0);
insn = decode_uleb128 (insn, &i);
insn += i;
}
- else if (strcmp (info.augmentation, "e") == 0)
- {
- state.s.eh_ptr = read_pointer (insn);
- insn += sizeof (void *);
- }
/* Then the insns in the FDE up to our target PC. */
end = next_fde (f);