Tockloader Bug Investigation Init Fn Size And Protected Size Discrepancies

by ADMIN 75 views
Iklan Headers

Hey guys! Ever stumbled upon a tech puzzle that just makes you scratch your head? Well, I’ve got one for you today! We're diving deep into the world of TockOS, specifically the Tockloader, and uncovering some intriguing differences between the Python and Rust versions when it comes to reading TBF (Tock Binary Format) headers. It's like comparing notes from two different students and finding some subtle, yet significant, variations. So, buckle up, and let’s get our geek on!

The Mystery: Differing Outputs in Init Fn Size and Protected Size

Our main focus today is on a peculiar issue observed when using tockloader info. This command, a handy tool for inspecting Tock applications, reveals a discrepancy in the output between the Python version (tockloader.py) and the Rust version (tockloader-rs). The variances pop up in the TLV (Type-Length-Value) headers, particularly in the init_fn_size and protected_size fields. It's like spotting a typo in a critical document – it might not break everything, but it definitely raises an eyebrow. To really get our hands dirty, I’ve compiled the latest libtock-c with the c-hello example. This gives us a consistent test case to compare the outputs.

Diving into the Python Output

Let’s kick things off by examining what the Python version spits out. When we run python3 -m tockloader.main info, we get a detailed breakdown of the application. The output includes crucial information like the application name, version, and size. But the interesting bits for our case are within the TLV headers. Specifically, the Python output shows the init_fn_offset as 41 (0x29) and the protected_size as 0. This is important. Remember these numbers, guys, because they’re about to get a twist.

(.venv) localhost ~/Work/tockloader $ python3 -m tockloader.main info
[INFO   ] Using openocd channel to communicate with the board.
[INFO   ] Using settings from KNOWN_BOARDS["microbit_v2"]
tockloader version: 1.15.0.dev1
[STATUS ] Showing all properties of the board...
Apps:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ App 0                                            |
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  Name:                  c_hello
  Version:               0
  Enabled:               True
  Sticky:                False
  Total Size in Flash:   4096 bytes
  Address in Flash:      0x40000
    TBF version           : 2                       [0x0  ] [0x40000  ]
    header_size           :         76         0x4c
    total_size            :       4096       0x1000
    checksum              :              0x65502739
    flags                 :          1          0x1
      enabled             : Yes
      sticky              : No
    TLV: Main (1)                                   [0x10 ] [0x40010  ]
      init_fn_offset      :         41         0x29
      protected_size      :          0          0x0
      minimum_ram_size    :       4580       0x11e4
    TLV: Program (9)                                [0x20 ] [0x40020  ]
      init_fn_offset      :         41         0x29
      protected_size      :          0          0x0
      minimum_ram_size:       4580       0x11e4
      binary_end_offset   :       1076        0x434
      app_version         :          0          0x0
    TLV: Package Name (3)                           [0x38 ] [0x40038  ]
      package_name        : c_hello
    TLV: Kernel Version (8)                         [0x44 ] [0x40044  ]
      kernel_major        : 2
      kernel_minor        : 0
      kernel version      : ^2.0

    Footer
      footer_size         :       3020        0xbcc
    Footer TLV: Credentials (128)                   [0x0  ] [0x40434  ]
      Type: Reserved (0)
      Length: 3012


Attributes:
Bootloader version: v1.1.1
Kernel Attributes                               [0x0  ] [0x40000  ]
  sentinel            : TOCK                    [-0x4 ] [0x3fffc  ]
  version             : 1                       [-0x8 ] [0x3fff8  ]
KATLV: App Memory (0x101)                       [-0x14] [0x3ffec  ]
  app_memory_start    :  536893380   0x200057c4
  app_memory_len      :     108604      0x1a83c
KATLV: Kernel Binary (0x102)                    [-0x20] [0x3ffe0  ]
  kernel_binary_start :      32768       0x8000
  kernel_binary_len   :  536846336   0x1fffa000

The Rust Version's Perspective

Now, let’s switch gears and peek at the output from the Rust version. Running cargo run -- info --board microbit-v2 gives us a similar, yet distinctly different, view. The Rust version reports the init_fn_offset as 117 and the protected_size as 76. Woah! That’s quite a jump from the Python version’s 41 and 0, isn't it? This difference is the heart of our puzzle. It suggests that the two versions are interpreting the TBF headers in a slightly different way. It's like reading the same map but ending up at slightly different locations.

