WTD is a python tool for replacing values with the C preprocessor macro which defined them.

Where's That Define

WTD is a python tool for replacing values with the C preprocessor macro which defined them. An example of this is when trying to understand a driver by dumping every read() and write(), you end up with a big list of values like the following:

[  162.326260] qcom,qpnp-smb2: smblib_read(addr = 0x1307, val=0x01)
[  162.326289] qcom,qpnp-smb2: smblib_read(addr = 0x1308, val=0x08)
[  162.326373] qcom,qpnp-smb2: smblib_read(addr = 0x1307, val=0x01)
[  162.326539] qcom,qpnp-smb2: smblib_read(addr = 0x1070, val=0x79)
[  162.326582] qcom,qpnp-smb2: smblib_read(addr = 0x1061, val=0x4e)
[  162.326623] qcom,qpnp-smb2: smblib_read(addr = 0x1607, val=0x13)
[  162.326666] qcom,qpnp-smb2: smblib_read(addr = 0x1007, val=0x80)
[  162.326702] qcom,qpnp-smb2: smblib_read(addr = 0x1365, val=0xf7)

Wouldn't it be so much better if it could look like this instead?

[ 7291.659328] qcom,qpnp-smb2: smblib_read(addr = APSD_STATUS_REG, val = APSD_DTC_STATUS_DONE_BIT)
[ 7291.659358] qcom,qpnp-smb2: smblib_read(addr = APSD_RESULT_STATUS_REG, val = DCP_CHARGER_BIT|APSD_RESULT_STATUS_MASK=0x8)
[ 7291.659457] qcom,qpnp-smb2: smblib_read(addr = APSD_STATUS_REG, val = APSD_DTC_STATUS_DONE_BIT)
[ 7291.659610] qcom,qpnp-smb2: smblib_read(addr = FLOAT_VOLTAGE_CFG_REG, val = FLOAT_VOLTAGE_SETTING_MASK=0x79)
[ 7291.659652] qcom,qpnp-smb2: smblib_read(addr = FAST_CHARGE_CURRENT_CFG_REG, val = FAST_CHARGE_CURRENT_SETTING_MASK=0x4e)
[ 7291.659694] qcom,qpnp-smb2: smblib_read(addr = ICL_STATUS_REG, val = INPUT_CURRENT_LIMIT_MASK=0x13)
[ 7291.659739] qcom,qpnp-smb2: smblib_read(addr = BATTERY_CHARGER_STATUS_2_REG, val = 0x00)
[ 7291.659776] qcom,qpnp-smb2: smblib_read(addr = USBIN_LOAD_CFG_REG, val = USBIN_OV_CH_LOAD_OPTION_BIT|ICL_OVERRIDE_AFTER_APSD_BIT)
[ 7291.659807] qcom,qpnp-smb2: smblib_read(addr = USBIN_CURRENT_LIMIT_CFG_REG, val = USBIN_CURRENT_LIMIT_MASK=0x3c)
[ 7291.661133] qcom,qpnp-smb2: smblib_read(addr = USB_INT_RT_STS, val = USBIN_PLUGIN_RT_STS_BIT)

Well with the power of WTD and Regex, it can!

Yes that's right, this is a header file parser using regex.

Usage

Before using WTD, some manual processing of #defines is required, WTD can parse macros in the following formats:

// The literal 3735941133 in hex
#define SOME_MACRO 0xdeadf00d
// The literal 1234
#define SOME_MACRO 1234
// Bit 2
#define SOME_MACRO BIT(2)
// Bitmask from bit 2 to bit 0
#define SOME_MACRO GENMASK(2, 0)

The header parser uses context to relate a bunch of bit / mask macros to a particular register, as such the ordering matters. The symbol tree will attribute all BIT() and GENMASK() macros to whatever the last literal value register was. For example:

#define BATTERY_CHARGER_STATUS_5_REG			0x100B
#define VALID_INPUT_POWER_SOURCE_BIT			BIT(7)
#define DISABLE_CHARGING_BIT				BIT(6)
#define FORCE_ZERO_CHARGE_CURRENT_BIT			BIT(5)
#define CHARGING_ENABLE_BIT				BIT(4)
#define TAPER_BIT					BIT(3)
#define ENABLE_CHG_SENSORS_BIT				BIT(2)
#define ENABLE_TAPER_SENSOR_BIT				BIT(1)
#define TAPER_REGION_BIT				BIT(0)

produces the following tree:

BATTERY_CHARGER_STATUS_5_REG: {
    'value': 4107,
    'bits':
    [
        {'name': 'VALID_INPUT_POWER_SOURCE_BIT', 'bit': 7},
        {'name': 'DISABLE_CHARGING_BIT', 'bit': 6},
        {'name': 'FORCE_ZERO_CHARGE_CURRENT_BIT', 'bit': 5},
        {'name': 'CHARGING_ENABLE_BIT', 'bit': 4},
        {'name': 'TAPER_BIT', 'bit': 3},
        {'name': 'ENABLE_CHG_SENSORS_BIT', 'bit': 2},
        {'name': 'ENABLE_TAPER_SENSOR_BIT', 'bit': 1},
        {'name': 'TAPER_REGION_BIT', 'bit': 0}
    ],
    'masks': []}

