1 /* 2 Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. 3 Portions Copyright (C) 2015-2020 David Anderson. All Rights Reserved. 4 5 This program is free software; you can redistribute it 6 and/or modify it under the terms of version 2.1 of the 7 GNU Lesser General Public License as published by the Free 8 Software Foundation. 9 10 This program is distributed in the hope that it would be 11 useful, but WITHOUT ANY WARRANTY; without even the implied 12 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 13 PURPOSE. 14 15 Further, this software is distributed without any warranty 16 that it is free of the rightful claim of any third person 17 regarding infringement or the like. Any license provided 18 herein, whether implied or otherwise, applies only to this 19 software file. Patent licenses, if any, provided herein 20 do not apply to combinations of this program with other 21 software, or any other product whatsoever. 22 23 You should have received a copy of the GNU Lesser General 24 Public License along with this program; if not, write the 25 Free Software Foundation, Inc., 51 Franklin Street - Fifth 26 Floor, Boston MA 02110-1301, USA. 27 */ 28 #ifndef DWARF_LOC_H 29 #define DWARF_LOC_H 30 #ifdef __cplusplus 31 extern "C" { 32 #endif /* __cplusplus */ 33 34 35 typedef struct Dwarf_Loc_Chain_s *Dwarf_Loc_Chain; 36 struct Dwarf_Loc_Chain_s { 37 Dwarf_Small lc_atom; 38 Dwarf_Unsigned lc_raw1; 39 Dwarf_Unsigned lc_raw2; 40 Dwarf_Unsigned lc_raw3; 41 Dwarf_Unsigned lc_number; 42 Dwarf_Unsigned lc_number2; 43 Dwarf_Unsigned lc_number3; 44 Dwarf_Unsigned lc_offset; 45 Dwarf_Unsigned lc_opnumber; 46 Dwarf_Loc_Chain lc_next; 47 }; 48 49 /* Dwarf_Loclists_Context_s contains the data from the .debug_loclists 50 section headers (if that section exists). Dwarf 2,3,4 .debug_loc 51 has no such data. The array (one of these per header in 52 .debug_loclists) is recorded in Dwarf_Debug. These 53 are filled in at startup at the same time .debug_info 54 is opened. Nothing of this struct is exposed to 55 libdwarf callers */ 56 struct Dwarf_Loclists_Context_s { 57 Dwarf_Debug lc_dbg; 58 Dwarf_Unsigned lc_index; /* An index assigned by 59 libdwarf to each loclists context. Starting 60 with zero at the zero offset in .debug_loclists. */ 61 62 /* Offset of the .debug_loclists header involved. */ 63 Dwarf_Unsigned lc_header_offset; 64 Dwarf_Unsigned lc_length; 65 66 /* Many places in in libdwarf this is called length_size. */ 67 Dwarf_Small lc_offset_size; 68 69 /* rc_extension_size is zero unless this is standard 70 DWARF3 and later 64bit dwarf using the extension mechanism. 71 64bit DWARF3 and later: rc_extension_size is 4. 72 64bit DWARF2 MIPS/IRIX: rc_extension_size is zero. 73 32bit DWARF: rc_extension_size is zero. */ 74 Dwarf_Small lc_extension_size; 75 76 unsigned lc_version; /* 5 */ 77 Dwarf_Small lc_address_size; 78 Dwarf_Small lc_segment_selector_size; 79 Dwarf_Unsigned lc_offset_entry_count; 80 81 /* offset in the section of the offset entries */ 82 Dwarf_Unsigned lc_offsets_off_in_sect; 83 84 /* Do not free. Points into section memory */ 85 Dwarf_Small * lc_offsets_array; 86 87 /* Offset in the .debug_loclists section of the 88 first loclist in the set of loclists for the 89 CU. */ 90 Dwarf_Unsigned lc_first_loclist_offset; 91 Dwarf_Unsigned lc_past_last_loclist_offset; 92 93 /* pointer to 1st byte of loclist header*/ 94 Dwarf_Small * lc_loclists_header; 95 /* pointer to first byte of the loclist data 96 for loclist involved. Do not free. */ 97 Dwarf_Small *lc_startaddr; 98 /* pointer one past end of the loclist data. */ 99 Dwarf_Small *lc_endaddr; 100 }; 101 102 103 104 /* Contains info on an uninterpreted block of data, 105 the data is DWARF location expression operators. */ 106 struct Dwarf_Block_c_s { 107 /* length of block bl_data points at */ 108 Dwarf_Unsigned bl_len; 109 110 /* Uninterpreted data, location expressions, 111 DW_OP_reg31 etc */ 112 Dwarf_Ptr bl_data; 113 114 /* DW_LKIND, see libdwarf.h.in */ 115 Dwarf_Small bl_kind; 116 117 /* Section (not CU) offset which 'data' comes from. */ 118 Dwarf_Unsigned bl_section_offset; 119 120 /* Section offset where the location description 121 itself starts. So a few bytes lower than 122 bl_section_offset */ 123 Dwarf_Unsigned bl_locdesc_offset; 124 }; 125 typedef struct Dwarf_Block_c_s Dwarf_Block_c; 126 127 /* Location record. Records up to 3 operand values. 128 For DWARF5 ops with a 1 byte size and then a block 129 of data of that size we the size in an operand 130 and follow that with the next operand as a 131 pointer to the block. The pointer is inserted 132 via cast, so an ugly hack. 133 This struct is opaque. Not visible to callers. 134 */ 135 typedef struct Dwarf_Loc_Expr_Op_s *Dwarf_Loc_Expr_Op; 136 struct Dwarf_Loc_Expr_Op_s { 137 Dwarf_Small lr_atom; /* Location operation */ 138 139 /* Operands exactly as in DWARF. */ 140 Dwarf_Unsigned lr_raw1; 141 Dwarf_Unsigned lr_raw2; 142 Dwarf_Unsigned lr_raw3; 143 144 Dwarf_Unsigned lr_number; /* First operand */ 145 146 /* Second operand. 147 For OP_bregx, OP_bit_piece, OP_[GNU_]const_type, 148 OP_[GNU_]deref_type, OP_[GNU_]entry_value, 149 OP_implicit_value, 150 OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type, 151 OP_xderef_type, */ 152 Dwarf_Unsigned lr_number2; 153 154 /* Third Operand. 155 For OP_[GNU_]const type, pointer to 156 block of length 'lr_number2' 157 FIXME: retrieve the value at the pointer, 158 store the value here instead*/ 159 Dwarf_Unsigned lr_number3; 160 161 /* The number assigned. 0 to the number-of-ops - 1 in 162 the expression we are expanding. */ 163 Dwarf_Unsigned lr_opnumber; 164 Dwarf_Unsigned lr_offset; /* offset for OP_BRA etc */ 165 Dwarf_Loc_Expr_Op lr_next; /* When a list is useful.*/ 166 }; 167 168 /* Location description DWARF 2,3,4,5 169 Adds the DW_LLE value (new in DWARF5). 170 This struct is opaque. Not visible to callers. */ 171 struct Dwarf_Locdesc_c_s { 172 Dwarf_Small ld_kind; /* DW_LKIND */ 173 174 /* A DW_LLEX or DW_LLE value, real or synthesized */ 175 Dwarf_Small ld_lle_value; 176 /* Failed means .debug_addr section needed but missing. 177 (possibly tied file needed) */ 178 Dwarf_Bool ld_index_failed; 179 180 /* Beginning of active range. This is actually an offset 181 of an applicable base address, not a pc value. */ 182 Dwarf_Addr ld_rawlow; 183 /* Translated to address */ 184 Dwarf_Addr ld_lopc; 185 186 /* End of active range. This is actually an offset 187 of an applicable base address, 188 or a length, never a pc value. */ 189 Dwarf_Addr ld_rawhigh; 190 /* Translated to address */ 191 Dwarf_Addr ld_highpc; 192 193 /* Byte length of the entire record for this entry, 194 including any DW_OP entries */ 195 Dwarf_Unsigned ld_entrylen; 196 197 /* For .debug_loclists, eases building record. */ 198 Dwarf_Block_c ld_opsblock; 199 200 /* count of struct Dwarf_Loc_Expr_Op_s (expression operators) 201 in array. */ 202 Dwarf_Half ld_cents; 203 /* pointer to array of expression operator structs */ 204 Dwarf_Loc_Expr_Op ld_s; 205 206 /* Section (not CU) offset where loc-expr begins*/ 207 Dwarf_Unsigned ld_section_offset; 208 209 /* Section (not CU) offset where location descr begins*/ 210 Dwarf_Unsigned ld_locdesc_offset; 211 212 /* Pointer to our header (in which we are located). */ 213 Dwarf_Loc_Head_c ld_loclist_head; 214 Dwarf_Locdesc_c ld_next; /*helps building the locdescs*/ 215 }; 216 217 /* A 'header' to the loclist and the 218 location description(s) attached to an attribute. 219 This struct is opaque. The contents not visible to 220 callers. */ 221 struct Dwarf_Loc_Head_c_s { 222 /* The array (1 or more entries) of 223 struct Loc_Desc_c_s 224 If 1 it may really be a locexpr */ 225 Dwarf_Locdesc_c ll_locdesc; 226 227 /* Entry count of the ll_locdesc array. */ 228 Dwarf_Unsigned ll_locdesc_count; 229 230 unsigned ll_attrnum; 231 unsigned ll_attrform; 232 unsigned ll_cuversion; 233 unsigned ll_address_size; 234 unsigned ll_offset_size; 235 /* The CU Context of this loclist or locexpr. */ 236 Dwarf_CU_Context ll_context; 237 /* DW_LKIND* */ 238 Dwarf_Small ll_kind; 239 Dwarf_Debug ll_dbg; 240 241 /* If ll_kind == DW_LKIND_loclists the following 242 pointer is non-null and index is the index of the localcontext */ 243 Dwarf_Unsigned ll_index; 244 Dwarf_Loclists_Context ll_localcontext; 245 246 /* rh_last and rh_first used during build-up. 247 Zero when array rh_loclists built. */ 248 Dwarf_Locdesc_c ll_first; 249 Dwarf_Locdesc_c ll_last; 250 Dwarf_Unsigned ll_bytes_total; 251 unsigned ll_segment_selector_size; 252 253 /* DW_AT_loclists_base */ 254 Dwarf_Bool ll_at_loclists_base_present; 255 Dwarf_Unsigned ll_at_loclists_base; 256 257 /* DW_AT_low_pc of CU or zero if none. */ 258 Dwarf_Bool ll_cu_base_address_present; 259 Dwarf_Unsigned ll_cu_base_address; 260 261 /* DW_AT_addr_base, so we can use .debug_addr 262 if such is needed. */ 263 Dwarf_Bool ll_cu_addr_base_present; 264 Dwarf_Unsigned ll_cu_addr_base; 265 266 Dwarf_Small * ll_llepointer; 267 Dwarf_Unsigned ll_llearea_offset; 268 Dwarf_Small * ll_end_data_area; 269 }; 270 271 int _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg, 272 Dwarf_Unsigned locdesc_index, 273 Dwarf_Loc_Head_c loc_head, 274 Dwarf_Block_c * loc_block, 275 Dwarf_Half address_size, 276 Dwarf_Half offset_size, 277 Dwarf_Small version_stamp, 278 Dwarf_Addr lowpc, 279 Dwarf_Addr highpc, 280 Dwarf_Half lle_op, 281 Dwarf_Error * error); 282 283 int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, 284 Dwarf_Block_c *loc_block,Dwarf_Error*error); 285 286 void _dwarf_loclists_head_destructor(void *l); 287 288 int _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, 289 Dwarf_Attribute attr, 290 Dwarf_Loc_Head_c llhead, 291 Dwarf_Error *error); 292 293 int _dwarf_loclists_expression_build(Dwarf_Debug dbg, 294 Dwarf_Attribute attr, 295 Dwarf_Loc_Head_c* llhead, 296 Dwarf_Error *error); 297 298 int _dwarf_read_loc_expr_op(Dwarf_Debug dbg, 299 Dwarf_Block_c * loc_block, 300 /* Caller: Start numbering at 0. */ 301 Dwarf_Signed opnumber, 302 303 /* 2 for DWARF 2 etc. */ 304 Dwarf_Half version_stamp, 305 Dwarf_Half offset_size, /* 4 or 8 */ 306 Dwarf_Half address_size, /* 2,4, 8 */ 307 Dwarf_Signed startoffset_in, /* offset in block, 308 not section offset */ 309 Dwarf_Small *section_end, 310 311 /* nextoffset_out so caller knows next entry startoffset */ 312 Dwarf_Unsigned *nextoffset_out, 313 314 /* The values picked up. */ 315 Dwarf_Loc_Expr_Op curr_loc, 316 Dwarf_Error * error); 317 void _dwarf_free_loclists_head(Dwarf_Loc_Head_c head); 318 319 #ifdef __cplusplus 320 } 321 #endif /* __cplusplus */ 322 #endif /* DWARF_LOC_H */ 323