1 /* 2 3 Copyright (C) 2000 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, 23 USA. 24 25 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 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 * This implementation of libdwarf will assume that the length of 66 * augmented fields follow the augmenter string when the augmentation 67 * starts with the string "z". It will skip over any augmented fields 68 * that it does not understand to the start of initial instructions 69 * (in case of CIE) or the instruction table (in case of FDE). 70 * 71 * Future sgi versions of cie or fde should use "z1", "z2" as the 72 * augmenter strings and it should guarantee that all the above fields 73 * are laid out in the same fashion. Older libraries will continue to be able 74 * to read all the old data, skipping over newly added data items. 75 * 76 * The fde's augmented by the string "z" have a new field (signed constant, 4 77 byte field) 78 * called offset_into_exception_tables, following the length_of_augmented field. 79 * This field contains an offset into the "_MIPS_eh_region", which describes 80 * the exception handling tables. 81 */ 82 83 #define DW_DEBUG_FRAME_VERSION 1 84 #define DW_DEBUG_FRAME_AUGMENTER_STRING "mti v1" 85 86 /* The value of the offset field for Cie's. */ 87 #define DW_CIE_OFFSET ~(0x0) 88 89 /* The augmentation string may be NULL. */ 90 #define DW_EMPTY_STRING "" 91 92 #define DW_FRAME_INSTR_OPCODE_SHIFT 6 93 #define DW_FRAME_INSTR_OFFSET_MASK 0x3f 94 95 /* 96 This struct denotes the rule for a register in a row of 97 the frame table. In other words, it is one element of 98 the table. 99 */ 100 struct Dwarf_Reg_Rule_s { 101 102 /* 103 Is a flag indicating whether the rule includes the offset 104 field, ie whether the ru_offset field is valid or not. It is 105 important, since reg+offset (offset of 0) is different from 106 just 'register' since the former means 'read memory at address 107 given by the sum of register contents plus offset to get the 108 value'. whereas the latter means 'the value is in the register'. 109 110 The 'register' numbers are either real registers (ie, table 111 columns defined as real registers) or defined entries that are 112 not really hardware registers, such as DW_FRAME_SAME_VAL or 113 DW_FRAME_CFA_COL. 114 115 */ 116 Dwarf_Sbyte ru_is_off; 117 118 /* Register involved in this rule. */ 119 Dwarf_Half ru_register; 120 121 /* Offset to add to register, if indicated by ru_is_offset. */ 122 Dwarf_Addr ru_offset; 123 }; 124 125 typedef struct Dwarf_Frame_s *Dwarf_Frame; 126 127 /* 128 This structure represents a row of the frame table. 129 Fr_loc is the pc value for this row, and Fr_reg 130 contains the rule for each column. 131 */ 132 struct Dwarf_Frame_s { 133 134 /* Pc value corresponding to this row of the frame table. */ 135 Dwarf_Addr fr_loc; 136 137 /* Rules for all the registers in this row. */ 138 struct Dwarf_Reg_Rule_s fr_reg[DW_FRAME_LAST_REG_NUM]; 139 140 Dwarf_Frame fr_next; 141 }; 142 143 typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List; 144 145 /* This is used to chain together Dwarf_Frame_Op structures. */ 146 struct Dwarf_Frame_Op_List_s { 147 Dwarf_Frame_Op *fl_frame_instr; 148 Dwarf_Frame_Op_List fl_next; 149 }; 150 151 /* 152 This structure contains all the pertinent info for a Cie. Most 153 of the fields are taken straight from the definition of a Cie. 154 Ci_cie_start points to the address (in .debug_frame) where this 155 Cie begins. Ci_cie_instr_start points to the first byte of the 156 frame instructions for this Cie. Ci_dbg points to the associated 157 Dwarf_Debug structure. Ci_initial_table is a pointer to the table 158 row generated by the instructions for this Cie. 159 */ 160 struct Dwarf_Cie_s { 161 Dwarf_Word ci_length; 162 char *ci_augmentation; 163 Dwarf_Small ci_code_alignment_factor; 164 Dwarf_Sbyte ci_data_alignment_factor; 165 Dwarf_Small ci_return_address_register; 166 Dwarf_Small *ci_cie_start; 167 Dwarf_Small *ci_cie_instr_start; 168 Dwarf_Debug ci_dbg; 169 Dwarf_Frame ci_initial_table; 170 Dwarf_Cie ci_next; 171 Dwarf_Small ci_length_size; 172 Dwarf_Small ci_extension_size; 173 }; 174 175 /* 176 This structure contains all the pertinent info for a Fde. 177 Most of the fields are taken straight from the definition. 178 fd_cie_index is the index of the Cie associated with this 179 Fde in the list of Cie's for this debug_frame. Fd_cie 180 points to the corresponsing Dwarf_Cie structure. Fd_fde_start 181 points to the start address of the Fde. Fd_fde_instr_start 182 points to the start of the instructions for this Fde. Fd_dbg 183 points to the associated Dwarf_Debug structure. 184 */ 185 struct Dwarf_Fde_s { 186 Dwarf_Word fd_length; 187 Dwarf_Addr fd_cie_offset; 188 Dwarf_Sword fd_cie_index; 189 Dwarf_Cie fd_cie; 190 Dwarf_Addr fd_initial_location; 191 Dwarf_Small *fd_initial_loc_pos; 192 Dwarf_Addr fd_address_range; 193 Dwarf_Small *fd_fde_start; 194 Dwarf_Small *fd_fde_instr_start; 195 Dwarf_Debug fd_dbg; 196 Dwarf_Signed fd_offset_into_exception_tables; 197 Dwarf_Fde fd_next; 198 Dwarf_Small fd_length_size; 199 Dwarf_Small fd_extension_size; 200 }; 201 202 203 int 204 _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist, 205 Dwarf_Off ** offsetlist, 206 Dwarf_Signed * returncount, 207 Dwarf_Error * err); 208