Some semi-manual preprocessing may be required before using this tool, personally I've found the multi-cursor feature in vscode to be very useful, as well as regex-based find and replace. You could also do this with sed / grep or whatever your preferred method is.

The logfile must log register read/writes in the format

addr = 0x123, val = 0x123

Alternatively hack your format into process_logs().

Owner
Caleb Connolly
they/them | Kernel hacker | consumer of bugs
Caleb Connolly
Similar Resources

A simple Oscilloscope application that reads the values in the serial generated by an Arduino board

A simple Oscilloscope application that reads the values in the serial generated by an Arduino board

Oscilloscope Serial A simple oscilloscope application that reads the values at serial port generated by an Arduino board and based on the value of the

Jun 14, 2022

A header-only C++ library that enables the representation of a range of values in a linear space

Numeric Range A header-only C++ library that enables the representation of a range of values in a linear space (via the NumericRange class). The linea

Mar 22, 2022

Nameof operator for modern C++, simply obtain the name of a variable, type, function, macro, and enum

_ _ __ _____ | \ | | / _| / ____|_ _ | \| | __ _ _ __ ___ ___ ___ | |_ | | _| |

Nov 25, 2022

The littlest Bluetooth macro pad

The littlest wireless macro pad! AWWWWW!!! (c) 2021 Zack Freedman and Voidstar Lab. Licensed CC-BY-NC (credit me and don't sell it) Built partially on

Feb 26, 2022

Macro keypad and rotary input based on the ATmega32U4 Pro Micro board

Macro keypad and rotary input based on the ATmega32U4 Pro Micro board

JC-Pro-Macro Macro keypad and rotary input based on the ATmega32U4 Pro Micro Videos: Development: https://www.youtube.com/watch?v=g-XJLiv03rI Assembly

Oct 26, 2022

Brainf.h - A C macro implementation of a brainf*ck interpreter

brainf.h - A C macro implementation of a brainf*ck interpreter #include stdlib.h #include stdio.h #define BRAINF(c){char*p,*b,*u,*i;p=b=calloc(300

Jan 1, 2022

A C++14 macro to get the type of the current class without naming it

self_macro C++14 header only library that exposes a macro that creates a type alias for the current class without naming it. Also exposes macros that

Nov 23, 2022

Macro magic for declaring/calling Objective-C APIs from C11 or C++. Preloads selectors, chooses the correct objc_msgSend to call per method/platform.

OC - Easily Declare/Invoke Objective-C APIs from C11 or C++11 Usage // Call class and instance methods: NSWindow* const nswindow = oc_cls(NSWindow,new

Sep 9, 2022
Comments
  • convert_val: print raw register value as well

    convert_val: print raw register value as well

    As the tool doesn't currently notice when a bit is set that is not defined in the header, re(?)-add printing the raw hex value of the register.

    Useful for example here (where bit 3 doesn't have a define):

    [    4.507546] aw8695_i2c_read: addr = AW8695_REG_ANADBG, val = AW8695_BIT_ANADBG_IOC_3P65A=0x16
    [    4.512645] aw8695_i2c_write: addr = AW8695_REG_ANADBG, val = AW8695_BIT_ANADBG_IOC_3P65A=0x1e
    
std::tuple like methods for user defined types without any macro or boilerplate code

Boost.PFR This is a C++14 library for very basic reflection that gives you access to structure elements by index and provides other std::tuple like me

Nov 25, 2022
Phasmer: A FastK K-mer phase chaining preprocessor

Phasmer: A FastK K-mer phase chaining preprocessor Author: Haynes Heaton, Richard Durbin, Gene Myers First: April 5, 2021 This is a repository under i

Feb 4, 2022
Keepy is a pseudo-language / HTML preprocessor that translates special syntax into HTML

Keepy is a pseudo-language / HTML preprocessor that translates special syntax into HTML with the peculiarity of being a "compiled pseudo-language". So after using Keepy you can edit the final output HTML file.

Jan 1, 2022
Automatically load dlls into any executables without replacing any files!

Automatically loaded dll using xinput9_1_0 proxy. Please put the modified xinput9_1_0.dll in the executable's directory.

Nov 25, 2022
SKSE plugin for replacing Skyrim SE shaders at launch.

Plugin for SSE Parallax Shader Fix. Requirements CMake Add this to your PATH PowerShell Vcpkg Add the environment variable VCPKG_ROOT with the value a

Aug 12, 2022
Oct 6, 2021
GPS parser which read raw GPS messages, selects only the valid ones and sends them to CAN bus

EagleTRT GPS System for Fenice GPS parser which read raw GPS messages, selects only the valid ones and sends them to CAN bus Compiling GPS Logger gps_

Nov 11, 2021
AssociatedEnum: header-only library for C++ for enumerations with associated values

asenum AssociatedEnum is a header-only library for C++ for enumerations with associated values asenum is C++ implementation of very neat enums from Sw

Oct 30, 2022
A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types and values using Ptrace during program execution.

print-function-args-debugger A refactored Proof-of-concept originally developed in 2017 to print all function calls with their arguments data types an

Jun 17, 2022