tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.h
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc.  All Rights Reserved.
       
     4 
       
     5   This program is free software; you can redistribute it and/or modify it
       
     6   under the terms of version 2.1 of the GNU Lesser General Public License 
       
     7   as published by the Free Software Foundation.
       
     8 
       
     9   This program is distributed in the hope that it would be useful, but
       
    10   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
       
    12 
       
    13   Further, this software is distributed without any warranty that it is
       
    14   free of the rightful claim of any third person regarding infringement 
       
    15   or the like.  Any license provided herein, whether implied or 
       
    16   otherwise, applies only to this software file.  Patent licenses, if
       
    17   any, provided herein do not apply to combinations of this program with 
       
    18   other software, or any other product whatsoever.  
       
    19 
       
    20   You should have received a copy of the GNU Lesser General Public
       
    21   License along with this program; if not, write the Free Software
       
    22   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    23   USA.
       
    24 
       
    25   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    26   Mountain View, CA 94043, or:
       
    27 
       
    28   http://www.sgi.com
       
    29 
       
    30   For further information regarding this notice, see:
       
    31 
       
    32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    33 
       
    34 */
       
    35 
       
    36 
       
    37 
       
    38 /* The dwarf 2.0 standard dictates that only the following
       
    39  * fields can be read when an unexpected augmentation string
       
    40  * (in the cie) is encountered: CIE length, CIE_id, version and
       
    41  * augmentation; FDE: length, CIE pointer, initial location and
       
    42  * address range. Unfortunately, with the above restrictions, it
       
    43  * is impossible to read the instruction table from a CIE or a FDE
       
    44  * when a new augmentation string is encountered.
       
    45  * To fix this problem, the following layout is used, if the
       
    46  * augmentation string starts with the string "z".
       
    47  *   CIE                        FDE
       
    48  *   length                     length
       
    49  *   CIE_id                     CIE_pointer
       
    50  *   version                    initial_location
       
    51  *   augmentation               address_range
       
    52  *                              length_of_augmented_fields (*NEW*)
       
    53  *   code_alignment_factor      Any new fields as necessary
       
    54  *   data_alignment_factor      instruction_table
       
    55  *   return_address
       
    56  *   length_of_augmented fields
       
    57  *   Any new fields as necessary
       
    58  *   initial_instructions
       
    59  *
       
    60  * The type of all the old data items are the same as what is
       
    61  * described in dwarf 2.0 standard. The length_of_augmented_fields
       
    62  * is an LEB128 data item that denotes the size (in bytes) of
       
    63  * the augmented fields (not including the size of
       
    64  * "length_of_augmented_fields" itself).
       
    65  
       
    66  * Handling of cie augmentation strings is necessarly a heuristic.
       
    67  * See dwarf_frame.c for the currently known augmentation strings.
       
    68 
       
    69 
       
    70    ---START SGI-ONLY COMMENT:
       
    71  * SGI-IRIX versions of cie or fde  were intended to use "z1", "z2" as the
       
    72  * augmenter strings if required for new augmentation.
       
    73  * However, that never happened (as of March 2005).
       
    74  *
       
    75  * The fde's augmented by the string "z" have a new field 
       
    76  * (signed constant, 4 byte field)
       
    77  * called offset_into_exception_tables, following the 
       
    78  * length_of_augmented field.   This field contains an offset 
       
    79  * into the "_MIPS_eh_region", which describes
       
    80  * the IRIX CC exception handling tables.
       
    81    ---END SGI-ONLY COMMENT
       
    82  
       
    83 
       
    84  * GNU .eh_frame has an augmentation string of z[RLP]* (gcc 3.4)
       
    85  * The similarity to IRIX 'z' (and proposed but never
       
    86  * implemented IRIX z1, z2 etc) was confusing things.
       
    87  * If the section is .eh_frame then 'z' means GNU exception
       
    88  * information 'Augmentation Data' not IRIX 'z'.
       
    89  * See The Linux Standard Base Core Specification version 3.0
       
    90  */
       
    91 
       
    92 #define DW_DEBUG_FRAME_VERSION                 	1 /* DWARF2 */
       
    93 #define DW_DEBUG_FRAME_VERSION3                	3 /* DWARF3 */
       
    94 #define DW_DEBUG_FRAME_AUGMENTER_STRING     	"mti v1"
       
    95 
       
    96 /* The value of the offset field for Cie's. */
       
    97 #define DW_CIE_OFFSET		~(0x0)
       
    98 
       
    99 /* The augmentation string may be NULL.	*/
       
   100 #define DW_EMPTY_STRING		""
       
   101 
       
   102 #define DW_FRAME_INSTR_OPCODE_SHIFT		6
       
   103 #define DW_FRAME_INSTR_OFFSET_MASK		0x3f
       
   104 
       
   105 /* 
       
   106     This struct denotes the rule for a register in a row of
       
   107     the frame table.  In other words, it is one element of 
       
   108     the table.
       
   109 */
       
   110 struct Dwarf_Reg_Rule_s {
       
   111 
       
   112     /* 
       
   113        Is a flag indicating whether the rule includes the offset
       
   114        field, ie whether the ru_offset field is valid or not. 
       
   115        Applies only if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET.
       
   116        It is important, since reg+offset (offset of 0) is different from
       
   117        just 'register' since the former means 'read memory at address
       
   118        given by the sum of register contents plus offset to get the
       
   119        value'. whereas the latter means 'the value is in the register'.
       
   120 
       
   121        The 'register' numbers are either real registers (ie, table
       
   122        columns defined as real registers) or defined entries that are
       
   123        not really hardware registers, such as DW_FRAME_SAME_VAL or
       
   124        DW_FRAME_CFA_COL.
       
   125 
       
   126      */
       
   127     Dwarf_Sbyte ru_is_off; 
       
   128 
       
   129     /* DW_EXPR_OFFSET (0, DWARF2)  
       
   130        DW_EXPR_VAL_OFFSET 1 (dwarf2/3)
       
   131        DW_EXPR_EXPRESSION 2  (dwarf2/3)
       
   132 	DW_EXPR_VAL_EXPRESSION 3 (dwarf2/3) 
       
   133        See dwarf_frame.h. */
       
   134     Dwarf_Sbyte ru_value_type;
       
   135 
       
   136     /* Register involved in this rule. */
       
   137     Dwarf_Half ru_register;
       
   138 
       
   139     /* Offset to add to register, if indicated by ru_is_offset
       
   140        and if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. 
       
   141        If DW_EXPR_EXPRESSION or DW_EXPR_VAL_EXPRESSION
       
   142        this is DW_FORM_block block-length, not offset. */
       
   143     Dwarf_Unsigned ru_offset_or_block_len;
       
   144     
       
   145     /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set,
       
   146        else 0. */
       
   147     Dwarf_Small *ru_block;
       
   148 };
       
   149 
       
   150 typedef struct Dwarf_Frame_s *Dwarf_Frame;
       
   151 
       
   152 /* 
       
   153     This structure represents a row of the frame table. 
       
   154     Fr_loc is the pc value for this row, and Fr_reg
       
   155     contains the rule for each column.
       
   156 
       
   157     Entry DW_FRAME_CFA_COL of fr_reg was the tradional MIPS
       
   158     way of setting CFA.  cfa_rule is the new one.
       
   159 */
       
   160 struct Dwarf_Frame_s {
       
   161 
       
   162     /* Pc value corresponding to this row of the frame table. */
       
   163     Dwarf_Addr fr_loc;
       
   164 
       
   165     /* Rules for all the registers in this row. */
       
   166     struct Dwarf_Reg_Rule_s fr_cfa_rule;
       
   167 
       
   168 	/* fr_reg_count is the the number of
       
   169 	entries of the fr_reg array. */
       
   170     unsigned long            fr_reg_count;
       
   171     struct Dwarf_Reg_Rule_s *fr_reg;
       
   172 
       
   173     Dwarf_Frame fr_next;
       
   174 };
       
   175 
       
   176 typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List;
       
   177 
       
   178 /* This is used to chain together Dwarf_Frame_Op structures. */
       
   179 struct Dwarf_Frame_Op_List_s {
       
   180     Dwarf_Frame_Op *fl_frame_instr;
       
   181     Dwarf_Frame_Op_List fl_next;
       
   182 };
       
   183 
       
   184 /* See dwarf_frame.c for the heuristics used to set the
       
   185    Dwarf_Cie ci_augmentation_type.  
       
   186 
       
   187    This succinctly helps interpret the size and meaning of .debug_frame
       
   188    and (for gcc) .eh_frame.
       
   189 
       
   190    In the case of gcc .eh_frame (gcc 3.3, 3.4)
       
   191    z may be followed by one or more of
       
   192    L R P.  
       
   193 
       
   194 */
       
   195 enum Dwarf_augmentation_type {
       
   196         aug_empty_string, /* Default empty augmentation string.  */
       
   197         aug_irix_exception_table,  /* IRIX  plain  "z",
       
   198                    for exception handling, IRIX CC compiler.
       
   199 		   Proposed z1 z2 ... never implemented.  */
       
   200         aug_gcc_eh_z,       /* gcc z augmentation,  (including
       
   201 			L R P variations). gcc 3.3 3.4 exception
       
   202 			handling in eh_frame.  */
       
   203         aug_irix_mti_v1,  /* IRIX "mti v1" augmentation string. Probably
       
   204                              never in any released SGI-IRIX compiler. */
       
   205         aug_eh,           /* For gcc .eh_frame, "eh" is the string.,
       
   206 				gcc 1,2, egcs. Older values.  */
       
   207         aug_unknown,      /* Unknown augmentation, we cannot do much. */
       
   208         aug_past_last
       
   209 };
       
   210 
       
   211 
       
   212 /* 
       
   213     This structure contains all the pertinent info for a Cie. Most 
       
   214     of the fields are taken straight from the definition of a Cie.  
       
   215     Ci_cie_start points to the address (in .debug_frame) where this 
       
   216     Cie begins.  Ci_cie_instr_start points to the first byte of the 
       
   217     frame instructions for this Cie.  Ci_dbg points to the associated 
       
   218     Dwarf_Debug structure.  Ci_initial_table is a pointer to the table 
       
   219     row generated by the instructions for this Cie.
       
   220 */
       
   221 struct Dwarf_Cie_s {
       
   222     Dwarf_Word ci_length;
       
   223     char *ci_augmentation;
       
   224     Dwarf_Small ci_code_alignment_factor;
       
   225     Dwarf_Sbyte ci_data_alignment_factor;
       
   226     Dwarf_Small ci_return_address_register;
       
   227     Dwarf_Small *ci_cie_start;
       
   228     Dwarf_Small *ci_cie_instr_start;
       
   229     Dwarf_Debug ci_dbg;
       
   230     Dwarf_Frame ci_initial_table;
       
   231     Dwarf_Cie ci_next;
       
   232     Dwarf_Small ci_length_size;
       
   233     Dwarf_Small ci_extension_size;
       
   234     Dwarf_Half ci_cie_version_number;
       
   235     enum Dwarf_augmentation_type ci_augmentation_type;	 
       
   236 
       
   237     /* The following 2 for GNU .eh_frame exception handling
       
   238        Augmentation Data. Set if ci_augmentation_type
       
   239        is aug_gcc_eh_z. Zero if unused. */
       
   240     Dwarf_Unsigned ci_gnu_eh_augmentation_len;
       
   241     Dwarf_Ptr      ci_gnu_eh_augmentation_bytes;
       
   242 
       
   243     /* These are extracted from the gnu eh_frame
       
   244        augmentation if the
       
   245        augmentation begins with 'z'. See Linux LSB documents.
       
   246        Otherwize these are zero. */
       
   247     unsigned char    ci_gnu_personality_handler_encoding;
       
   248     unsigned char    ci_gnu_lsda_encoding;
       
   249     unsigned char    ci_gnu_fde_begin_encoding;
       
   250 
       
   251     /* If 'P' augmentation present, is handler addr. Else
       
   252 	is zero. */
       
   253     Dwarf_Addr     ci_gnu_personality_handler_addr;
       
   254 
       
   255 
       
   256     /* In creating list of cie's (which will become an array)
       
   257        record the position so fde can get it on fde creation. */
       
   258     Dwarf_Unsigned ci_index;
       
   259     Dwarf_Small *  ci_section_ptr;
       
   260 };
       
   261 
       
   262 /*
       
   263 	This structure contains all the pertinent info for a Fde.
       
   264 	Most of the fields are taken straight from the definition.
       
   265 	fd_cie_index is the index of the Cie associated with this
       
   266 	Fde in the list of Cie's for this debug_frame.  Fd_cie
       
   267 	points to the corresponsing Dwarf_Cie structure.  Fd_fde_start
       
   268 	points to the start address of the Fde.  Fd_fde_instr_start
       
   269 	points to the start of the instructions for this Fde.  Fd_dbg
       
   270 	points to the associated Dwarf_Debug structure.
       
   271 */
       
   272 struct Dwarf_Fde_s {
       
   273     Dwarf_Unsigned fd_length;
       
   274     Dwarf_Addr fd_cie_offset;
       
   275     Dwarf_Unsigned fd_cie_index;
       
   276     Dwarf_Cie fd_cie;
       
   277     Dwarf_Addr fd_initial_location;
       
   278     Dwarf_Small *fd_initial_loc_pos;
       
   279     Dwarf_Addr fd_address_range;
       
   280     Dwarf_Small *fd_fde_start;
       
   281     Dwarf_Small *fd_fde_instr_start;
       
   282     Dwarf_Debug fd_dbg;
       
   283 
       
   284 	/* fd_offset_into_exception_tables is SGI/IRIX exception table
       
   285 	   offset. Unused and zero if not IRIX .debug_frame. */
       
   286     Dwarf_Signed fd_offset_into_exception_tables;
       
   287 
       
   288     Dwarf_Fde fd_next;
       
   289     Dwarf_Small fd_length_size;
       
   290     Dwarf_Small fd_extension_size;
       
   291     /* The following 2 for GNU .eh_frame exception handling
       
   292        Augmentation Data. Set if CIE ci_augmentation_type
       
   293        is aug_gcc_eh_z. Zero if unused. */
       
   294     Dwarf_Unsigned fd_gnu_eh_augmentation_len;
       
   295     Dwarf_Ptr fd_gnu_eh_augmentation_bytes;
       
   296     Dwarf_Addr fd_gnu_eh_lsda; /* If 'L' augmentation letter
       
   297          present:  is address of the 
       
   298          Language Specific Data Area (LSDA). If not 'L" is zero. */
       
   299 
       
   300     /* The following 3 are about the Elf section the FDEs come from. */
       
   301     Dwarf_Small * fd_section_ptr;
       
   302     Dwarf_Unsigned fd_section_length;
       
   303     Dwarf_Unsigned fd_section_index; 
       
   304 
       
   305 };
       
   306 
       
   307 
       
   308 int
       
   309   _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
       
   310 			       Dwarf_Off ** offsetlist,
       
   311 			       Dwarf_Signed * returncount,
       
   312 			       Dwarf_Error * err);
       
   313 
       
   314 int
       
   315 _dwarf_get_fde_list_internal(Dwarf_Debug dbg,
       
   316                               Dwarf_Cie ** cie_data,
       
   317                               Dwarf_Signed * cie_element_count,
       
   318                               Dwarf_Fde ** fde_data,
       
   319                               Dwarf_Signed * fde_element_count,
       
   320                               Dwarf_Small * section_ptr,
       
   321                               Dwarf_Unsigned section_index,
       
   322                               Dwarf_Unsigned section_length,
       
   323                               Dwarf_Unsigned cie_id_value,
       
   324                               int use_gnu_cie_calc,  /* If non-zero,
       
   325                                 this is gcc eh_frame. */
       
   326                               Dwarf_Error * error);
       
   327 
       
   328 enum Dwarf_augmentation_type
       
   329 _dwarf_get_augmentation_type(Dwarf_Debug dbg,
       
   330         Dwarf_Small *augmentation_string,
       
   331         int is_gcc_eh_frame);
       
   332 
       
   333 Dwarf_Unsigned _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr,
       
   334                         int version,
       
   335                         unsigned long *size);
       
   336 
       
   337 /* Temporary recording of crucial cie/fde prefix data.
       
   338  * Vastly simplifies some argument lists.
       
   339  */
       
   340 struct cie_fde_prefix_s {
       
   341    Dwarf_Small *  cf_start_addr;
       
   342    Dwarf_Small *  cf_addr_after_prefix;
       
   343    Dwarf_Unsigned cf_length;
       
   344    int            cf_local_length_size;
       
   345    int            cf_local_extension_size;
       
   346    Dwarf_Unsigned cf_cie_id;
       
   347    Dwarf_Small *  cf_cie_id_addr; /* used for eh_frame calculations. */
       
   348 
       
   349    /* Simplifies passing around these values to create fde having
       
   350       these here. */
       
   351    Dwarf_Small *  cf_section_ptr;
       
   352    Dwarf_Unsigned cf_section_index; 
       
   353    Dwarf_Unsigned cf_section_length; 
       
   354 };
       
   355 
       
   356 int
       
   357 _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
       
   358                         Dwarf_Frame_Op ** ret_frame_instr,
       
   359                         Dwarf_Bool search_pc,
       
   360                         Dwarf_Addr search_pc_val,
       
   361                         Dwarf_Addr initial_loc,
       
   362                         Dwarf_Small * start_instr_ptr,
       
   363                         Dwarf_Small * final_instr_ptr,
       
   364                         Dwarf_Frame table,
       
   365                         Dwarf_Cie cie,
       
   366                         Dwarf_Debug dbg,
       
   367 			Dwarf_Half reg_num_of_cfa,
       
   368                         Dwarf_Sword * returned_count,
       
   369                         int *returned_error);
       
   370 
       
   371 
       
   372 int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
       
   373         Dwarf_Small *frame_ptr_in,
       
   374         Dwarf_Small *section_ptr_in,
       
   375         Dwarf_Unsigned section_index_in,
       
   376 	Dwarf_Unsigned section_length_in,
       
   377         struct cie_fde_prefix_s *prefix_out,
       
   378         Dwarf_Error *error);
       
   379 
       
   380 int dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
       
   381         struct cie_fde_prefix_s *  prefix,
       
   382         Dwarf_Small *section_pointer,
       
   383         Dwarf_Small *frame_ptr,
       
   384         int use_gnu_cie_calc,
       
   385         Dwarf_Cie  cie_ptr_in,
       
   386         Dwarf_Fde *fde_ptr_out,
       
   387         Dwarf_Error *error);
       
   388 
       
   389 int dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
       
   390         struct cie_fde_prefix_s *prefix,
       
   391         Dwarf_Small* section_pointer,
       
   392         Dwarf_Small* frame_ptr,
       
   393         Dwarf_Unsigned cie_count,
       
   394         int use_gnu_cie_calc,
       
   395         Dwarf_Cie *cie_ptr_out,
       
   396         Dwarf_Error *error);
       
   397 
       
   398 
       
   399 int _dwarf_frame_constructor(Dwarf_Debug dbg,void * );
       
   400 void _dwarf_frame_destructor (void *);