libdrgn: cfi: don't rely on member containing a flexible array

Clang enables -Wgnu-variable-sized-type-not-at-end by default, which
warns for DRGN_CFI_ROW():

  arch_x86_64.c:735:27: warning: field 'row' with variable sized type 'struct drgn_cfi_row' not at the end of a struct or class is a GNU extension
        [-Wgnu-variable-sized-type-not-at-end]
          .default_dwarf_cfi_row = DRGN_CFI_ROW(

DRGN_CFI_ROW() is gnarly anyways, so instead of having it expand to a
pointer expression relying on this GCC extension, make it expand to an
initializer. Then, we can initialize default_dwarf_cfi_row as a separate
variable rather than directly in the initializer for struct
drgn_architecture_info.

This still relies on a GCC extension for static initialization of
flexible array members, but apparently Clang is okay with that one by
default (-Wgnu-flexible-array-initializer must be enabled explictly or
by -Wgnu or -Wpedantic).

Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
Omar Sandoval 2021-04-02 15:56:41 -07:00
parent 5c86e30b6e
commit b772432a86
5 changed files with 57 additions and 59 deletions

View File

@ -71,6 +71,32 @@
#include "arch_ppc64.inc"
static const struct drgn_cfi_row default_dwarf_cfi_row_ppc64 = DRGN_CFI_ROW(
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(ra)),
[DRGN_REGISTER_NUMBER(r1)] = { DRGN_CFI_RULE_CFA_PLUS_OFFSET },
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r14)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r15)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r16)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r17)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r18)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r19)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r20)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r21)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r22)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r23)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r24)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r25)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r26)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r27)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r28)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r29)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r30)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r31)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(cr2)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(cr3)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(cr4)),
);
static struct drgn_error *
fallback_unwind_ppc64(struct drgn_program *prog,
struct drgn_register_state *regs,
@ -258,31 +284,7 @@ const struct drgn_architecture_info arch_info_ppc64 = {
.default_flags = (DRGN_PLATFORM_IS_64_BIT |
DRGN_PLATFORM_IS_LITTLE_ENDIAN),
DRGN_ARCHITECTURE_REGISTERS,
.default_dwarf_cfi_row = DRGN_CFI_ROW(
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(ra)),
[DRGN_REGISTER_NUMBER(r1)] = { DRGN_CFI_RULE_CFA_PLUS_OFFSET },
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r14)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r15)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r16)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r17)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r18)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r19)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r20)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r21)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r22)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r23)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r24)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r25)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r26)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r27)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r28)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r29)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r30)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r31)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(cr2)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(cr3)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(cr4)),
),
.default_dwarf_cfi_row = &default_dwarf_cfi_row_ppc64,
.fallback_unwind = fallback_unwind_ppc64,
.pt_regs_get_initial_registers = pt_regs_get_initial_registers_ppc64,
.prstatus_get_initial_registers = prstatus_get_initial_registers_ppc64,

View File

@ -40,6 +40,24 @@
#include "arch_x86_64.inc"
static const struct drgn_cfi_row default_dwarf_cfi_row_x86_64 = DRGN_CFI_ROW(
/*
* The System V psABI defines the CFA as the value of rsp in the calling
* frame.
*/
[DRGN_REGISTER_NUMBER(rsp)] = { DRGN_CFI_RULE_CFA_PLUS_OFFSET },
/*
* Other callee-saved registers default to DW_CFA_same_value. This isn't
* explicitly documented in the psABI, but it seems to be the consensus.
*/
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(rbx)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(rbp)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r12)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r13)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r14)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r15)),
);
static struct drgn_error *
orc_to_cfi_x86_64(const struct drgn_orc_entry *orc,
struct drgn_cfi_row **row_ret, bool *interrupted_ret,
@ -732,24 +750,7 @@ const struct drgn_architecture_info arch_info_x86_64 = {
.default_flags = (DRGN_PLATFORM_IS_64_BIT |
DRGN_PLATFORM_IS_LITTLE_ENDIAN),
DRGN_ARCHITECTURE_REGISTERS,
.default_dwarf_cfi_row = DRGN_CFI_ROW(
/*
* The System V psABI defines the CFA as the value of rsp in the
* calling frame.
*/
[DRGN_REGISTER_NUMBER(rsp)] = { DRGN_CFI_RULE_CFA_PLUS_OFFSET },
/*
* Other callee-saved registers default to DW_CFA_same_value.
* This isn't explicitly documented in the psABI, but it seems
* to be the consensus.
*/
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(rbx)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(rbp)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r12)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r13)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r14)),
DRGN_CFI_SAME_VALUE_INIT(DRGN_REGISTER_NUMBER(r15)),
),
.default_dwarf_cfi_row = &default_dwarf_cfi_row_x86_64,
.orc_to_cfi = orc_to_cfi_x86_64,
.fallback_unwind = fallback_unwind_x86_64,
.pt_regs_get_initial_registers = pt_regs_get_initial_registers_x86_64,

View File

@ -145,20 +145,15 @@ struct drgn_cfi_row {
struct drgn_cfi_rule reg_rules[];
};
/** Create a static @ref drgn_cfi_row given initializers for `reg_rules`. */
#define DRGN_CFI_ROW(...) \
((struct drgn_cfi_row *) \
&(const struct { \
struct drgn_cfi_row row; \
struct drgn_cfi_rule reg_rules[sizeof((struct drgn_cfi_rule []){ __VA_ARGS__ })\
/ sizeof(struct drgn_cfi_rule)]; \
}){ \
{ \
.num_regs = (sizeof((struct drgn_cfi_rule []){ __VA_ARGS__ })\
/ sizeof(struct drgn_cfi_rule)), \
}, \
{ __VA_ARGS__ }, \
})
/**
* Initializer for a static @ref drgn_cfi_row given initializers for @ref
* drgn_cfi_row::reg_rules.
*/
#define DRGN_CFI_ROW(...) { \
.num_regs = (sizeof((struct drgn_cfi_rule []){ __VA_ARGS__ }) \
/ sizeof(struct drgn_cfi_rule)), \
.reg_rules = { __VA_ARGS__ }, \
}
/**
* Initializer for a rule in @ref drgn_cfi_row::reg_rules specifying that the

View File

@ -4240,7 +4240,7 @@ drgn_debug_info_find_cfi_in_fde(struct drgn_debug_info_module *module,
struct drgn_error *err;
struct drgn_dwarf_cie *cie = &module->cies[fde->cie];
struct drgn_cfi_row *initial_row =
module->platform.arch->default_dwarf_cfi_row;
(struct drgn_cfi_row *)module->platform.arch->default_dwarf_cfi_row;
err = drgn_eval_dwarf_cfi(module, fde, NULL, unbiased_pc,
cie->initial_instructions,
cie->initial_instructions_size, &initial_row);

View File

@ -86,7 +86,7 @@ struct drgn_architecture_info {
const struct drgn_register_layout *register_layout;
drgn_register_number (*dwarf_regno_to_internal)(uint64_t);
/* CFI row containing default rules for DWARF CFI. */
struct drgn_cfi_row *default_dwarf_cfi_row;
const struct drgn_cfi_row *default_dwarf_cfi_row;
struct drgn_error *(*orc_to_cfi)(const struct drgn_orc_entry *,
struct drgn_cfi_row **, bool *,
drgn_register_number *);