From cbb68d2c69de7f5a362c2698936a333e9246082a Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Tue, 27 Apr 2021 14:26:27 +0200 Subject: [PATCH 1/7] Add tools/build/elf_sanity.py This script uses pyelftools to check the elf output file. In this first version it will make sure that the added parameters are not duplicates and does not exceed the max length of 25 characters. This is hard to do in compile-time with macro magic. --- tools/build/elf_sanity.py | 97 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tools/build/elf_sanity.py diff --git a/tools/build/elf_sanity.py b/tools/build/elf_sanity.py new file mode 100644 index 0000000000..67267b10e1 --- /dev/null +++ b/tools/build/elf_sanity.py @@ -0,0 +1,97 @@ +import struct +import sys + +from elftools.elf.elffile import ELFFile + + +PARAM_NAME_MAXLEN = 25 +PARAM_SIZE = 12 +PARAM_GROUP = 0x1 << 7 +PARAM_START = 0x1 + + +def process_file(filename): + with open(filename, 'rb') as f: + check_params(f) + + +def get_offset_of(elf, addr): + for seg in elf.iter_segments(): + if seg.header['p_type'] != 'PT_LOAD': + continue + + # If the symbol is inside the range of a LOADed segment, calculate the + # file offset by subtracting the virtual start address and adding the + # file offset of the loaded section(s) + if addr >= seg['p_vaddr'] and addr < seg['p_vaddr'] + seg['p_filesz']: + return addr - seg['p_vaddr'] + seg['p_offset'] + + return None + + +def get_offset_of_symbol(elf, name): + section = elf.get_section_by_name('.symtab') + sym = section.get_symbol_by_name(name)[0] + if not sym: + print('symbol %s not found' % name, file=sys.stderr) + sys.exit(1) + + return get_offset_of(elf, sym['st_value']) + + +def check_params(stream): + elf = ELFFile(stream) + offset = get_offset_of_symbol(elf, '_param_start') + stop_offset = get_offset_of_symbol(elf, '_param_stop') + + parameters = {} + + while offset < stop_offset: + elf.stream.seek(offset) + # + # Parsing a parameter, first unpack the param_s struct: + # struct param_s { + # uint8_t type; + # char * name; + # void * address; + # }; + # + # We want the type and the name. + # + buffer = elf.stream.read(PARAM_SIZE) + t, addr = struct.unpack('@Bxxxixxxx', buffer) + # + # Next, convert address of name to offset in elf + # + addr = get_offset_of(elf, addr) + # + # And read the name from that offset + # + elf.stream.seek(addr) + name = ''.join(iter(lambda: stream.read(1).decode('ascii'), '\x00')) + # + # Check if this is start of a group + # + if t & PARAM_GROUP != 0 and t & PARAM_START != 0: + current_group = name + elif t & PARAM_GROUP == 0: + name = '%s.%s' % (current_group, name) + if name in parameters: + print('duplicate parameter detected: %s' % name) + sys.exit(1) + else: + parameters[name] = name + + if len(name) > PARAM_NAME_MAXLEN: + print('name of param to long (%s > %d)' % + (name, PARAM_NAME_MAXLEN)) + sys.exit(1) + + offset += PARAM_SIZE + + +if __name__ == '__main__': + if len(sys.argv) > 1: + process_file(sys.argv[1]) + else: + sys.exit(1) From 93991923d856341b10ca8a5182628c96896641e8 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Thu, 29 Apr 2021 08:05:06 +0200 Subject: [PATCH 2/7] elf_sanity.py: Add --list-params This will list parameters with type, in alpabetical order. ``` $ python3 tools/build/elf_sanity.py --list-params cf2.elf activeMarker.back PARAM_UINT8 activeMarker.front PARAM_UINT8 activeMarker.left PARAM_UINT8 activeMarker.mode PARAM_UINT8 activeMarker.poll PARAM_UINT8 activeMarker.right PARAM_UINT8 cmdrCPPM.angPitch PARAM_FLOAT cmdrCPPM.angRoll PARAM_FLOAT cmdrCPPM.ratePitch PARAM_FLOAT cmdrCPPM.rateRoll PARAM_FLOAT cmdrCPPM.rateYaw PARAM_FLOAT colAv.bboxMaxX PARAM_FLOAT colAv.bboxMaxY PARAM_FLOAT colAv.bboxMaxZ PARAM_FLOAT colAv.bboxMinX PARAM_FLOAT colAv.bboxMinY PARAM_FLOAT colAv.bboxMinZ PARAM_FLOAT colAv.ellipsoidX PARAM_FLOAT colAv.ellipsoidY PARAM_FLOAT colAv.ellipsoidZ PARAM_FLOAT colAv.enable PARAM_UINT8 colAv.horizon PARAM_FLOAT colAv.maxPeerLocAge PARAM_INT32 colAv.maxSpeed PARAM_FLOAT colAv.sidestepThrsh PARAM_FLOAT colAv.vorIters PARAM_INT32 colAv.vorTol PARAM_FLOAT commander.enHighLevel PARAM_UINT8 controller.tiltComp PARAM_UINT8 cpu.flash PARAM_UIN16 | PARAM_RONLY cpu.id0 PARAM_UINT32 | PARAM_RONLY cpu.id1 PARAM_UINT32 | PARAM_RONLY cpu.id2 PARAM_UINT32 | PARAM_RONLY crtpsrv.echoDelay PARAM_UIN16 ctrlINDI.act_dyn_p PARAM_FLOAT ctrlINDI.act_dyn_q PARAM_FLOAT ctrlINDI.act_dyn_r PARAM_FLOAT ctrlINDI.bound_ctrl_input PARAM_FLOAT ctrlINDI.filt_cutoff PARAM_FLOAT ctrlINDI.filt_cutoff_r PARAM_FLOAT ctrlINDI.g1_p PARAM_FLOAT ctrlINDI.g1_q PARAM_FLOAT ctrlINDI.g1_r PARAM_FLOAT ctrlINDI.g2 PARAM_FLOAT ctrlINDI.outerLoopActive PARAM_UINT8 ctrlINDI.pitch_kp PARAM_FLOAT ctrlINDI.ref_err_p PARAM_FLOAT ctrlINDI.ref_err_q PARAM_FLOAT ctrlINDI.ref_err_r PARAM_FLOAT ctrlINDI.ref_rate_p PARAM_FLOAT ctrlINDI.ref_rate_q PARAM_FLOAT ctrlINDI.ref_rate_r PARAM_FLOAT ctrlINDI.roll_kp PARAM_FLOAT ctrlINDI.thrust_threshold PARAM_FLOAT ctrlINDI.yaw_kp PARAM_FLOAT ctrlMel.i_range_m_xy PARAM_FLOAT ctrlMel.i_range_m_z PARAM_FLOAT ctrlMel.i_range_xy PARAM_FLOAT ctrlMel.i_range_z PARAM_FLOAT ctrlMel.kR_xy PARAM_FLOAT ctrlMel.kR_z PARAM_FLOAT ctrlMel.kd_omega_rp PARAM_FLOAT ctrlMel.kd_xy PARAM_FLOAT ctrlMel.kd_z PARAM_FLOAT ctrlMel.ki_m_xy PARAM_FLOAT ctrlMel.ki_m_z PARAM_FLOAT ctrlMel.ki_xy PARAM_FLOAT ctrlMel.ki_z PARAM_FLOAT ctrlMel.kp_xy PARAM_FLOAT ctrlMel.kp_z PARAM_FLOAT ctrlMel.kw_xy PARAM_FLOAT ctrlMel.kw_z PARAM_FLOAT ctrlMel.mass PARAM_FLOAT ctrlMel.massThrust PARAM_FLOAT deck.bcAIDeck PARAM_UINT8 | PARAM_RONLY deck.bcBuzzer PARAM_UINT8 | PARAM_RONLY deck.bcCPPM PARAM_UINT8 | PARAM_RONLY deck.bcDWM1000 PARAM_UINT8 | PARAM_RONLY deck.bcFlow PARAM_UINT8 | PARAM_RONLY deck.bcFlow2 PARAM_UINT8 | PARAM_RONLY deck.bcGTGPS PARAM_UINT8 | PARAM_RONLY deck.bcLedRing PARAM_UINT8 | PARAM_RONLY deck.bcLighthouse4 PARAM_UINT8 | PARAM_RONLY deck.bcMultiranger PARAM_UINT8 | PARAM_RONLY deck.bcOA PARAM_UINT8 | PARAM_RONLY deck.bcUSD PARAM_UINT8 | PARAM_RONLY deck.bcZRanger PARAM_UINT8 | PARAM_RONLY deck.bcZRanger2 PARAM_UINT8 | PARAM_RONLY firmware.modified PARAM_UINT8 | PARAM_RONLY firmware.revision0 PARAM_UINT32 | PARAM_RONLY firmware.revision1 PARAM_UIN16 | PARAM_RONLY flightmode.althold PARAM_UINT8 flightmode.posSet PARAM_UINT8 flightmode.poshold PARAM_UINT8 flightmode.stabModePitch PARAM_UINT8 flightmode.stabModeRoll PARAM_UINT8 flightmode.stabModeYaw PARAM_UINT8 flightmode.yawMode PARAM_UINT8 flightmode.yawRst PARAM_UINT8 health.startBatTest PARAM_UINT8 health.startPropTest PARAM_UINT8 hlCommander.vland PARAM_FLOAT hlCommander.vtoff PARAM_FLOAT imu_sensors.BMP388 PARAM_UINT8 | PARAM_RONLY imu_sensors.HMC5883L PARAM_UINT8 | PARAM_RONLY imu_sensors.MS5611 PARAM_UINT8 | PARAM_RONLY imu_tests.HMC5883L PARAM_UINT8 | PARAM_RONLY imu_tests.MPU6500 PARAM_UINT8 | PARAM_RONLY imu_tests.MS5611 PARAM_UINT8 | PARAM_RONLY kalman.initialX PARAM_FLOAT kalman.initialY PARAM_FLOAT kalman.initialYaw PARAM_FLOAT kalman.initialZ PARAM_FLOAT kalman.mNBaro PARAM_FLOAT kalman.mNGyro_rollpitch PARAM_FLOAT kalman.mNGyro_yaw PARAM_FLOAT kalman.maxPos PARAM_FLOAT kalman.maxVel PARAM_FLOAT kalman.pNAcc_xy PARAM_FLOAT kalman.pNAcc_z PARAM_FLOAT kalman.pNAtt PARAM_FLOAT kalman.pNPos PARAM_FLOAT kalman.pNVel PARAM_FLOAT kalman.quadIsFlying PARAM_UINT8 kalman.resetEstimation PARAM_UINT8 kalman.robustTdoa PARAM_UINT8 kalman.robustTwr PARAM_UINT8 lighthouse.bsCalibReset PARAM_UINT8 lighthouse.method PARAM_UINT8 lighthouse.sweepStd PARAM_FLOAT lighthouse.sweepStd2 PARAM_FLOAT lighthouse.systemType PARAM_UINT8 locSrv.enLhAngleStream PARAM_UINT8 locSrv.enRangeStreamFP32 PARAM_UINT8 locSrv.extPosStdDev PARAM_FLOAT locSrv.extQuatStdDev PARAM_FLOAT loco.mode PARAM_UINT8 memTst.resetW PARAM_UINT8 motion.adaptive PARAM_UINT8 motion.disable PARAM_UINT8 motion.flowStdFixed PARAM_FLOAT motorPowerSet.enable PARAM_UINT8 motorPowerSet.m1 PARAM_UIN16 motorPowerSet.m2 PARAM_UIN16 motorPowerSet.m3 PARAM_UIN16 motorPowerSet.m4 PARAM_UIN16 pid_attitude.pitch_kd PARAM_FLOAT pid_attitude.pitch_ki PARAM_FLOAT pid_attitude.pitch_kp PARAM_FLOAT pid_attitude.roll_kd PARAM_FLOAT pid_attitude.roll_ki PARAM_FLOAT pid_attitude.roll_kp PARAM_FLOAT pid_attitude.yaw_kd PARAM_FLOAT pid_attitude.yaw_ki PARAM_FLOAT pid_attitude.yaw_kp PARAM_FLOAT pid_rate.pitch_kd PARAM_FLOAT pid_rate.pitch_ki PARAM_FLOAT pid_rate.pitch_kp PARAM_FLOAT pid_rate.roll_kd PARAM_FLOAT pid_rate.roll_ki PARAM_FLOAT pid_rate.roll_kp PARAM_FLOAT pid_rate.yaw_kd PARAM_FLOAT pid_rate.yaw_ki PARAM_FLOAT pid_rate.yaw_kp PARAM_FLOAT posCtlPid.rpLimit PARAM_FLOAT posCtlPid.thrustBase PARAM_UIN16 posCtlPid.thrustMin PARAM_UIN16 posCtlPid.xKd PARAM_FLOAT posCtlPid.xKi PARAM_FLOAT posCtlPid.xKp PARAM_FLOAT posCtlPid.xyVelMax PARAM_FLOAT posCtlPid.yKd PARAM_FLOAT posCtlPid.yKi PARAM_FLOAT posCtlPid.yKp PARAM_FLOAT posCtlPid.zKd PARAM_FLOAT posCtlPid.zKi PARAM_FLOAT posCtlPid.zKp PARAM_FLOAT posCtlPid.zVelMax PARAM_FLOAT posCtrlIndi.K_dxi_x PARAM_FLOAT posCtrlIndi.K_dxi_y PARAM_FLOAT posCtrlIndi.K_dxi_z PARAM_FLOAT posCtrlIndi.K_xi_x PARAM_FLOAT posCtrlIndi.K_xi_y PARAM_FLOAT posCtrlIndi.K_xi_z PARAM_FLOAT posEstAlt.estAlphaAsl PARAM_FLOAT posEstAlt.estAlphaZr PARAM_FLOAT posEstAlt.vAccDeadband PARAM_FLOAT posEstAlt.velFactor PARAM_FLOAT posEstAlt.velZAlpha PARAM_FLOAT powerDist.idleThrust PARAM_UINT32 ring.effect PARAM_UINT8 ring.emptyCharge PARAM_FLOAT ring.fadeColor PARAM_UINT32 ring.fadeTime PARAM_FLOAT ring.fullCharge PARAM_FLOAT ring.glowstep PARAM_FLOAT ring.headlightEnable PARAM_UINT8 ring.neffect PARAM_UINT32 | PARAM_RONLY ring.solidBlue PARAM_UINT8 ring.solidGreen PARAM_UINT8 ring.solidRed PARAM_UINT8 sensfusion6.baseZacc PARAM_FLOAT sensfusion6.ki PARAM_FLOAT sensfusion6.kp PARAM_FLOAT sound.effect PARAM_UINT8 sound.freq PARAM_UIN16 sound.neffect PARAM_UINT32 | PARAM_RONLY sound.ratio PARAM_UINT8 stabilizer.controller PARAM_UINT8 stabilizer.estimator PARAM_UINT8 stabilizer.stop PARAM_UINT8 system.forceArm PARAM_INT8 system.highlight PARAM_UINT8 system.selftestPassed PARAM_INT8 | PARAM_RONLY system.taskDump PARAM_UINT8 tdoaEngine.logId PARAM_UINT8 tdoaEngine.logOthrId PARAM_UINT8 tdoaEngine.matchAlgo PARAM_UINT8 usd.canLog PARAM_UINT8 | PARAM_RONLY usd.logging PARAM_UINT8 velCtlPid.vxKd PARAM_FLOAT velCtlPid.vxKi PARAM_FLOAT velCtlPid.vxKp PARAM_FLOAT velCtlPid.vyKd PARAM_FLOAT velCtlPid.vyKi PARAM_FLOAT velCtlPid.vyKp PARAM_FLOAT velCtlPid.vzKd PARAM_FLOAT velCtlPid.vzKi PARAM_FLOAT velCtlPid.vzKp PARAM_FLOAT ``` --- tools/build/elf_sanity.py | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/tools/build/elf_sanity.py b/tools/build/elf_sanity.py index 67267b10e1..e5fa1b65cc 100644 --- a/tools/build/elf_sanity.py +++ b/tools/build/elf_sanity.py @@ -1,3 +1,4 @@ +import argparse import struct import sys @@ -9,6 +10,27 @@ PARAM_GROUP = 0x1 << 7 PARAM_START = 0x1 +parameters = {} + + +param_type_to_str_dict = { + 0x0 | 0x0 << 2 | 0x1 << 3: 'PARAM_UINT8', + 0x0 | 0x0 << 2 | 0x0 << 3: 'PARAM_INT8', + 0x1 | 0x0 << 2 | 0x1 << 3: 'PARAM_UIN16', + 0x1 | 0x0 << 2 | 0x0 << 3: 'PARAM_INT16', + 0x2 | 0x0 << 2 | 0x1 << 3: 'PARAM_UINT32', + 0x2 | 0x0 << 2 | 0x0 << 3: 'PARAM_INT32', + 0x2 | 0x1 << 2 | 0x0 << 3: 'PARAM_FLOAT' +} + + +def param_type_to_str(t: int) -> str: + read_only = str() + if t & (1 << 6): # PARAM_RONLY set + read_only = ' | PARAM_RONLY' + + return '{:12}{}'.format(param_type_to_str_dict[t & ~(1 << 6)], read_only) + def process_file(filename): with open(filename, 'rb') as f: @@ -44,8 +66,6 @@ def check_params(stream): offset = get_offset_of_symbol(elf, '_param_start') stop_offset = get_offset_of_symbol(elf, '_param_stop') - parameters = {} - while offset < stop_offset: elf.stream.seek(offset) # @@ -80,7 +100,7 @@ def check_params(stream): print('duplicate parameter detected: %s' % name) sys.exit(1) else: - parameters[name] = name + parameters[name] = t if len(name) > PARAM_NAME_MAXLEN: print('name of param to long (%s > %d)' % @@ -91,7 +111,14 @@ def check_params(stream): if __name__ == '__main__': - if len(sys.argv) > 1: - process_file(sys.argv[1]) + parser = argparse.ArgumentParser() + parser.add_argument('--list-params', action='store_true') + parser.add_argument('filename', nargs=argparse.REMAINDER) + args = parser.parse_args() + + if args.filename: + process_file(args.filename[0]) + for key in sorted(parameters.keys()): + print('{:25}\t{}'.format(key, param_type_to_str(parameters[key]))) else: sys.exit(1) From 41b5b6b5f13955b72e4725eeb3c4c95f85a5415a Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Fri, 30 Apr 2021 05:42:38 +0200 Subject: [PATCH 3/7] elf_sanity.py: Add support for --list-logs --- tools/build/elf_sanity.py | 81 ++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/tools/build/elf_sanity.py b/tools/build/elf_sanity.py index e5fa1b65cc..3c7c12c68d 100644 --- a/tools/build/elf_sanity.py +++ b/tools/build/elf_sanity.py @@ -5,14 +5,6 @@ from elftools.elf.elffile import ELFFile -PARAM_NAME_MAXLEN = 25 -PARAM_SIZE = 12 -PARAM_GROUP = 0x1 << 7 -PARAM_START = 0x1 - -parameters = {} - - param_type_to_str_dict = { 0x0 | 0x0 << 2 | 0x1 << 3: 'PARAM_UINT8', 0x0 | 0x0 << 2 | 0x0 << 3: 'PARAM_INT8', @@ -32,9 +24,39 @@ def param_type_to_str(t: int) -> str: return '{:12}{}'.format(param_type_to_str_dict[t & ~(1 << 6)], read_only) -def process_file(filename): +log_type_to_str_dict = { + 0x1: 'LOG_UINT8', + 0x2: 'LOG_INT8', + 0x3: 'LOG_UIN16', + 0x4: 'LOG_INT16', + 0x5: 'LOG_UINT32', + 0x6: 'LOG_INT32', + 0x7: 'LOG_FLOAT', + 0x8: 'LOG_FP16' +} + + +def log_type_to_str(t: int) -> str: + by_function = str() + if t & (1 << 6): # BY_FUNCTION set + by_function = ' | BY_FUNCTION' + + return '{:12}{}'.format(log_type_to_str_dict[t & ~(1 << 6)], by_function) + + +def process_file(filename, list_params: bool, list_logs: bool): with open(filename, 'rb') as f: - check_params(f) + parameters = check_structs(f, 'param') + if list_params: + for key in sorted(parameters.keys()): + t = parameters[key] + print('{:25}\t{}'.format(key, param_type_to_str(t))) + + logs = check_structs(f, 'log') + if list_logs: + for key in sorted(logs.keys()): + t = logs[key] + print('{:25}\t{}'.format(key, log_type_to_str(t))) def get_offset_of(elf, addr): @@ -61,16 +83,22 @@ def get_offset_of_symbol(elf, name): return get_offset_of(elf, sym['st_value']) -def check_params(stream): +def check_structs(stream, what: str) -> dict: elf = ELFFile(stream) - offset = get_offset_of_symbol(elf, '_param_start') - stop_offset = get_offset_of_symbol(elf, '_param_stop') + offset = get_offset_of_symbol(elf, '_{}_start'.format(what)) + stop_offset = get_offset_of_symbol(elf, '_{}_stop'.format(what)) + + name_type_dict = {} + name_maxlen = 25 + struct_len = 12 + group_bit = 0x1 << 7 + start_bit = 0x1 while offset < stop_offset: elf.stream.seek(offset) # - # Parsing a parameter, first unpack the param_s struct: - # struct param_s { + # Parsing log or param, first unpack the struct: + # struct [param_s|log_s] { # uint8_t type; # char * name; # void * address; @@ -78,7 +106,7 @@ def check_params(stream): # # We want the type and the name. # - buffer = elf.stream.read(PARAM_SIZE) + buffer = elf.stream.read(struct_len) t, addr = struct.unpack('@Bxxxixxxx', buffer) # # Next, convert address of name to offset in elf @@ -92,33 +120,32 @@ def check_params(stream): # # Check if this is start of a group # - if t & PARAM_GROUP != 0 and t & PARAM_START != 0: + if t & group_bit != 0 and t & start_bit != 0: current_group = name - elif t & PARAM_GROUP == 0: + elif t & group_bit == 0: name = '%s.%s' % (current_group, name) - if name in parameters: + if name in name_type_dict: print('duplicate parameter detected: %s' % name) sys.exit(1) else: - parameters[name] = t + name_type_dict[name] = t - if len(name) > PARAM_NAME_MAXLEN: - print('name of param to long (%s > %d)' % - (name, PARAM_NAME_MAXLEN)) + if len(name) > name_maxlen: + print('name too long (%s > %d)' % (name, name_maxlen)) sys.exit(1) - offset += PARAM_SIZE + offset += struct_len + return name_type_dict if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--list-params', action='store_true') + parser.add_argument('--list-logs', action='store_true') parser.add_argument('filename', nargs=argparse.REMAINDER) args = parser.parse_args() if args.filename: - process_file(args.filename[0]) - for key in sorted(parameters.keys()): - print('{:25}\t{}'.format(key, param_type_to_str(parameters[key]))) + process_file(args.filename[0], args.list_params, args.list_logs) else: sys.exit(1) From d809a7762749e38cefe6abc07934f6734c360cc0 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Fri, 30 Apr 2021 06:05:40 +0200 Subject: [PATCH 4/7] Add check_elf script to tools/build/build --- tools/build/build | 1 + tools/build/check_elf | 5 +++++ tools/build/elf_sanity.py | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100755 tools/build/check_elf diff --git a/tools/build/build b/tools/build/build index fb3ecf2b31..452bd88d8c 100755 --- a/tools/build/build +++ b/tools/build/build @@ -5,3 +5,4 @@ scriptDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) ${scriptDir}/test "${@}" ${scriptDir}/make "${@}" +${scriptDir}/check_elf diff --git a/tools/build/check_elf b/tools/build/check_elf new file mode 100755 index 0000000000..d9c2210c18 --- /dev/null +++ b/tools/build/check_elf @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e + +scriptDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +python3 ${scriptDir}/elf_sanity.py ${scriptDir}/../../cf2.elf diff --git a/tools/build/elf_sanity.py b/tools/build/elf_sanity.py index 3c7c12c68d..76813b5378 100644 --- a/tools/build/elf_sanity.py +++ b/tools/build/elf_sanity.py @@ -2,7 +2,18 @@ import struct import sys -from elftools.elf.elffile import ELFFile +try: + from elftools.elf.elffile import ELFFile +except ImportError: + print('pytelftools missing, install to run this script', file=sys.stderr) + print('https://github.com/eliben/pyelftools#installing', file=sys.stderr) + sys.exit(1) + + +class Colors: + BLUE = '\033[94m' + GREEN = '\033[92m' + END = '\033[0m' param_type_to_str_dict = { @@ -58,6 +69,10 @@ def process_file(filename, list_params: bool, list_logs: bool): t = logs[key] print('{:25}\t{}'.format(key, log_type_to_str(t))) + n_logs = Colors.GREEN + str(len(logs.keys())) + Colors.END + n_params = Colors.BLUE + str(len(parameters.keys())) + Colors.END + print('{} parameters and {} log vars in elf'.format(n_params, n_logs)) + def get_offset_of(elf, addr): for seg in elf.iter_segments(): From b1e8a390aa5675429d7e9d2245b99271f5a4edc6 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Fri, 30 Apr 2021 06:16:16 +0200 Subject: [PATCH 5/7] elf_sanity.py: Make failure message stand out --- tools/build/elf_sanity.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/build/elf_sanity.py b/tools/build/elf_sanity.py index 76813b5378..9faeaf3252 100644 --- a/tools/build/elf_sanity.py +++ b/tools/build/elf_sanity.py @@ -11,6 +11,7 @@ class Colors: + RED = '\033[91m' BLUE = '\033[94m' GREEN = '\033[92m' END = '\033[0m' @@ -140,13 +141,15 @@ def check_structs(stream, what: str) -> dict: elif t & group_bit == 0: name = '%s.%s' % (current_group, name) if name in name_type_dict: - print('duplicate parameter detected: %s' % name) + print('%sDuplicate parameter detected!%s (%s)' % + (Colors.RED, Colors.END, name)) sys.exit(1) else: name_type_dict[name] = t if len(name) > name_maxlen: - print('name too long (%s > %d)' % (name, name_maxlen)) + print('%sName too long!%s (%s > %d)' % + (Colors.RED, Colors.END, name, name_maxlen)) sys.exit(1) offset += struct_len From 3a365f195ca9620cd9aecf81253c75bbce6df861 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Fri, 30 Apr 2021 06:20:00 +0200 Subject: [PATCH 6/7] elf_sanity.py: Write error messages to stderr --- tools/build/elf_sanity.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/build/elf_sanity.py b/tools/build/elf_sanity.py index 9faeaf3252..b46e8be2fa 100644 --- a/tools/build/elf_sanity.py +++ b/tools/build/elf_sanity.py @@ -142,14 +142,15 @@ def check_structs(stream, what: str) -> dict: name = '%s.%s' % (current_group, name) if name in name_type_dict: print('%sDuplicate parameter detected!%s (%s)' % - (Colors.RED, Colors.END, name)) + (Colors.RED, Colors.END, name), file=sys.stderr) sys.exit(1) else: name_type_dict[name] = t if len(name) > name_maxlen: print('%sName too long!%s (%s > %d)' % - (Colors.RED, Colors.END, name, name_maxlen)) + (Colors.RED, Colors.END, name, name_maxlen), + file=sys.stderr) sys.exit(1) offset += struct_len From a12b031d5350163645831b15015d8b4496c6c013 Mon Sep 17 00:00:00 2001 From: Jonas Danielsson Date: Fri, 30 Apr 2021 09:02:03 +0200 Subject: [PATCH 7/7] check_elf: Handle tag as well --- tools/build/check_elf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build/check_elf b/tools/build/check_elf index d9c2210c18..b89317fd2d 100755 --- a/tools/build/check_elf +++ b/tools/build/check_elf @@ -2,4 +2,4 @@ set -e scriptDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -python3 ${scriptDir}/elf_sanity.py ${scriptDir}/../../cf2.elf +python3 ${scriptDir}/elf_sanity.py ${scriptDir}/../../*.elf