Commit 1a18111c authored by Alessandro Rubini's avatar Alessandro Rubini

tool/wrpc-dump: change the access mode, to avoid "gcc -m32"

Accessing data structures in the host to get target fields is broken:
we may have different data size or alignment, or whatever. The hack
of using "-m32" to be able to access lm32 fields from x86-64 is not
clean (we imply the i386 and target have the same size/alignment).
Even worse, not everybody has an x86-64 cross-compiler for i386.

Thus, we use OFFSET_OF in the target, with the lm32 cross compiler,
to build a binary table that is then accessed by the host.

In order to link the data structure in the host we use the assembler
instead of objcopy. With objcopy we'd need to spell out the bfd name
of the host, and we'd get horrible names like
   struct dump_info _binary_dump_info_host_bin_start[];
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <>
parent 9a6a1443
......@@ -24,6 +24,7 @@ obj-$(CONFIG_WR_NODE) += wrc_main.o
obj-$(CONFIG_WR_SWITCH) += wrs_main.o
obj-$(CONFIG_WR_SWITCH) += ipc/minipc-mem-server.o ipc/rt_ipc.o
obj-y += dump-info.o
# our linker script is preprocessed, so have a rule here
%.ld: %.ld.S $(AUTOCONF) .config
$(CC) -include $(AUTOCONF) -E -P $*.ld.S -o $@
......@@ -37,12 +38,15 @@ cflags-$(CONFIG_PPSI) += \
-ffreestanding \
-include include/ppsi-wrappers.h \
-Iinclude \
-I$(PPSI)/include \
-I$(PPSI)/arch-wrpc \
-I$(PPSI)/arch-wrpc/include \
-I$(PPSI)/proto-ext-whiterabbit \
# in order to build tools/wrpc-dump, we need these flags, even for wrs builds
cflags-y += \
-I$(PPSI)/arch-wrpc/include \
obj-ppsi = \
#include <sys/types.h>
#include <ppsi/ppsi.h>
#include <softpll_ng.h>
#include "dump-info.h"
struct dump_info dump_info[] = {
/* map for fields of ppsi structures */
#define DUMP_STRUCT struct pp_globals
DUMP_FIELD(pointer, pp_instances), /* FIXME: follow this */
DUMP_FIELD(pointer, servo), /* FIXME: follow this */
DUMP_FIELD(pointer, rt_opts),
DUMP_FIELD(pointer, defaultDS),
DUMP_FIELD(pointer, currentDS),
DUMP_FIELD(pointer, parentDS),
DUMP_FIELD(pointer, timePropertiesDS),
DUMP_FIELD(int, ebest_idx),
DUMP_FIELD(int, ebest_updated),
DUMP_FIELD(int, nlinks),
DUMP_FIELD(int, max_links),
//DUMP_FIELD(struct pp_globals_cfg cfg),
DUMP_FIELD(int, rxdrop),
DUMP_FIELD(int, txdrop),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, global_ext_data),
#define DUMP_STRUCT DSDefault /* Horrible typedef */
DUMP_FIELD(Boolean, twoStepFlag),
DUMP_FIELD(ClockIdentity, clockIdentity),
DUMP_FIELD(UInteger16, numberPorts),
DUMP_FIELD(ClockQuality, clockQuality),
DUMP_FIELD(UInteger8, priority1),
DUMP_FIELD(UInteger8, priority2),
DUMP_FIELD(UInteger8, domainNumber),
DUMP_FIELD(Boolean, slaveOnly),
#define DUMP_STRUCT DSCurrent /* Horrible typedef */
DUMP_FIELD(UInteger16, stepsRemoved),
DUMP_FIELD(TimeInternal, offsetFromMaster),
DUMP_FIELD(TimeInternal, meanPathDelay), /* oneWayDelay */
DUMP_FIELD(UInteger16, primarySlavePortNumber),
#define DUMP_STRUCT DSParent /* Horrible typedef */
DUMP_FIELD(PortIdentity, parentPortIdentity),
DUMP_FIELD(UInteger16, observedParentOffsetScaledLogVariance),
DUMP_FIELD(Integer32, observedParentClockPhaseChangeRate),
DUMP_FIELD(ClockIdentity, grandmasterIdentity),
DUMP_FIELD(ClockQuality, grandmasterClockQuality),
DUMP_FIELD(UInteger8, grandmasterPriority1),
DUMP_FIELD(UInteger8, grandmasterPriority2),
#define DUMP_STRUCT DSTimeProperties /* Horrible typedef */
DUMP_FIELD(Integer16, currentUtcOffset),
DUMP_FIELD(Boolean, currentUtcOffsetValid),
DUMP_FIELD(Boolean, leap59),
DUMP_FIELD(Boolean, leap61),
DUMP_FIELD(Boolean, timeTraceable),
DUMP_FIELD(Boolean, frequencyTraceable),
DUMP_FIELD(Boolean, ptpTimescale),
DUMP_FIELD(Enumeration8, timeSource),
#define DUMP_STRUCT struct wr_servo_state
DUMP_FIELD_SIZE(char, if_name, 16),
DUMP_FIELD(unsigned_long, flags),
DUMP_FIELD(int, state),
DUMP_FIELD(Integer32, delta_tx_m),
DUMP_FIELD(Integer32, delta_rx_m),
DUMP_FIELD(Integer32, delta_tx_s),
DUMP_FIELD(Integer32, delta_rx_s),
DUMP_FIELD(Integer32, fiber_fix_alpha),
DUMP_FIELD(Integer32, clock_period_ps),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(Integer32, delta_ms_prev),
DUMP_FIELD(int, missed_iters),
DUMP_FIELD(TimeInternal, mu), /* half of the RTT */
DUMP_FIELD(Integer64, picos_mu),
DUMP_FIELD(Integer32, cur_setpoint),
DUMP_FIELD(Integer32, delta_ms),
DUMP_FIELD(UInteger32, update_count),
DUMP_FIELD(int, tracking_enabled),
DUMP_FIELD_SIZE(char, servo_state_name, 32),
DUMP_FIELD(Integer64, skew),
DUMP_FIELD(Integer64, offset),
DUMP_FIELD(UInteger32, n_err_state),
DUMP_FIELD(UInteger32, n_err_offset),
DUMP_FIELD(UInteger32, n_err_delta_rtt),
#define DUMP_STRUCT struct pp_instance
DUMP_FIELD(int, state),
DUMP_FIELD(int, next_state),
DUMP_FIELD(int, next_delay),
DUMP_FIELD(int, is_new_state),
DUMP_FIELD(pointer, arch_data),
DUMP_FIELD(pointer, ext_data),
DUMP_FIELD(unsigned_long, d_flags),
DUMP_FIELD(unsigned_char, flags),
DUMP_FIELD(unsigned_char, role),
DUMP_FIELD(unsigned_char, proto),
DUMP_FIELD(pointer, glbs),
DUMP_FIELD(pointer, n_ops),
DUMP_FIELD(pointer, t_ops),
DUMP_FIELD(pointer, __tx_buffer),
DUMP_FIELD(pointer, __rx_buffer),
DUMP_FIELD(pointer, tx_frame),
DUMP_FIELD(pointer, rx_frame),
DUMP_FIELD(pointer, tx_ptp),
DUMP_FIELD(pointer, rx_ptp),
/* This is a sub-structure */
DUMP_FIELD(int, ch[0].fd),
DUMP_FIELD(pointer, ch[0].custom),
DUMP_FIELD(pointer, ch[0].arch_data),
DUMP_FIELD_SIZE(bina, ch[0].addr, 6),
DUMP_FIELD(int, ch[0].pkt_present),
DUMP_FIELD(int, ch[1].fd),
DUMP_FIELD(pointer, ch[1].custom),
DUMP_FIELD(pointer, ch[1].arch_data),
DUMP_FIELD_SIZE(bina, ch[1].addr, 6),
DUMP_FIELD(int, ch[1].pkt_present),
DUMP_FIELD(ip_address, mcast_addr),
DUMP_FIELD(int, tx_offset),
DUMP_FIELD(int, rx_offset),
DUMP_FIELD_SIZE(bina, peer, 6),
DUMP_FIELD(uint16_t, peer_vid),
DUMP_FIELD(TimeInternal, t1),
DUMP_FIELD(TimeInternal, t2),
DUMP_FIELD(TimeInternal, t3),
DUMP_FIELD(TimeInternal, t4),
DUMP_FIELD(TimeInternal, cField),
DUMP_FIELD(TimeInternal, last_rcv_time),
DUMP_FIELD(TimeInternal, last_snt_time),
DUMP_FIELD(UInteger16, frgn_rec_num),
DUMP_FIELD(Integer16, frgn_rec_best),
//DUMP_FIELD(struct pp_frgn_master frgn_master[PP_NR_FOREIGN_RECORDS]),
DUMP_FIELD(pointer, portDS),
//DUMP_FIELD(unsigned long timeouts[__PP_TO_ARRAY_SIZE]),
DUMP_FIELD(UInteger16, recv_sync_sequence_id),
DUMP_FIELD(Integer8, log_min_delay_req_interval),
//DUMP_FIELD(UInteger16 sent_seq[__PP_NR_MESSAGES_TYPES]),
DUMP_FIELD_SIZE(bina, received_ptp_header, sizeof(MsgHeader)),
//DUMP_FIELD(pointer, iface_name),
//DUMP_FIELD(pointer, port_name),
DUMP_FIELD(int, port_idx),
DUMP_FIELD(int, vlans_array_len),
/* FIXME: array */
DUMP_FIELD(int, nvlans),
/* sub structure */
DUMP_FIELD_SIZE(char, cfg.port_name, 16),
DUMP_FIELD_SIZE(char, cfg.iface_name, 16),
DUMP_FIELD(int, cfg.ext),
DUMP_FIELD(int, cfg.ext),
DUMP_FIELD(unsigned_long, ptp_tx_count),
DUMP_FIELD(unsigned_long, ptp_rx_count),
#define DUMP_STRUCT struct softpll_state
DUMP_FIELD(int, mode),
DUMP_FIELD(int, seq_state),
DUMP_FIELD(int, dac_timeout),
DUMP_FIELD(int, default_dac_main),
DUMP_FIELD(int, delock_count),
DUMP_FIELD(uint32_t, irq_count),
DUMP_FIELD(int, mpll_shift_ps),
DUMP_FIELD(int, helper.p_adder),
DUMP_FIELD(int, helper.p_setpoint),
DUMP_FIELD(int, helper.tag_d0),
DUMP_FIELD(int, helper.ref_src),
DUMP_FIELD(int, helper.sample_n),
DUMP_FIELD(int, helper.delock_count),
/* FIXME: missing helper.pi etc.. */
DUMP_FIELD(int, ext.enabled),
DUMP_FIELD(int, ext.align_state),
DUMP_FIELD(int, ext.align_timer),
DUMP_FIELD(int, ext.align_target),
DUMP_FIELD(int, ext.align_step),
DUMP_FIELD(int, ext.align_shift),
DUMP_FIELD(int, mpll.state),
/* FIXME: mpll.pi etc */
DUMP_FIELD(int, mpll.adder_ref),
DUMP_FIELD(int, mpll.adder_out),
DUMP_FIELD(int, mpll.tag_ref),
DUMP_FIELD(int, mpll.tag_out),
DUMP_FIELD(int, mpll.tag_ref_d),
DUMP_FIELD(int, mpll.tag_out_d),
DUMP_FIELD(uint32_t, mpll.seq_ref),
DUMP_FIELD(int, mpll.seq_out),
DUMP_FIELD(int, mpll.match_state),
DUMP_FIELD(int, mpll.match_seq),
DUMP_FIELD(int, mpll.phase_shift_target),
DUMP_FIELD(int, mpll.phase_shift_current),
DUMP_FIELD(int, mpll.id_ref),
DUMP_FIELD(int, mpll.id_out),
DUMP_FIELD(int, mpll.sample_n),
DUMP_FIELD(int, mpll.delock_count),
DUMP_FIELD(int, mpll.dac_index),
DUMP_FIELD(int, mpll.enabled),
#define DUMP_STRUCT struct spll_fifo_log
DUMP_FIELD(uint32_t, trr),
DUMP_FIELD(uint16_t, irq_count),
DUMP_FIELD(uint16_t, tag_count),
/* FIXME: aux_state and ptracker_state -- variable-len arrays */
* This header defines structures for dumping other structures from
* binary files. Every arch has a different endianness and alignment/size,
* so we can't just use the structures from the host compiler. It used to
* work for lm32/i386, but it fails with x86-64, so let's change attitude.
#include <stdint.h>
* To ease copying from header files, allow int, char and other known types.
* Please add more type as more structures are included here
enum dump_type {
dump_type_char, /* for zero-terminated strings */
dump_type_bina, /* for binary stull in MAC format */
/* normal types follow */
/* and strange ones, from IEEE */
/* and this is ours */
/* because of the sizeof later on, we need these typedefs */
typedef void * pointer;
typedef unsigned long unsigned_long;
typedef unsigned char unsigned_char;
typedef unsigned short unsigned_short;
typedef struct {unsigned char addr[4];} ip_address;
* This is generated with the target compiler, and then linked
* by the host compiler, so size and alignment must be safe. Then, the
* first structure in each group has the endian flag and the structure name.
* Following ones have zero in endian flag and field name.
#define DUMP_ENDIAN_FLAG 0x12345678
struct dump_info {
uint32_t endian_flag;
uint32_t type;
uint32_t offset;
uint32_t size;
char name[48];
extern struct dump_info dump_info[]; /* wrpc-sw/dump-info.c -> bina -> elf */
#define DUMP_HEADER(_struct) { \
.endian_flag = DUMP_ENDIAN_FLAG, \
.name = _struct, \
/* The macros below rely on DUMP_STRUCT that must be externally defined */
#define DUMP_FIELD(_type, _fname) { \
.endian_flag = 0, \
.type = dump_type_ ## _type, \
.offset = offsetof(DUMP_STRUCT, _fname),\
.size = sizeof(_type), \
.name = #_fname, \
#define DUMP_FIELD_SIZE(_type, _fname, _size) { \
.endian_flag = 0, \
.type = dump_type_ ## _type, \
.offset = offsetof(DUMP_STRUCT, _fname),\
.size = _size, \
.name = #_fname, \
......@@ -42,11 +42,20 @@ eb-w1-write: eb-w1-write.c ../dev/w1.c ../dev/w1-eeprom.c eb-w1.c
sdb-wrpc.bin: sdbfs
$(SDBFS)/gensdbfs $< $@
wrpc-dump: wrpc-dump.c
$(CC) -m32 $(CFLAGS) -I../ppsi/include -I../ppsi/arch-wrpc/include \
wrpc-dump: wrpc-dump.c dump-info-host.o
$(CC) $(CFLAGS) -I../ppsi/include -I../ppsi/arch-wrpc/include \
-I ../softpll \
$^ -o $@
dump-info-host.o: ../dump-info.o
$(CROSS_COMPILE)objcopy \
-O binary $^ dump-info-host.bin
$(AS) makebin.S -o $@
../dump-info.o: ../dump-info.c
$(MAKE) -C .. dump-info.o
rm -f $(ALL) *.o *~
* "objcopy -O binary" they say...
* how can I say "spit the default ELF object format"?
.global dump_info
.incbin "dump-info-host.bin"
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment