automatically generate hfi structs from dwarf info
This commit is contained in:
committed by
Balazs Gerofi
parent
6279f69f5c
commit
03fed4d1c8
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@ elfboot/elfboot_test
|
||||
linux/executer/mcexec
|
||||
linux/mod_test*
|
||||
linux/target
|
||||
kernel/script/dwarf-extract-struct
|
||||
|
||||
@ -71,7 +71,7 @@ void hfi1_put_tid(struct hfi1_devdata *dd, u32 index,
|
||||
{
|
||||
u64 reg;
|
||||
void __iomem *base = (dd->rcvarray_wc ? dd->rcvarray_wc :
|
||||
(dd->kregbase + RCV_ARRAY));
|
||||
(dd->kregbase1 + RCV_ARRAY));
|
||||
|
||||
if (!(dd->flags & HFI1_PRESENT))
|
||||
goto done;
|
||||
|
||||
@ -1187,7 +1187,7 @@ static int find_shared_ctxt(struct file *fp,
|
||||
for (ndev = 0; ndev < devmax; ndev++) {
|
||||
struct hfi1_devdata *dd = hfi1_lookup(ndev);
|
||||
|
||||
if (!(dd && (dd->flags & HFI1_PRESENT) && dd->kregbase))
|
||||
if (!(dd && (dd->flags & HFI1_PRESENT) && dd->kregbase1))
|
||||
continue;
|
||||
for (i = dd->first_user_ctxt; i < dd->num_rcv_contexts; i++) {
|
||||
struct hfi1_ctxtdata *uctxt = dd->rcd[i];
|
||||
|
||||
@ -137,30 +137,6 @@ struct exp_tid_set {
|
||||
u32 count;
|
||||
};
|
||||
|
||||
//TODO: Fix hfi1_ctxtdata and pport
|
||||
#ifndef __HFI1_ORIG__
|
||||
struct hfi1_ctxtdata {
|
||||
char __padding0[144];
|
||||
unsigned ctxt;
|
||||
char __padding1[172-148];
|
||||
/* number of RcvArray groups for this context. */
|
||||
u32 rcv_array_groups;
|
||||
/* index of first eager TID entry. */
|
||||
u32 eager_base;
|
||||
/* number of expected TID entries */
|
||||
u32 expected_count;
|
||||
/* index of first expected TID entry. */
|
||||
u32 expected_base;
|
||||
|
||||
struct exp_tid_set tid_group_list;
|
||||
struct exp_tid_set tid_used_list;
|
||||
struct exp_tid_set tid_full_list;
|
||||
|
||||
char __padding2[432-264];
|
||||
struct hfi1_devdata *dd;
|
||||
};
|
||||
#endif /* !__HFI1_ORIG__ */
|
||||
|
||||
/*
|
||||
* Get/Set IB link-level config parameters for f_get/set_ib_cfg()
|
||||
* Mostly for MADs that set or query link parameters, also ipath
|
||||
@ -301,24 +277,6 @@ static inline void incr_cntr32(u32 *cntr)
|
||||
|
||||
#define MAX_NAME_SIZE 64
|
||||
|
||||
#ifndef __HFI1_ORIG__
|
||||
struct hfi1_pportdata {
|
||||
char _padding[1907]; // TODO: compute this offset automatically from kernel we're basing off
|
||||
/*
|
||||
$ objdump --dwarf $(modinfo -n hfi1) | \
|
||||
awk '/DW_AT_name.*: vls_operational/ {
|
||||
while (getline) {
|
||||
if (/DW_AT_data_member_location/) {
|
||||
print $NF; exit;
|
||||
}
|
||||
}
|
||||
}'
|
||||
-> 1899
|
||||
*/
|
||||
u8 vls_operational;
|
||||
};
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
struct rcv_array_data {
|
||||
u8 group_size;
|
||||
u16 ngroups;
|
||||
@ -333,347 +291,7 @@ struct rcv_array_data {
|
||||
#define BOARD_VERS_MAX 96 /* how long the version string can be */
|
||||
#define SERIAL_MAX 16 /* length of the serial number */
|
||||
|
||||
/* Size on Linux side is 7360 Bytes */
|
||||
struct hfi1_devdata {
|
||||
char verbs_dev[2624]; //struct hfi1_ibdev verbs_dev
|
||||
struct list_head list;
|
||||
/* pointers to related structs for this device */
|
||||
/* pci access data structure */
|
||||
void *pcidev; // struct pci_dev *pcidev;
|
||||
char user_cdev[104]; //struct cdev user_cdev
|
||||
char diag_cdev[104]; //struct cdev diag_cdev
|
||||
char ui_cdev[104]; //struct cdev ui_cdev
|
||||
void *user_device; //struct device *user_device;
|
||||
void *diag_device; //struct device *diag_device;
|
||||
void *ui_device; //struct device *ui_device;
|
||||
|
||||
|
||||
u8 __iomem *kregbase;
|
||||
resource_size_t physaddr;
|
||||
|
||||
/* second uncached mapping from RcvArray to pio send buffers */
|
||||
u8 __iomem *kregend;
|
||||
/* for detecting offset above kregbase2 address */
|
||||
u32 base2_start;
|
||||
/* Per VL data. Enough for all VLs but not all elements are set/used. */
|
||||
char vld[16 * PER_VL_SEND_CONTEXTS]; //struct per_vl_data vld[PER_VL_SEND_CONTEXTS]
|
||||
/* send context data */
|
||||
void *send_contexts; //struct send_context_info *send_contexts;
|
||||
|
||||
/* map hardware send contexts to software index */
|
||||
u8 *hw_to_sw;
|
||||
/* spinlock for allocating and releasing send context resources */
|
||||
spinlock_t sc_lock;
|
||||
/* lock for pio_map */
|
||||
spinlock_t pio_map_lock;
|
||||
/* Send Context initialization lock. */
|
||||
spinlock_t sc_init_lock;
|
||||
/* lock for sdma_map */
|
||||
spinlock_t sde_map_lock;
|
||||
/* array of kernel send contexts */
|
||||
void **kernel_send_context; //struct send_context **kernel_send_context;
|
||||
|
||||
void __rcu *pio_map; //struct pio_vl_map __rcu *pio_map
|
||||
/* default flags to last descriptor */
|
||||
u64 default_desc1;
|
||||
|
||||
/* fields common to all SDMA engines */
|
||||
|
||||
volatile __le64 *sdma_heads_dma; /* DMA'ed by chip */
|
||||
dma_addr_t sdma_heads_phys;
|
||||
void *sdma_pad_dma; /* DMA'ed by chip */
|
||||
dma_addr_t sdma_pad_phys;
|
||||
/* for deallocation */
|
||||
size_t sdma_heads_size;
|
||||
/* number from the chip */
|
||||
u32 chip_sdma_engines;
|
||||
/* num used */
|
||||
u32 num_sdma;
|
||||
/* array of engines sized by num_sdma */
|
||||
struct sdma_engine *per_sdma;
|
||||
/* array of vl maps */
|
||||
struct sdma_vl_map __rcu *sdma_map; //struct sdma_vl_map __rc *sdma_map
|
||||
/* SPC freeze waitqueue and variable */
|
||||
wait_queue_head_t sdma_unfreeze_wq;
|
||||
atomic_t sdma_unfreeze_count;
|
||||
|
||||
u32 lcb_access_count;
|
||||
|
||||
|
||||
void *asic_data; //struct hfi1_asic_data *asic_data;
|
||||
|
||||
|
||||
/* mem-mapped pointer to base of PIO buffers */
|
||||
void __iomem *piobase;
|
||||
/*
|
||||
* write-combining mem-mapped pointer to base of RcvArray
|
||||
* memory.
|
||||
*/
|
||||
void __iomem *rcvarray_wc;
|
||||
/*
|
||||
* credit return base - a per-NUMA range of DMA address that
|
||||
* the chip will use to update the per-context free counter
|
||||
*/
|
||||
void *cr_base; //struct credit_return_base *cr_base;
|
||||
|
||||
char sc_sizes[4 * SC_MAX]; //struct sc_config_sizes sc_sizes[SC_MAX]
|
||||
|
||||
char *boardname;
|
||||
|
||||
|
||||
u64 z_int_counter;
|
||||
u64 z_rcv_limit;
|
||||
u64 z_send_schedule;
|
||||
|
||||
u64 __percpu *send_schedule;
|
||||
/* number of receive contexts in use by the driver */
|
||||
|
||||
u32 num_rcv_contexts;
|
||||
/* number of pio send contexts in use by the driver */
|
||||
|
||||
u32 num_send_contexts;
|
||||
/*
|
||||
* number of ctxts available for PSM open
|
||||
*/
|
||||
u32 freectxts;
|
||||
/* total number of available user/PSM contexts */
|
||||
u32 num_user_contexts;
|
||||
/* base receive interrupt timeout, in CSR units */
|
||||
u32 rcv_intr_timeout_csr;
|
||||
|
||||
u32 freezelen; /* max length of freezemsg */
|
||||
u64 __iomem *egrtidbase;
|
||||
spinlock_t sendctrl_lock;
|
||||
spinlock_t rcvctrl_lock;
|
||||
|
||||
spinlock_t uctxt_lock;
|
||||
|
||||
char dc8051_lock[40]; // struct mutex dc8051_lock; /* exclusive access to 8051 */
|
||||
struct workqueue_struct *update_cntr_wq;
|
||||
char update_cntr_work[32]; // struct work_struct update_cntr_work;
|
||||
|
||||
spinlock_t dc8051_memlock;
|
||||
int dc8051_timed_out;
|
||||
unsigned long *events;
|
||||
void *status; //struct hfi1_status *status;
|
||||
|
||||
|
||||
u64 revision;
|
||||
|
||||
u64 base_guid;
|
||||
|
||||
|
||||
|
||||
|
||||
u32 rcvhdrsize;
|
||||
|
||||
u32 chip_rcv_contexts;
|
||||
|
||||
u32 chip_rcv_array_count;
|
||||
|
||||
u32 chip_send_contexts;
|
||||
|
||||
u32 chip_pio_mem_size;
|
||||
|
||||
u32 chip_sdma_mem_size;
|
||||
|
||||
|
||||
u32 rcvegrbufsize;
|
||||
|
||||
u16 rcvegrbufsize_shift;
|
||||
|
||||
u8 link_gen3_capable;
|
||||
|
||||
u8 link_default;
|
||||
|
||||
u32 lbus_width;
|
||||
|
||||
u32 lbus_speed;
|
||||
int unit;
|
||||
int node;
|
||||
|
||||
|
||||
u32 pcibar0;
|
||||
u32 pcibar1;
|
||||
u32 pci_rom;
|
||||
u16 pci_command;
|
||||
u16 pcie_devctl;
|
||||
u16 pcie_lnkctl;
|
||||
u16 pcie_devctl2;
|
||||
u32 pci_msix0;
|
||||
u32 pci_lnkctl3;
|
||||
u32 pci_tph2;
|
||||
u8 serial[SERIAL_MAX];
|
||||
|
||||
u8 boardversion[BOARD_VERS_MAX];
|
||||
u8 lbus_info[32];
|
||||
|
||||
u8 majrev;
|
||||
|
||||
u8 minrev;
|
||||
|
||||
u8 hfi1_id;
|
||||
|
||||
u8 icode;
|
||||
|
||||
u8 vau;
|
||||
|
||||
u8 vcu;
|
||||
|
||||
u16 link_credits;
|
||||
/* initial vl15 credits to use */
|
||||
u16 vl15_init;
|
||||
/*
|
||||
* Cached value for vl15buf, read during verify cap interrupt. VL15
|
||||
* credits are to be kept at 0 and set when handling the link-up
|
||||
* interrupt. This removes the possibility of receiving VL15 MAD
|
||||
* packets before this HFI is ready.
|
||||
*/
|
||||
u16 vl15buf_cached;
|
||||
|
||||
|
||||
u8 n_krcv_queues;
|
||||
u8 qos_shift;
|
||||
|
||||
u16 irev;
|
||||
u32 dc8051_ver; /* 8051 firmware version */
|
||||
|
||||
spinlock_t hfi1_diag_trans_lock;
|
||||
char platform_config[16]; //struct platform_config platform_config
|
||||
char pcfg_cache[176]; //struct platform_config_cache pcfg_cache
|
||||
|
||||
void *diag_client; //struct diag_client *diag_client;
|
||||
|
||||
|
||||
void *msix_entries; //struct hfi1_msix_entry *msix_entries;
|
||||
u32 num_msix_entries;
|
||||
|
||||
/* INTx information */
|
||||
u32 requested_intx_irq;
|
||||
char intx_name[MAX_NAME_SIZE];
|
||||
|
||||
/* general interrupt: mask of handled interrupts */
|
||||
u64 gi_mask[CCE_NUM_INT_CSRS];
|
||||
|
||||
struct rcv_array_data rcv_entries;
|
||||
|
||||
|
||||
u16 psxmitwait_check_rate;
|
||||
char synth_stats_timer[80]; //struct timer_list synth_stats_timer
|
||||
char *cntrnames;
|
||||
size_t cntrnameslen;
|
||||
size_t ndevcntrs;
|
||||
u64 *cntrs;
|
||||
u64 *scntrs;
|
||||
u64 last_tx;
|
||||
u64 last_rx;
|
||||
size_t nportcntrs;
|
||||
char *portcntrnames;
|
||||
size_t portcntrnameslen;
|
||||
|
||||
char hfi1_snoop[192]; //struct hfi1_snoop_data hfi1_snoop
|
||||
|
||||
char err_info_rcvport[24]; //struct err_info_rcvport err_info_rcvport
|
||||
char err_info_rcv_constraint[8]; //struct err_info_constraint err_info_rcv_constraint
|
||||
char err_info_xmit_constraint[8]; //struct err_info_constraint err_info_xmit_constraint
|
||||
|
||||
atomic_t drop_packet;
|
||||
u8 do_drop;
|
||||
u8 err_info_uncorrectable;
|
||||
u8 err_info_fmconfig;
|
||||
u64 cce_err_status_cnt[NUM_CCE_ERR_STATUS_COUNTERS];
|
||||
u64 rcv_err_status_cnt[NUM_RCV_ERR_STATUS_COUNTERS];
|
||||
u64 misc_err_status_cnt[NUM_MISC_ERR_STATUS_COUNTERS];
|
||||
u64 send_pio_err_status_cnt[NUM_SEND_PIO_ERR_STATUS_COUNTERS];
|
||||
u64 send_dma_err_status_cnt[NUM_SEND_DMA_ERR_STATUS_COUNTERS];
|
||||
u64 send_egress_err_status_cnt[NUM_SEND_EGRESS_ERR_STATUS_COUNTERS];
|
||||
u64 send_err_status_cnt[NUM_SEND_ERR_STATUS_COUNTERS];
|
||||
|
||||
|
||||
u64 sw_ctxt_err_status_cnt[NUM_SEND_CTXT_ERR_STATUS_COUNTERS];
|
||||
|
||||
u64 sw_send_dma_eng_err_status_cnt[
|
||||
NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS];
|
||||
|
||||
u64 sw_cce_err_status_aggregate;
|
||||
|
||||
u64 sw_rcv_bypass_packet_errors;
|
||||
|
||||
void *rnormal_rhf_rcv_functions[8]; //hf_rcv_function_ptr normal_rhf_rcv_functions[8]
|
||||
|
||||
u64 lcb_err_en;
|
||||
send_routine process_pio_send ____cacheline_aligned_in_smp;
|
||||
send_routine process_dma_send;
|
||||
void *pio_inline_send; //void (*pio_inline_send)(struct hfi1_devdata *dd, struct pio_buf *pbuf,u64 pbc, const void *from, size_t count);
|
||||
struct hfi1_pportdata *pport;
|
||||
|
||||
void **rcd; //struct hfi1_ctxtdata **rcd;
|
||||
u64 __percpu *int_counter;
|
||||
|
||||
u16 flags;
|
||||
|
||||
u8 num_pports;
|
||||
|
||||
u8 first_user_ctxt;
|
||||
|
||||
|
||||
|
||||
seqlock_t sc2vl_lock ____cacheline_aligned_in_smp;
|
||||
u64 sc2vl[4];
|
||||
|
||||
void *rhf_rcv_function_map; //rhf_rcv_function_ptr *rhf_rcv_function_map
|
||||
u64 __percpu *rcv_limit;
|
||||
u16 rhf_offset;
|
||||
|
||||
|
||||
|
||||
u8 oui1;
|
||||
u8 oui2;
|
||||
u8 oui3;
|
||||
u8 dc_shutdown;
|
||||
|
||||
|
||||
char rcverr_timer[80]; //struct timer_list rcverr_timer
|
||||
|
||||
wait_queue_head_t event_queue;
|
||||
|
||||
|
||||
__le64 *rcvhdrtail_dummy_kvaddr;
|
||||
dma_addr_t rcvhdrtail_dummy_dma;
|
||||
|
||||
u32 rcv_ovfl_cnt;
|
||||
|
||||
spinlock_t aspm_lock;
|
||||
|
||||
atomic_t aspm_disabled_cnt;
|
||||
|
||||
atomic_t user_refcount;
|
||||
|
||||
struct completion user_comp;
|
||||
bool eprom_available;
|
||||
bool aspm_supported;
|
||||
bool aspm_enabled;
|
||||
void *sdma_rht; //struct rhashtable sdma_rht
|
||||
|
||||
char kobj[64]; //struct kobject kobj
|
||||
};
|
||||
|
||||
/* USED FILEDS */
|
||||
// struct hfi1_devdata {
|
||||
// struct list_head list; //used
|
||||
// /* pointers to related structs for this device */
|
||||
// /* pci access data structure */
|
||||
// struct pci_dev *pcidev; //used
|
||||
// /* lock for sdma_map */
|
||||
// spinlock_t sde_map_lock; //used
|
||||
// /* array of vl maps */
|
||||
// struct sdma_vl_map __rcu *sdma_map; //used
|
||||
// dma_addr_t sdma_pad_phys; //used
|
||||
// /* array of engines sized by num_sdma */
|
||||
// struct sdma_engine *per_sdma; //used
|
||||
// struct hfi1_pportdata *pport; //used
|
||||
// };
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
#endif /* !__HFI1_ORIG__ */
|
||||
|
||||
/* 8051 firmware version helper */
|
||||
#define dc8051_ver(a, b) ((a) << 8 | (b))
|
||||
@ -892,23 +510,6 @@ static inline void pause_for_credit_return(struct hfi1_devdata *dd)
|
||||
udelay(usec ? usec : 1);
|
||||
}
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
#define OPA_MAX_SCS 32 // from opa_smi.h
|
||||
|
||||
/**
|
||||
* sc_to_vlt() reverse lookup sc to vl
|
||||
* @dd - devdata
|
||||
* @sc5 - 5 bit sc
|
||||
*/
|
||||
static inline u8 sc_to_vlt(struct hfi1_devdata *dd, u8 sc5)
|
||||
{
|
||||
if (sc5 >= OPA_MAX_SCS)
|
||||
return (u8)(0xff);
|
||||
|
||||
return *(((u8 *)dd->sc2vl) + sc5);
|
||||
}
|
||||
#ifdef __HFI1_ORIG__
|
||||
#define PKEY_MEMBER_MASK 0x8000
|
||||
#define PKEY_LOW_15_MASK 0x7fff
|
||||
|
||||
@ -1619,4 +1220,26 @@ __print_symbolic(opcode, \
|
||||
ib_opcode_name(CNP))
|
||||
|
||||
#endif /* __HFI1_ORIG__ */
|
||||
|
||||
/* This include is at the end of this file on purpose,
|
||||
* because it needs other structs defined here.
|
||||
* Except for static inlines that need these types.
|
||||
*/
|
||||
#include <hfi1/hfi1_generated_structs.h>
|
||||
|
||||
#define OPA_MAX_SCS 32 // from opa_smi.h
|
||||
|
||||
/**
|
||||
* sc_to_vlt() reverse lookup sc to vl
|
||||
* @dd - devdata
|
||||
* @sc5 - 5 bit sc
|
||||
*/
|
||||
static inline u8 sc_to_vlt(struct hfi1_devdata *dd, u8 sc5)
|
||||
{
|
||||
if (sc5 >= OPA_MAX_SCS)
|
||||
return (u8)(0xff);
|
||||
|
||||
return *(((u8 *)dd->sc2vl) + sc5);
|
||||
}
|
||||
|
||||
#endif /* _HFI1_KERNEL_H */
|
||||
|
||||
100
kernel/include/hfi1/hfi1_generated_structs.h
Normal file
100
kernel/include/hfi1/hfi1_generated_structs.h
Normal file
@ -0,0 +1,100 @@
|
||||
struct hfi1_pportdata {
|
||||
union {
|
||||
struct {
|
||||
char padding0[1907];
|
||||
u8 vls_operational;
|
||||
};
|
||||
};
|
||||
};
|
||||
struct hfi1_ctxtdata {
|
||||
union {
|
||||
struct {
|
||||
char padding0[144];
|
||||
unsigned int ctxt;
|
||||
};
|
||||
struct {
|
||||
char padding1[172];
|
||||
u32 rcv_array_groups;
|
||||
};
|
||||
struct {
|
||||
char padding2[176];
|
||||
u32 eager_base;
|
||||
};
|
||||
struct {
|
||||
char padding3[180];
|
||||
u32 expected_count;
|
||||
};
|
||||
struct {
|
||||
char padding4[184];
|
||||
u32 expected_base;
|
||||
};
|
||||
struct {
|
||||
char padding5[192];
|
||||
struct exp_tid_set tid_group_list;
|
||||
};
|
||||
struct {
|
||||
char padding6[216];
|
||||
struct exp_tid_set tid_used_list;
|
||||
};
|
||||
struct {
|
||||
char padding7[240];
|
||||
struct exp_tid_set tid_full_list;
|
||||
};
|
||||
struct {
|
||||
char padding8[432];
|
||||
struct hfi1_devdata *dd;
|
||||
};
|
||||
};
|
||||
};
|
||||
struct hfi1_devdata {
|
||||
union {
|
||||
struct {
|
||||
char padding0[2984];
|
||||
u8 *kregbase1;
|
||||
};
|
||||
struct {
|
||||
char padding1[2992];
|
||||
resource_size_t physaddr;
|
||||
};
|
||||
struct {
|
||||
char padding2[3320];
|
||||
u64 default_desc1;
|
||||
};
|
||||
struct {
|
||||
char padding3[3352];
|
||||
dma_addr_t sdma_pad_phys;
|
||||
};
|
||||
struct {
|
||||
char padding4[3376];
|
||||
struct sdma_engine *per_sdma;
|
||||
};
|
||||
struct {
|
||||
char padding5[3384];
|
||||
struct sdma_vl_map *sdma_map;
|
||||
};
|
||||
struct {
|
||||
char padding6[3432];
|
||||
void *piobase;
|
||||
};
|
||||
struct {
|
||||
char padding7[3440];
|
||||
void *rcvarray_wc;
|
||||
};
|
||||
struct {
|
||||
char padding8[3688];
|
||||
u32 chip_rcv_array_count;
|
||||
};
|
||||
struct {
|
||||
char padding9[6872];
|
||||
struct hfi1_pportdata *pport;
|
||||
};
|
||||
struct {
|
||||
char padding10[6896];
|
||||
u16 flags;
|
||||
};
|
||||
struct {
|
||||
char padding11[6920];
|
||||
u64 sc2vl[4];
|
||||
};
|
||||
};
|
||||
};
|
||||
614
kernel/script/dwarf-extract-struct.c
Normal file
614
kernel/script/dwarf-extract-struct.c
Normal file
@ -0,0 +1,614 @@
|
||||
/*
|
||||
* Trivial dwarf parser to extract part of a struct from debug infos
|
||||
*
|
||||
* Author: Dominique Martinet <dominique.martinet@cea.fr>
|
||||
* License: WTFPLv2
|
||||
*
|
||||
* Canonical source: http://cgit.notk.org/asmadeus/dwarf-extract-struct.git
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include "libdwarf/dwarf.h"
|
||||
#include "libdwarf/libdwarf.h"
|
||||
|
||||
|
||||
static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name,
|
||||
const char *field_names[], int field_count);
|
||||
static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name,
|
||||
const char *field_names[], int field_count, int level);
|
||||
static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name,
|
||||
const char *field_names[], int field_count, int level);
|
||||
static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name,
|
||||
int pad_num);
|
||||
|
||||
int debug = 0;
|
||||
|
||||
void usage(const char *argv[]) {
|
||||
fprintf(stderr, "%s debug_file struct_name field [field...]\n",
|
||||
argv[0]);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
Dwarf_Debug dbg = 0;
|
||||
int fd = -1;
|
||||
const char *filepath;
|
||||
const char *struct_name;
|
||||
int res = DW_DLV_ERROR;
|
||||
Dwarf_Error error;
|
||||
Dwarf_Handler errhand = 0;
|
||||
Dwarf_Ptr errarg = 0;
|
||||
|
||||
if(argc < 4) {
|
||||
usage(argv);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
filepath = argv[1];
|
||||
struct_name = argv[2];
|
||||
|
||||
fd = open(filepath,O_RDONLY);
|
||||
if(fd < 0) {
|
||||
fprintf(stderr, "Failure attempting to open %s\n",filepath);
|
||||
}
|
||||
res = dwarf_init(fd, DW_DLC_READ, errhand, errarg, &dbg, &error);
|
||||
if(res != DW_DLV_OK) {
|
||||
fprintf(stderr, "Giving up, cannot do DWARF processing\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parse_dwarf(dbg, struct_name, argv + 3, argc - 3);
|
||||
|
||||
res = dwarf_finish(dbg,&error);
|
||||
if(res != DW_DLV_OK) {
|
||||
fprintf(stderr, "dwarf_finish failed!\n");
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name,
|
||||
const char *field_names[], int field_count) {
|
||||
Dwarf_Bool is_info = 1;
|
||||
Dwarf_Unsigned cu_length;
|
||||
Dwarf_Half cu_version;
|
||||
Dwarf_Off cu_abbrev_offset;
|
||||
Dwarf_Half cu_pointer_size;
|
||||
Dwarf_Half cu_offset_size;
|
||||
Dwarf_Half cu_extension_size;
|
||||
Dwarf_Sig8 type_signature;
|
||||
Dwarf_Unsigned type_offset;
|
||||
Dwarf_Unsigned cu_next_offset;
|
||||
Dwarf_Error err;
|
||||
int rc;
|
||||
|
||||
|
||||
while (1) {
|
||||
Dwarf_Die die;
|
||||
|
||||
rc = dwarf_next_cu_header_c(dbg, is_info, &cu_length,
|
||||
&cu_version, &cu_abbrev_offset, &cu_pointer_size,
|
||||
&cu_offset_size, &cu_extension_size, &type_signature,
|
||||
&type_offset, &cu_next_offset, &err);
|
||||
|
||||
if (rc == DW_DLV_NO_ENTRY)
|
||||
break;
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "error dwarf_next_cu_header_c: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
rc = dwarf_siblingof(dbg, NULL, &die, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "first dwarf_siblingof failed: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
find_struct(dbg, die, struct_name, field_names, field_count, 0);
|
||||
}
|
||||
|
||||
fprintf(stderr, "struct %s not found\n", struct_name);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name,
|
||||
const char *field_names[], int field_count, int level) {
|
||||
Dwarf_Die next;
|
||||
Dwarf_Error err;
|
||||
int rc;
|
||||
|
||||
if (level > 1)
|
||||
return;
|
||||
|
||||
do {
|
||||
char *name;
|
||||
const char *tag_name;
|
||||
Dwarf_Half tag;
|
||||
|
||||
rc = dwarf_diename(die, &name, &err);
|
||||
if (rc == DW_DLV_NO_ENTRY) {
|
||||
name = NULL;
|
||||
} else if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "dwarf_diename error: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rc = dwarf_tag(die, &tag, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "dwarf_tag error: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
rc = dwarf_get_TAG_name(tag, &tag_name);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"dwarf_get_TAG_name error: %d\n", rc);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("<%d> %p <%d> %s: %s\n", level, die, tag,
|
||||
tag_name, name ? name : "<no name>");
|
||||
}
|
||||
|
||||
rc = dwarf_child(die, &next, &err);
|
||||
if (rc == DW_DLV_ERROR) {
|
||||
fprintf(stderr, "dwarf_child error: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
exit(1);
|
||||
}
|
||||
if (rc == DW_DLV_OK) {
|
||||
if (tag == DW_TAG_structure_type
|
||||
&& name && strcasecmp(name, struct_name) == 0) {
|
||||
find_fields(dbg, next, struct_name, field_names,
|
||||
field_count, level + 1);
|
||||
fprintf(stderr,
|
||||
"Found struct %s but it did not have all members given!\nMissing:\n",
|
||||
struct_name);
|
||||
for (rc = 0; rc < field_count; rc++) {
|
||||
if (field_names[rc])
|
||||
fprintf(stderr, "%s\n",
|
||||
field_names[rc]);
|
||||
}
|
||||
exit(3);
|
||||
}
|
||||
find_struct(dbg, next, struct_name, field_names,
|
||||
field_count, level + 1);
|
||||
dwarf_dealloc(dbg, next, DW_DLA_DIE);
|
||||
}
|
||||
|
||||
|
||||
rc = dwarf_siblingof(dbg, die, &next, &err);
|
||||
dwarf_dealloc(dbg, die, DW_DLA_DIE);
|
||||
if (name)
|
||||
dwarf_dealloc(dbg, name, DW_DLA_STRING);
|
||||
|
||||
if (rc != DW_DLV_OK)
|
||||
break;
|
||||
|
||||
die = next;
|
||||
} while (die);
|
||||
}
|
||||
|
||||
static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name,
|
||||
const char *field_names[], int field_count, int level) {
|
||||
Dwarf_Die next;
|
||||
Dwarf_Error err;
|
||||
int rc, i, printed_count = 0;
|
||||
|
||||
printf("struct %s {\n\tunion {\n",
|
||||
struct_name);
|
||||
|
||||
do {
|
||||
char *name;
|
||||
const char *tag_name;
|
||||
Dwarf_Half tag;
|
||||
|
||||
rc = dwarf_diename(die, &name, &err);
|
||||
if (rc == DW_DLV_NO_ENTRY) {
|
||||
name = NULL;
|
||||
} else if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "dwarf_diename error: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rc = dwarf_tag(die, &tag, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "dwarf_tag error: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
rc = dwarf_get_TAG_name(tag, &tag_name);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"dwarf_get_TAG_name error: %d\n", rc);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("<%d> %p <%d> %s: %s\n", level, die, tag,
|
||||
tag_name, name ? name : "<no name>");
|
||||
}
|
||||
|
||||
if (tag == DW_TAG_member && name) {
|
||||
for (i = 0; i < field_count; i++) {
|
||||
if (!field_names[i])
|
||||
continue;
|
||||
if (strcasecmp(name, field_names[i]) == 0) {
|
||||
print_field(dbg, die, field_names[i],
|
||||
printed_count);
|
||||
field_names[i] = NULL;
|
||||
printed_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (printed_count == field_count) {
|
||||
printf("\t};\n};\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
rc = dwarf_siblingof(dbg, die, &next, &err);
|
||||
dwarf_dealloc(dbg, die, DW_DLA_DIE);
|
||||
if (name)
|
||||
dwarf_dealloc(dbg, name, DW_DLA_STRING);
|
||||
|
||||
if (rc != DW_DLV_OK)
|
||||
break;
|
||||
|
||||
die = next;
|
||||
} while (die);
|
||||
}
|
||||
|
||||
|
||||
static int dwarf_get_offset(Dwarf_Debug dbg, Dwarf_Die die,
|
||||
int *poffset, Dwarf_Error *perr) {
|
||||
Dwarf_Attribute attr;
|
||||
Dwarf_Unsigned offset;
|
||||
int rc;
|
||||
|
||||
rc = dwarf_attr(die, DW_AT_data_member_location, &attr, perr);
|
||||
if (rc != DW_DLV_OK) {
|
||||
return rc;
|
||||
}
|
||||
Dwarf_Half form;
|
||||
rc = dwarf_whatform(attr, &form, perr);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "Error getting whatform: %s\n",
|
||||
dwarf_errmsg(*perr));
|
||||
exit(5);
|
||||
}
|
||||
if (form == DW_FORM_data1 || form == DW_FORM_data2
|
||||
|| form == DW_FORM_data2 || form == DW_FORM_data4
|
||||
|| form == DW_FORM_data8 || form == DW_FORM_udata) {
|
||||
dwarf_formudata(attr, &offset, 0);
|
||||
} else if (form == DW_FORM_sdata) {
|
||||
Dwarf_Signed soffset;
|
||||
dwarf_formsdata(attr, &soffset, 0);
|
||||
if (soffset < 0) {
|
||||
fprintf(stderr,
|
||||
"unsupported negative offset\n");
|
||||
exit(5);
|
||||
}
|
||||
offset = (Dwarf_Unsigned) soffset;
|
||||
} else {
|
||||
Dwarf_Locdesc **locdescs;
|
||||
Dwarf_Signed len;
|
||||
if (dwarf_loclist_n(attr, &locdescs, &len, perr)
|
||||
== DW_DLV_ERROR) {
|
||||
fprintf(stderr, "unsupported member offset\n");
|
||||
exit(5);
|
||||
}
|
||||
if (len != 1
|
||||
|| locdescs[0]->ld_cents != 1
|
||||
|| (locdescs[0]->ld_s[0]).lr_atom
|
||||
!= DW_OP_plus_uconst) {
|
||||
fprintf(stderr,
|
||||
"unsupported location expression\n");
|
||||
exit(5);
|
||||
}
|
||||
offset = (locdescs[0]->ld_s[0]).lr_number;
|
||||
}
|
||||
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
|
||||
|
||||
*poffset = (int) offset;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
static int dwarf_get_size(Dwarf_Debug dbg, Dwarf_Die die,
|
||||
int *psize, Dwarf_Error *perr) {
|
||||
Dwarf_Attribute attr;
|
||||
Dwarf_Unsigned size;
|
||||
int rc;
|
||||
|
||||
rc = dwarf_attr(die, DW_AT_byte_size, &attr, perr);
|
||||
if (rc != DW_DLV_OK) {
|
||||
return rc;
|
||||
}
|
||||
Dwarf_Half form;
|
||||
rc = dwarf_whatform(attr, &form, perr);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "Error getting whatform: %s\n",
|
||||
dwarf_errmsg(*perr));
|
||||
exit(5);
|
||||
}
|
||||
if (form == DW_FORM_data1 || form == DW_FORM_data2
|
||||
|| form == DW_FORM_data2 || form == DW_FORM_data4
|
||||
|| form == DW_FORM_data8 || form == DW_FORM_udata) {
|
||||
dwarf_formudata(attr, &size, 0);
|
||||
} else if (form == DW_FORM_sdata) {
|
||||
Dwarf_Signed ssize;
|
||||
dwarf_formsdata(attr, &ssize, 0);
|
||||
if (ssize < 0) {
|
||||
fprintf(stderr,
|
||||
"unsupported negative size\n");
|
||||
exit(5);
|
||||
}
|
||||
size = (Dwarf_Unsigned) ssize;
|
||||
} else {
|
||||
Dwarf_Locdesc **locdescs;
|
||||
Dwarf_Signed len;
|
||||
if (dwarf_loclist_n(attr, &locdescs, &len, perr)
|
||||
== DW_DLV_ERROR) {
|
||||
fprintf(stderr, "unsupported member size\n");
|
||||
exit(5);
|
||||
}
|
||||
if (len != 1
|
||||
|| locdescs[0]->ld_cents != 1
|
||||
|| (locdescs[0]->ld_s[0]).lr_atom
|
||||
!= DW_OP_plus_uconst) {
|
||||
fprintf(stderr,
|
||||
"unsupported location expression\n");
|
||||
exit(5);
|
||||
}
|
||||
size = (locdescs[0]->ld_s[0]).lr_number;
|
||||
}
|
||||
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
|
||||
|
||||
*psize = (int) size;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
static int deref_type(Dwarf_Debug dbg, Dwarf_Die type_die,
|
||||
Dwarf_Die *new_type_die, Dwarf_Half *ptype_tag,
|
||||
Dwarf_Error *perr) {
|
||||
Dwarf_Attribute pointer_attr;
|
||||
Dwarf_Off pointer_off;
|
||||
int rc;
|
||||
|
||||
rc = dwarf_attr(type_die, DW_AT_type, &pointer_attr,
|
||||
perr);
|
||||
if (rc != DW_DLV_OK)
|
||||
return rc;
|
||||
|
||||
rc = dwarf_global_formref(pointer_attr, &pointer_off,
|
||||
perr);
|
||||
if (rc != DW_DLV_OK)
|
||||
return rc;
|
||||
|
||||
rc = dwarf_offdie_b(dbg, pointer_off, 1, new_type_die,
|
||||
perr);
|
||||
if (rc != DW_DLV_OK)
|
||||
return rc;
|
||||
|
||||
dwarf_dealloc(dbg, pointer_attr, DW_DLA_ATTR);
|
||||
|
||||
if (ptype_tag)
|
||||
rc = dwarf_tag(*new_type_die, ptype_tag, perr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name,
|
||||
int padnum) {
|
||||
Dwarf_Attribute attr;
|
||||
Dwarf_Error err;
|
||||
int offset = 0;
|
||||
char type_buf[1024];
|
||||
char array_buf[128] = "";
|
||||
int rc;
|
||||
|
||||
rc = dwarf_get_offset(dbg, die, &offset, &err);
|
||||
if (rc == DW_DLV_NO_ENTRY) {
|
||||
fprintf(stderr, "Found %s but no offset, assuming 0\n",
|
||||
field_name);
|
||||
} else if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "Error getting dwarf attr offset: %s\n",
|
||||
dwarf_errmsg(err));
|
||||
exit(4);
|
||||
}
|
||||
|
||||
rc = dwarf_attr(die, DW_AT_type, &attr, &err);
|
||||
if (rc == DW_DLV_NO_ENTRY) {
|
||||
fprintf(stderr,
|
||||
"Found %s but no type, can't assume that one out..\n",
|
||||
field_name);
|
||||
exit(6);
|
||||
} else if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "Error getting dwarf attrlist: %s\n",
|
||||
dwarf_errmsg(err));
|
||||
exit(6);
|
||||
} else {
|
||||
Dwarf_Die type_die, next;
|
||||
Dwarf_Off type_off;
|
||||
Dwarf_Half type_tag;
|
||||
char *type_name;
|
||||
int pointer = 0;
|
||||
|
||||
rc = dwarf_global_formref(attr, &type_off, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"Error getting ref offset for type: %s\n",
|
||||
dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
|
||||
rc = dwarf_offdie_b(dbg, type_off, 1, &type_die, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"Error getting die from offset for type: %s\n",
|
||||
dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
|
||||
rc = dwarf_tag(type_die, &type_tag, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "dwarf_tag error: %d %s\n",
|
||||
rc, dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
|
||||
if (type_tag == DW_TAG_pointer_type) {
|
||||
rc = deref_type(dbg, type_die, &next,
|
||||
&type_tag, &err);
|
||||
/* No entry here means void* */
|
||||
if (rc != DW_DLV_NO_ENTRY) {
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"Could not deref type for %s: %s\n",
|
||||
field_name, dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
|
||||
dwarf_dealloc(dbg, type_die, DW_DLA_DIE);
|
||||
type_die = next;
|
||||
}
|
||||
|
||||
pointer++;
|
||||
}
|
||||
if (type_tag == DW_TAG_array_type) {
|
||||
int next_offset, size;
|
||||
|
||||
rc = deref_type(dbg, type_die, &next,
|
||||
&type_tag, &err);
|
||||
if (rc == DW_DLV_NO_ENTRY) {
|
||||
fprintf(stderr,
|
||||
"Could not deref array type for %s: no entry\n",
|
||||
field_name);
|
||||
exit(7);
|
||||
}
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"Could not deref type for %s: %s\n",
|
||||
field_name, dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
|
||||
dwarf_dealloc(dbg, type_die, DW_DLA_DIE);
|
||||
type_die = next;
|
||||
|
||||
/* get next pos */
|
||||
rc = dwarf_siblingof(dbg, die, &next, &err);
|
||||
if (rc == DW_DLV_NO_ENTRY) {
|
||||
fprintf(stderr,
|
||||
"Need to get sibling for array size but none left, please implement through whole struct size instead. field %s\n",
|
||||
field_name);
|
||||
exit(7);
|
||||
}
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"Could not get sibling of field %s: %s\n",
|
||||
field_name, dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
rc = dwarf_get_offset(dbg, next, &next_offset, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"Could not get neighbor's offset for field %s: %s\n",
|
||||
field_name, dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
dwarf_dealloc(dbg, next, DW_DLA_DIE);
|
||||
|
||||
/* get type size */
|
||||
next = type_die;
|
||||
if (type_tag == DW_TAG_typedef) {
|
||||
rc = deref_type(dbg, type_die, &next, NULL, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"Could not deref array typedef type for %s: %s\n",
|
||||
field_name, dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
}
|
||||
rc = dwarf_get_size(dbg, next, &size, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"Could not get size for type for %s: %s\n",
|
||||
field_name, dwarf_errmsg(err));
|
||||
exit(7);
|
||||
}
|
||||
if (next != type_die)
|
||||
dwarf_dealloc(dbg, next, DW_DLA_DIE);
|
||||
|
||||
snprintf(array_buf, 128, "[%d]", (next_offset - offset) / size);
|
||||
}
|
||||
|
||||
/* If it's still pointer at this point, it's void * */
|
||||
if (type_tag != DW_TAG_pointer_type) {
|
||||
rc = dwarf_diename(type_die, &type_name, &err);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr, "dwarf_diename error: %s\n",
|
||||
rc == DW_DLV_NO_ENTRY ?
|
||||
"no name" : dwarf_errmsg(err));
|
||||
const char *tag_name;
|
||||
|
||||
rc = dwarf_get_TAG_name(type_tag, &tag_name);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"dwarf_get_TAG_name error: %d\n",
|
||||
rc);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Bad tag %s (%d)?\n",
|
||||
tag_name, type_tag);
|
||||
exit(7);
|
||||
}
|
||||
}
|
||||
|
||||
if (type_tag == DW_TAG_structure_type) {
|
||||
snprintf(type_buf, 1024, "struct %s %s",
|
||||
type_name, pointer ? "*" : "");
|
||||
} else if (type_tag == DW_TAG_base_type
|
||||
|| type_tag == DW_TAG_typedef) {
|
||||
snprintf(type_buf, 1024, "%s %s", type_name,
|
||||
pointer ? "*" : "");
|
||||
} else if (type_tag == DW_TAG_pointer_type) {
|
||||
snprintf(type_buf, 1024, "void *");
|
||||
} else {
|
||||
const char *tag_name;
|
||||
|
||||
rc = dwarf_get_TAG_name(type_tag, &tag_name);
|
||||
if (rc != DW_DLV_OK) {
|
||||
fprintf(stderr,
|
||||
"dwarf_get_TAG_name error: %d\n", rc);
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"Type tag %s (%d) is not implemented, please add it\n",
|
||||
tag_name, type_tag);
|
||||
exit(7);
|
||||
}
|
||||
|
||||
dwarf_dealloc(dbg, type_name, DW_DLA_STRING);
|
||||
dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
|
||||
dwarf_dealloc(dbg, type_die, DW_DLA_DIE);
|
||||
}
|
||||
|
||||
printf("\t\tstruct {\n\t\t\tchar padding%i[%u];\n\t\t\t%s%s%s;\n\t\t};\n",
|
||||
padnum, (unsigned int) offset,
|
||||
type_buf, field_name, array_buf);
|
||||
}
|
||||
38
kernel/script/regenerate_hfi1_header.sh
Executable file
38
kernel/script/regenerate_hfi1_header.sh
Executable file
@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
|
||||
# usage:
|
||||
# /path/to/regenerate_hfi1_header.sh [hfi1.ko]
|
||||
|
||||
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
||||
ROOTDIR=$(readlink -m "$SCRIPT_PATH")
|
||||
ROOTDIR=$(dirname "$ROOTDIR")
|
||||
set -e
|
||||
|
||||
# static configuration-ish
|
||||
declare -r DES_BIN="${ROOTDIR}/dwarf-extract-struct"
|
||||
declare -r DES_SRC="${DES_BIN}.c"
|
||||
declare -r HDR="${ROOTDIR}/../include/hfi1/hfi1_generated_structs.h"
|
||||
|
||||
error() {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
HFI1_KO="${1-$(modprobe -n hfi1)}" || \
|
||||
error "Could not find hfi1 module and no argument given. Usage: $0 [hfi1.ko]"
|
||||
|
||||
|
||||
[[ "$DES_BIN" -nt "$DES_SRC" ]] || \
|
||||
gcc -o "$DES_BIN" -g -ldwarf "$DES_SRC" || \
|
||||
error "Could not compile, install libdwarf-devel ?"
|
||||
|
||||
"$DES_BIN" "$HFI1_KO" hfi1_pportdata vls_operational > "$HDR"
|
||||
|
||||
"$DES_BIN" "$HFI1_KO" hfi1_ctxtdata \
|
||||
ctxt rcv_array_groups eager_base expected_count expected_base \
|
||||
tid_group_list tid_used_list tid_full_list dd >> "$HDR"
|
||||
|
||||
"$DES_BIN" "$HFI1_KO" hfi1_devdata \
|
||||
per_sdma sdma_pad_phys sdma_map pport chip_rcv_array_count \
|
||||
kregbase1 piobase physaddr rcvarray_wc default_desc1 flags \
|
||||
sc2vl >> "$HDR"
|
||||
@ -573,8 +573,8 @@ int hfi1_map_device_addresses(struct hfi1_filedata *fd)
|
||||
/*
|
||||
* Map device addresses if not mapped or mapping changed.
|
||||
*/
|
||||
if (proc->hfi1_kregbase != dd->kregbase) {
|
||||
void *hfi1_kregbase = dd->kregbase;
|
||||
if (proc->hfi1_kregbase != dd->kregbase1) {
|
||||
void *hfi1_kregbase = dd->kregbase1;
|
||||
|
||||
phys = dd->physaddr;
|
||||
attr = PTATTR_UNCACHABLE | PTATTR_WRITABLE;
|
||||
|
||||
Reference in New Issue
Block a user