From d84e64d416af881a3dbc9eed8dd0212cc473baf8 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sun, 26 Oct 1997 19:54:42 +0000 Subject: [PATCH] dwarf2out.c (output_call_frame_info): The CIE pointer is now a 32 bit PC-relative offset. * 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. From-SVN: r16192 --- gcc/ChangeLog | 12 ++++++++++++ gcc/dwarf2out.c | 36 ++++++++++++++++++++---------------- gcc/frame.c | 46 +++++++++++++++++++++++++++++----------------- 3 files changed, 61 insertions(+), 33 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d95d6c3ca0..88005429c9c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Sun Oct 26 11:41:49 1997 Jason Merrill + + * 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 * alias.c (memrefs_conflict_p): Treat arg_pointer_rtx just diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index eebac520cac..45b60d6e11b 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -1532,12 +1532,18 @@ output_call_frame_info (for_eh) 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); @@ -1550,11 +1556,19 @@ output_call_frame_info (for_eh) 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 { @@ -1605,7 +1619,7 @@ output_call_frame_info (for_eh) 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) @@ -1623,16 +1637,6 @@ output_call_frame_info (for_eh) 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. */ diff --git a/gcc/frame.c b/gcc/frame.c index b13167e62a2..ca0bb39de80 100644 --- a/gcc/frame.c +++ b/gcc/frame.c @@ -46,9 +46,10 @@ Boston, MA 02111-1307, USA. */ /* 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, @@ -57,7 +58,7 @@ typedef unsigned char ubyte; struct dwarf_cie { uword length; - uaddr CIE_id; + sword CIE_id; ubyte version; char augmentation[0]; } __attribute__ ((packed, aligned (__alignof__ (void *)))); @@ -66,7 +67,7 @@ struct dwarf_cie { struct dwarf_fde { uword length; - struct dwarf_cie* CIE_pointer; + sword CIE_delta; void* pc_begin; uaddr pc_range; } __attribute__ ((packed, aligned (__alignof__ (void *)))); @@ -92,6 +93,7 @@ static struct object *objects; struct cie_info { char *augmentation; + void *eh_ptr; int code_align; int data_align; unsigned ra_regno; @@ -217,8 +219,8 @@ count_fdes (fde *this_fde) 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; @@ -237,8 +239,8 @@ add_fdes (fde *this_fde, fde **array, size_t *i_ptr, 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); @@ -332,6 +334,12 @@ find_fde (void *pc) return 0; } +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. */ @@ -341,15 +349,23 @@ extract_cie_info (fde *f, struct cie_info *c) 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++; @@ -576,9 +592,10 @@ __frame_state_for (void *pc_target, struct frame_state *state_in) 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); @@ -590,11 +607,6 @@ __frame_state_for (void *pc_target, struct frame_state *state_in) 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); -- 2.30.2