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