gdb: move call site types to call-site.h
I hesitated between putting the file in the dwarf2 directory (as gdb/dwarf2/call-site.h) or in the common directory (as gdb/call-site.h). The concept of call site is not DWARF-specific, another debug info reader could provide this information. But as it is, the implementation is a bit DWARF-specific, as one form it can take is a DWARF expression and parameters can be defined using a DWARF register number. So I ended up choosing to put it under dwarf2/. If another debug info reader ever wants to provide call site information, we can introduce a layer of abstraction between the "common" call site and the "dwarf2" call site. The copyright start year comes from the date `struct call_site` was introduced. Change-Id: I1cd84aa581fbbf729edc91b20f7d7a6e0377014d Reviewed-By: Bruno Larsen <blarsen@redhat.com>
This commit is contained in:
parent
b23bf9f724
commit
1298c32f01
@ -21,7 +21,6 @@
|
||||
#define GDB_DWARF2_ABBREV_CACHE_H
|
||||
|
||||
#include "dwarf2/abbrev.h"
|
||||
#include "gdbtypes.h"
|
||||
|
||||
/* An abbrev cache holds abbrev tables for easier reuse. */
|
||||
class abbrev_cache
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define GDB_DWARF2_ATTRIBUTE_H
|
||||
|
||||
#include "dwarf2.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "dwarf2/types.h"
|
||||
#include "gdbsupport/gdb_optional.h"
|
||||
|
||||
/* Blocks are a bunch of untyped bytes. */
|
||||
|
244
gdb/dwarf2/call-site.h
Normal file
244
gdb/dwarf2/call-site.h
Normal file
@ -0,0 +1,244 @@
|
||||
/* Call site information.
|
||||
|
||||
Copyright (C) 2011-2022 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Cygnus Support, using pieces from other GDB modules.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef CALL_SITE_H
|
||||
#define CALL_SITE_H
|
||||
|
||||
#include "dwarf2/types.h"
|
||||
#include "gdbsupport/function-view.h"
|
||||
#include "frame-info.h"
|
||||
|
||||
struct dwarf2_locexpr_baton;
|
||||
struct dwarf2_per_cu_data;
|
||||
struct dwarf2_per_objfile;
|
||||
|
||||
/* struct call_site_parameter can be referenced in callees by several ways. */
|
||||
|
||||
enum call_site_parameter_kind
|
||||
{
|
||||
/* * Use field call_site_parameter.u.dwarf_reg. */
|
||||
CALL_SITE_PARAMETER_DWARF_REG,
|
||||
|
||||
/* * Use field call_site_parameter.u.fb_offset. */
|
||||
CALL_SITE_PARAMETER_FB_OFFSET,
|
||||
|
||||
/* * Use field call_site_parameter.u.param_offset. */
|
||||
CALL_SITE_PARAMETER_PARAM_OFFSET
|
||||
};
|
||||
|
||||
struct call_site_target
|
||||
{
|
||||
/* The kind of location held by this call site target. */
|
||||
enum kind
|
||||
{
|
||||
/* An address. */
|
||||
PHYSADDR,
|
||||
/* A name. */
|
||||
PHYSNAME,
|
||||
/* A DWARF block. */
|
||||
DWARF_BLOCK,
|
||||
/* An array of addresses. */
|
||||
ADDRESSES,
|
||||
};
|
||||
|
||||
void set_loc_physaddr (CORE_ADDR physaddr)
|
||||
{
|
||||
m_loc_kind = PHYSADDR;
|
||||
m_loc.physaddr = physaddr;
|
||||
}
|
||||
|
||||
void set_loc_physname (const char *physname)
|
||||
{
|
||||
m_loc_kind = PHYSNAME;
|
||||
m_loc.physname = physname;
|
||||
}
|
||||
|
||||
void set_loc_dwarf_block (dwarf2_locexpr_baton *dwarf_block)
|
||||
{
|
||||
m_loc_kind = DWARF_BLOCK;
|
||||
m_loc.dwarf_block = dwarf_block;
|
||||
}
|
||||
|
||||
void set_loc_array (unsigned length, const CORE_ADDR *data)
|
||||
{
|
||||
m_loc_kind = ADDRESSES;
|
||||
m_loc.addresses.length = length;
|
||||
m_loc.addresses.values = data;
|
||||
}
|
||||
|
||||
/* Callback type for iterate_over_addresses. */
|
||||
|
||||
using iterate_ftype = gdb::function_view<void (CORE_ADDR)>;
|
||||
|
||||
/* Call CALLBACK for each DW_TAG_call_site's DW_AT_call_target
|
||||
address. CALLER_FRAME (for registers) can be NULL if it is not
|
||||
known. This function always may throw NO_ENTRY_VALUE_ERROR. */
|
||||
|
||||
void iterate_over_addresses (struct gdbarch *call_site_gdbarch,
|
||||
const struct call_site *call_site,
|
||||
frame_info_ptr caller_frame,
|
||||
iterate_ftype callback) const;
|
||||
|
||||
private:
|
||||
|
||||
union
|
||||
{
|
||||
/* Address. */
|
||||
CORE_ADDR physaddr;
|
||||
/* Mangled name. */
|
||||
const char *physname;
|
||||
/* DWARF block. */
|
||||
struct dwarf2_locexpr_baton *dwarf_block;
|
||||
/* Array of addresses. */
|
||||
struct
|
||||
{
|
||||
unsigned length;
|
||||
const CORE_ADDR *values;
|
||||
} addresses;
|
||||
} m_loc;
|
||||
|
||||
/* * Discriminant for union field_location. */
|
||||
enum kind m_loc_kind;
|
||||
};
|
||||
|
||||
union call_site_parameter_u
|
||||
{
|
||||
/* * DW_TAG_formal_parameter's DW_AT_location's DW_OP_regX
|
||||
as DWARF register number, for register passed
|
||||
parameters. */
|
||||
|
||||
int dwarf_reg;
|
||||
|
||||
/* * Offset from the callee's frame base, for stack passed
|
||||
parameters. This equals offset from the caller's stack
|
||||
pointer. */
|
||||
|
||||
CORE_ADDR fb_offset;
|
||||
|
||||
/* * Offset relative to the start of this PER_CU to
|
||||
DW_TAG_formal_parameter which is referenced by both
|
||||
caller and the callee. */
|
||||
|
||||
cu_offset param_cu_off;
|
||||
};
|
||||
|
||||
struct call_site_parameter
|
||||
{
|
||||
ENUM_BITFIELD (call_site_parameter_kind) kind : 2;
|
||||
|
||||
union call_site_parameter_u u;
|
||||
|
||||
/* * DW_TAG_formal_parameter's DW_AT_call_value. It is never NULL. */
|
||||
|
||||
const gdb_byte *value;
|
||||
size_t value_size;
|
||||
|
||||
/* * DW_TAG_formal_parameter's DW_AT_call_data_value.
|
||||
It may be NULL if not provided by DWARF. */
|
||||
|
||||
const gdb_byte *data_value;
|
||||
size_t data_value_size;
|
||||
};
|
||||
|
||||
/* * A place where a function gets called from, represented by
|
||||
DW_TAG_call_site. It can be looked up from symtab->call_site_htab. */
|
||||
|
||||
struct call_site
|
||||
{
|
||||
call_site (CORE_ADDR pc, dwarf2_per_cu_data *per_cu,
|
||||
dwarf2_per_objfile *per_objfile)
|
||||
: per_cu (per_cu), per_objfile (per_objfile), m_unrelocated_pc (pc)
|
||||
{}
|
||||
|
||||
static int
|
||||
eq (const call_site *a, const call_site *b)
|
||||
{
|
||||
return a->m_unrelocated_pc == b->m_unrelocated_pc;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
hash (const call_site *a)
|
||||
{
|
||||
return a->m_unrelocated_pc;
|
||||
}
|
||||
|
||||
static int
|
||||
eq (const void *a, const void *b)
|
||||
{
|
||||
return eq ((const call_site *)a, (const call_site *)b);
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
hash (const void *a)
|
||||
{
|
||||
return hash ((const call_site *)a);
|
||||
}
|
||||
|
||||
/* Return the address of the first instruction after this call. */
|
||||
|
||||
CORE_ADDR pc () const;
|
||||
|
||||
/* Call CALLBACK for each target address. CALLER_FRAME (for
|
||||
registers) can be NULL if it is not known. This function may
|
||||
throw NO_ENTRY_VALUE_ERROR. */
|
||||
|
||||
void iterate_over_addresses (struct gdbarch *call_site_gdbarch,
|
||||
frame_info_ptr caller_frame,
|
||||
call_site_target::iterate_ftype callback)
|
||||
const
|
||||
{
|
||||
return target.iterate_over_addresses (call_site_gdbarch, this,
|
||||
caller_frame, callback);
|
||||
}
|
||||
|
||||
/* * List successor with head in FUNC_TYPE.TAIL_CALL_LIST. */
|
||||
|
||||
struct call_site *tail_call_next = nullptr;
|
||||
|
||||
/* * Describe DW_AT_call_target. Missing attribute uses
|
||||
FIELD_LOC_KIND_DWARF_BLOCK with FIELD_DWARF_BLOCK == NULL. */
|
||||
|
||||
struct call_site_target target {};
|
||||
|
||||
/* * Size of the PARAMETER array. */
|
||||
|
||||
unsigned parameter_count = 0;
|
||||
|
||||
/* * CU of the function where the call is located. It gets used
|
||||
for DWARF blocks execution in the parameter array below. */
|
||||
|
||||
dwarf2_per_cu_data *const per_cu = nullptr;
|
||||
|
||||
/* objfile of the function where the call is located. */
|
||||
|
||||
dwarf2_per_objfile *const per_objfile = nullptr;
|
||||
|
||||
private:
|
||||
/* Unrelocated address of the first instruction after this call. */
|
||||
const CORE_ADDR m_unrelocated_pc;
|
||||
|
||||
public:
|
||||
/* * Describe DW_TAG_call_site's DW_TAG_formal_parameter. */
|
||||
|
||||
struct call_site_parameter parameter[];
|
||||
};
|
||||
|
||||
#endif /* CALL_SITE_H */
|
@ -27,8 +27,11 @@
|
||||
#ifndef GDB_DWARF2_COMP_UNIT_H
|
||||
#define GDB_DWARF2_COMP_UNIT_H
|
||||
|
||||
#include "dwarf2.h"
|
||||
#include "dwarf2/leb.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "dwarf2/types.h"
|
||||
|
||||
struct dwarf2_per_objfile;
|
||||
|
||||
/* The data in a compilation unit header, after target2host
|
||||
translation, looks like this. */
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define GDB_DWARF2_COOKED_INDEX_H
|
||||
|
||||
#include "dwarf2.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "dwarf2/types.h"
|
||||
#include "symtab.h"
|
||||
#include "hashtab.h"
|
||||
#include "dwarf2/index-common.h"
|
||||
|
@ -23,7 +23,7 @@
|
||||
#define DWARF2EXPR_H
|
||||
|
||||
#include "leb128.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "dwarf2/call-site.h"
|
||||
|
||||
struct dwarf2_per_objfile;
|
||||
|
||||
|
@ -20,8 +20,6 @@
|
||||
#ifndef DWARF2_LINE_HEADER_H
|
||||
#define DWARF2_LINE_HEADER_H
|
||||
|
||||
#include "gdbtypes.h"
|
||||
|
||||
/* dir_index is 1-based in DWARF 4 and before, and is 0-based in DWARF 5 and
|
||||
later. */
|
||||
typedef int dir_index;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define DWARF2_TYPES_H
|
||||
|
||||
#include "gdbsupport/offset-type.h"
|
||||
#include "gdbsupport/underlying.h"
|
||||
|
||||
/* Offset relative to the start of its containing CU (compilation
|
||||
unit). */
|
||||
|
211
gdb/gdbtypes.h
211
gdb/gdbtypes.h
@ -57,7 +57,6 @@
|
||||
#include "gdbsupport/gdb_obstack.h"
|
||||
#include "gmp-utils.h"
|
||||
#include "frame-info.h"
|
||||
#include "dwarf2/types.h"
|
||||
|
||||
/* Forward declarations for prototypes. */
|
||||
struct field;
|
||||
@ -1735,216 +1734,6 @@ struct func_type
|
||||
struct type *self_type;
|
||||
};
|
||||
|
||||
/* struct call_site_parameter can be referenced in callees by several ways. */
|
||||
|
||||
enum call_site_parameter_kind
|
||||
{
|
||||
/* * Use field call_site_parameter.u.dwarf_reg. */
|
||||
CALL_SITE_PARAMETER_DWARF_REG,
|
||||
|
||||
/* * Use field call_site_parameter.u.fb_offset. */
|
||||
CALL_SITE_PARAMETER_FB_OFFSET,
|
||||
|
||||
/* * Use field call_site_parameter.u.param_offset. */
|
||||
CALL_SITE_PARAMETER_PARAM_OFFSET
|
||||
};
|
||||
|
||||
struct call_site_target
|
||||
{
|
||||
/* The kind of location held by this call site target. */
|
||||
enum kind
|
||||
{
|
||||
/* An address. */
|
||||
PHYSADDR,
|
||||
/* A name. */
|
||||
PHYSNAME,
|
||||
/* A DWARF block. */
|
||||
DWARF_BLOCK,
|
||||
/* An array of addresses. */
|
||||
ADDRESSES,
|
||||
};
|
||||
|
||||
void set_loc_physaddr (CORE_ADDR physaddr)
|
||||
{
|
||||
m_loc_kind = PHYSADDR;
|
||||
m_loc.physaddr = physaddr;
|
||||
}
|
||||
|
||||
void set_loc_physname (const char *physname)
|
||||
{
|
||||
m_loc_kind = PHYSNAME;
|
||||
m_loc.physname = physname;
|
||||
}
|
||||
|
||||
void set_loc_dwarf_block (dwarf2_locexpr_baton *dwarf_block)
|
||||
{
|
||||
m_loc_kind = DWARF_BLOCK;
|
||||
m_loc.dwarf_block = dwarf_block;
|
||||
}
|
||||
|
||||
void set_loc_array (unsigned length, const CORE_ADDR *data)
|
||||
{
|
||||
m_loc_kind = ADDRESSES;
|
||||
m_loc.addresses.length = length;
|
||||
m_loc.addresses.values = data;
|
||||
}
|
||||
|
||||
/* Callback type for iterate_over_addresses. */
|
||||
|
||||
using iterate_ftype = gdb::function_view<void (CORE_ADDR)>;
|
||||
|
||||
/* Call CALLBACK for each DW_TAG_call_site's DW_AT_call_target
|
||||
address. CALLER_FRAME (for registers) can be NULL if it is not
|
||||
known. This function always may throw NO_ENTRY_VALUE_ERROR. */
|
||||
|
||||
void iterate_over_addresses (struct gdbarch *call_site_gdbarch,
|
||||
const struct call_site *call_site,
|
||||
frame_info_ptr caller_frame,
|
||||
iterate_ftype callback) const;
|
||||
|
||||
private:
|
||||
|
||||
union
|
||||
{
|
||||
/* Address. */
|
||||
CORE_ADDR physaddr;
|
||||
/* Mangled name. */
|
||||
const char *physname;
|
||||
/* DWARF block. */
|
||||
struct dwarf2_locexpr_baton *dwarf_block;
|
||||
/* Array of addresses. */
|
||||
struct
|
||||
{
|
||||
unsigned length;
|
||||
const CORE_ADDR *values;
|
||||
} addresses;
|
||||
} m_loc;
|
||||
|
||||
/* * Discriminant for union field_location. */
|
||||
enum kind m_loc_kind;
|
||||
};
|
||||
|
||||
union call_site_parameter_u
|
||||
{
|
||||
/* * DW_TAG_formal_parameter's DW_AT_location's DW_OP_regX
|
||||
as DWARF register number, for register passed
|
||||
parameters. */
|
||||
|
||||
int dwarf_reg;
|
||||
|
||||
/* * Offset from the callee's frame base, for stack passed
|
||||
parameters. This equals offset from the caller's stack
|
||||
pointer. */
|
||||
|
||||
CORE_ADDR fb_offset;
|
||||
|
||||
/* * Offset relative to the start of this PER_CU to
|
||||
DW_TAG_formal_parameter which is referenced by both
|
||||
caller and the callee. */
|
||||
|
||||
cu_offset param_cu_off;
|
||||
};
|
||||
|
||||
struct call_site_parameter
|
||||
{
|
||||
ENUM_BITFIELD (call_site_parameter_kind) kind : 2;
|
||||
|
||||
union call_site_parameter_u u;
|
||||
|
||||
/* * DW_TAG_formal_parameter's DW_AT_call_value. It is never NULL. */
|
||||
|
||||
const gdb_byte *value;
|
||||
size_t value_size;
|
||||
|
||||
/* * DW_TAG_formal_parameter's DW_AT_call_data_value.
|
||||
It may be NULL if not provided by DWARF. */
|
||||
|
||||
const gdb_byte *data_value;
|
||||
size_t data_value_size;
|
||||
};
|
||||
|
||||
/* * A place where a function gets called from, represented by
|
||||
DW_TAG_call_site. It can be looked up from symtab->call_site_htab. */
|
||||
|
||||
struct call_site
|
||||
{
|
||||
call_site (CORE_ADDR pc, dwarf2_per_cu_data *per_cu,
|
||||
dwarf2_per_objfile *per_objfile)
|
||||
: per_cu (per_cu), per_objfile (per_objfile), m_unrelocated_pc (pc)
|
||||
{}
|
||||
|
||||
static int
|
||||
eq (const call_site *a, const call_site *b)
|
||||
{
|
||||
return a->m_unrelocated_pc == b->m_unrelocated_pc;
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
hash (const call_site *a)
|
||||
{
|
||||
return a->m_unrelocated_pc;
|
||||
}
|
||||
|
||||
static int
|
||||
eq (const void *a, const void *b)
|
||||
{
|
||||
return eq ((const call_site *)a, (const call_site *)b);
|
||||
}
|
||||
|
||||
static hashval_t
|
||||
hash (const void *a)
|
||||
{
|
||||
return hash ((const call_site *)a);
|
||||
}
|
||||
|
||||
/* Return the address of the first instruction after this call. */
|
||||
|
||||
CORE_ADDR pc () const;
|
||||
|
||||
/* Call CALLBACK for each target address. CALLER_FRAME (for
|
||||
registers) can be NULL if it is not known. This function may
|
||||
throw NO_ENTRY_VALUE_ERROR. */
|
||||
|
||||
void iterate_over_addresses (struct gdbarch *call_site_gdbarch,
|
||||
frame_info_ptr caller_frame,
|
||||
call_site_target::iterate_ftype callback)
|
||||
const
|
||||
{
|
||||
return target.iterate_over_addresses (call_site_gdbarch, this,
|
||||
caller_frame, callback);
|
||||
}
|
||||
|
||||
/* * List successor with head in FUNC_TYPE.TAIL_CALL_LIST. */
|
||||
|
||||
struct call_site *tail_call_next = nullptr;
|
||||
|
||||
/* * Describe DW_AT_call_target. Missing attribute uses
|
||||
FIELD_LOC_KIND_DWARF_BLOCK with FIELD_DWARF_BLOCK == NULL. */
|
||||
|
||||
struct call_site_target target {};
|
||||
|
||||
/* * Size of the PARAMETER array. */
|
||||
|
||||
unsigned parameter_count = 0;
|
||||
|
||||
/* * CU of the function where the call is located. It gets used
|
||||
for DWARF blocks execution in the parameter array below. */
|
||||
|
||||
dwarf2_per_cu_data *const per_cu = nullptr;
|
||||
|
||||
/* objfile of the function where the call is located. */
|
||||
|
||||
dwarf2_per_objfile *const per_objfile = nullptr;
|
||||
|
||||
private:
|
||||
/* Unrelocated address of the first instruction after this call. */
|
||||
const CORE_ADDR m_unrelocated_pc;
|
||||
|
||||
public:
|
||||
/* * Describe DW_TAG_call_site's DW_TAG_formal_parameter. */
|
||||
|
||||
struct call_site_parameter parameter[];
|
||||
};
|
||||
|
||||
/* The type-specific info for TYPE_CODE_FIXED_POINT types. */
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "dwarf2/call-site.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "gdbcore.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user