(.venv) localhost ~/Work/tockloader-rs $ cargo run -- info --board microbit-v2
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
     Running `target/debug/tockloader info --board microbit-v2`
> Which debug probe do you want to use? "BBC micro:bit CMSIS-DAP" -- 0d28:0204:9904360259004e45005e300300000027000000009796990b (CMSIS-DAP)

 ┏━━━━━━━━━━━━━━━━┓
 ┃  App_0         ┃
 ┗━━━━━━━━━━━━━━━━┛

  Name:                c_hello
  Version:             0
  Enabled:             true
  Stricky:             false
  Total_Size:          4096
  Address in Flash:  262144
     TBF version:    0
     header_size:    76
     total_size:     4096
     checksum:       1699751737
     flags:
         enabled:        true
         sticky:         false
     TVL: Main (1)
         init_fn_offset:             117
         protected_size:             76
         minimum_ram_size:           4580
     TVL: Program (9)
         init_fn_offset:             117
         protected_size:             76
         minimum_ram_size:           4580
         binary_end_offset:          1076
         app_version:                0
     TVL: Package Name (3)
         package_name:               c_hello
     TVL: Kernel Version (8)
         kernel_major:               2
         kernel_minor:               0

     Footer
             footer_size:            3020
     Footer [0] TVL: Credentials
         Type:                       Reserved
         Length:                     3012


 Kernel Attributes
     Sentinel:               TOCK      
     Version:                1         
 KATLV: APP Memory
     app_memory_start:       536893380 
     app_memory_len:         108604    
 KATLV: Kernel Binary
     kernel_binary_start:    32768     
     kernel_binary_len:      536846336 

Potential Culprits: Where Could the Bug Be Hiding?

So, where do we even start looking for the cause of this discrepancy? Well, one potential suspect is the tbf-parser library. There's a mention of a past encounter with similar issues, specifically in #29. It might be worth revisiting that to see if there's a connection. The other possibility is that the issue lies in how we read the TBF headers within the lib of each version. It’s like having two different translators for the same language – they might interpret some nuances differently. It’s also crucial to ensure that the TBF format is being parsed correctly. This format dictates how the application metadata is structured, and any misinterpretation here could lead to incorrect values for fields like init_fn_offset and protected_size.

The Role of TBF Parser Library

The TBF parser library is crucial in interpreting the binary format of Tock applications. If this library has a bug, it could lead to misreading the init_fn_size and protected_size fields. Checking past issues, like #29, might reveal similar problems or fixes that could apply here. It’s like detective work, where past cases can give us clues to solve the current mystery.

Reading TBF Headers in Lib

Another place where the issue might be hiding is in the logic for reading TBF headers within each version of Tockloader. The Python and Rust versions might have slight differences in how they interpret the header structure, leading to the observed discrepancies. This is where a careful comparison of the code in both versions is essential. It's like comparing the recipes of two chefs – they might use the same ingredients but end up with slightly different dishes.

Time to Roll Up Our Sleeves: Replicating the Bug and Finding a Fix

Now comes the fun part – the investigation! The first step is to replicate the bug. Can you, guys, reproduce the same output differences on your end? If we can confirm that this isn’t just a one-off issue, we know we’re on the right track. Once we’ve got a solid reproduction, it’s time to dive into the code and start hunting for the root cause. This might involve stepping through the parsing logic, comparing the Python and Rust implementations, and maybe even dusting off our TBF format specification knowledge.

Verifying the Bug

To effectively tackle this issue, we need to ensure that it can be consistently reproduced across different environments. Replicating the bug is a critical step in confirming its existence and understanding its scope. This involves running the same commands (tockloader info in both Python and Rust) on the same application binary and verifying that the output discrepancies persist.

Sending a PR

If you, guys, think you’ve spotted the culprit and have a fix in mind, don’t hesitate to send a PR (Pull Request)! This is how open-source projects thrive – through collaboration and community contributions. A well-documented PR, explaining the issue, the fix, and how it was tested, is gold. It's like sharing your secret recipe with the world, but for code!

Let's Get to the Bottom of This!

So, there you have it – a tech mystery wrapped in a TBF header. The differing init_fn_size and protected_size fields between the Python and Rust versions of Tockloader are definitely intriguing. It’s a challenge that calls for some careful investigation, a bit of code sleuthing, and maybe a dash of community collaboration. If you are familiar with embedded systems, TockOS, and binary formats, your expertise can significantly contribute to solving this issue. Remember, every bug squashed makes the software world a little bit better. Let’s dive in and see what we can uncover, guys!