Linux and mac compatibility#1029
Conversation
…one is not enough to make sure symbols are actually exported on mac
…either avoid it by prefixing with or strip this prefix explicitly
… on linux and mac, to offset addresses accordingly, since the linker script won't work on them (there's probably a more normal way to do this only once)
…s-calculations Return to no-std, use linker symbols to calculate the base address
remove two deps from defmt/Cargo.toml
On macOS, each defmt log statement created a unique section in the .defmt segment. With 200+ logs, this exceeded Mach-O's 255 section limit. Fix: Group logs by severity level instead of unique hash per log.
fix(macos): avoid 255 section-per-segment limit
…y type, instead of the decoding os
Linux and mac compatibility issue fixes
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…ather than the decoding host
Linux and mac compatibility fixes, part 2
… LLVM behavior so I would prefer it for now
This reverts commit 57acf1b.
This reverts commit ba1f9ae.
Linux and mac compatibility fixes3
|
Nice - I'm excited to look through this in detail soon. |
…bol by its export name, make it macos-only
|
I had a trial run with this, but How have you been testing it? |
|
I tested this on Linux and it works well 🥳 Although I still needed to have a custom linker file that collects all interned strings into a single section: Ideally the elf parser could deal with it without the linker file, because the symbols are in the elf file when I print them out. Alternatively modify the provided |
|
I think the best solution is to only put items into the |
I just used the decoder directly, but let me go ahead and change this - added a commit to support Mach-O files in |
|
@knoellle is going to take a look at this one, right after his Robocup competition. |
|
Thank you for your work so far. What is your plan with the linker scripts? As @tomasbarton-stemcell mentioned already, I think we should either include linker scripts for Linux/Mac or adjust the elf parser to work without linker scripts. |
|
Thanks for the PR! As mentioned in the PR description, the location information currently does not work for macOS. |
Mac doesn't have linker scripts, and like @mhatzl said it should work without the need for one. It does mean that things like the default panic handler that's auto-configured by |
The issue is that by default mac location information is scattered across files, and the table parsing doesn't handle this well. Running without split debug info ( |
|
Hi @aimir, looking at the docs for split-debuginfo and the cargo profile docs, the default for macOS is Since the |
I spent some time attempted making the default panic stuff work without linker scripts but didn't find a way without breaking user code. See #1050. Again, I don't have a mac to test with, but if I understand correctly then attempting to use What are your thoughts on requiring a custom panic handler for building for macOS specifically? |
|
I'm curious how you tested the linux compatibility. For embedded platforms, we use flip-link which does a bunch of magic to find linker scripts inside library search paths which other linkers don't do.
How do you build your linux binaries? |
Fix macos dsym mapping
|
@lakechurch suggested a fix for the symbol table collection that seems to work well - thanks!! @mhatzl can you take a look now? |
|
@knoellle what I ended up doing is using |
CI (knurling-rs#1029) failed across the whole host matrix with three small issues introduced by the macOS dSYM mapping work: - print/src/main.rs: `let mut dwarf_bytes = bytes.clone();` had `mut` only for the `#[cfg(target_os = "macos")]` reassignment, so non-macOS hosts hit `error: variable does not need to be mutable` under `-D warnings`. Fix by binding `dwarf_bytes` separately on the two cfgs: a non-mut `bytes.clone()` on non-macOS, and a block-expression that does the mutable reassignment and returns the result on macOS. - decoder/src/elf2table/mod.rs: `clippy::collapsible_if` flagged the nested `if name_str == "DEFMT_LOG_STATEMENT" { if table.raw_symbols()…` in the standard-ELF branch. Collapse with `&&`. - decoder/src/frame.rs: `clippy::cloned_ref_to_slice_refs` (Rust 1.93, not yet in the CI matrix but coming): `&[arg.clone()]` -> `std::slice::from_ref(arg)`. Also picks up `cargo fmt --all` whitespace fixes in the same areas. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Apple's linker strips memory addresses from `#[no_mangle]` statics that its visibility analysis treats as unreferenced, so the standard ELF DWARF→symtab correlation (`DW_AT_location` → address → symbol-table entry) collapses every defmt log to address 0 on macOS host builds. Result today on macOS: `Locations` is empty/wrong and ERROR-level log lines render without `file:line` (gen2's `runtime/observability/logging/output.rs:361` already plumbs the `Locations` map; it just has nothing to look up). This commit ports the design from upstream PR knurling-rs#1029 (lakechurch's `fix-macos-dsym-mapping`) onto our `gen-bc/defmt:main` line, adapted for the existing unified `.defmt.{severity}` section layout we already have. What changes: - macros/src/construct.rs: alongside every defmt log static, on macOS emit a sibling marker `DEFMT_LOC_MARKER_{hash}` whose source ident encodes a 64-bit SipHash of the log's `sym_name`. `#[used]` keeps the marker referenced; `#[link_section = "__DATA,__defmt_loc"]` parks it in its own data section. No emission on non-macOS. - decoder/src/elf2table/mod.rs: on Mach-O, build a `hash_to_index` side table keyed by hash of each entry's `raw_symbol` (with leading `_` stripped, since Mach-O exports carry it) and valued at the entry's table key. Walk DWARF, find variable DIEs whose `DW_AT_name` starts with `DEFMT_LOC_MARKER_`, parse the hex hash, and resolve to the table key via `hash_to_index`. The non-Mach-O path is untouched. Hardening: bail on hash collisions both when building `hash_to_index` (two symbols hashing to the same value) and when inserting into the result map (the actual location-collision bug we're guarding). - print/src/main.rs: on macOS with `split-debuginfo = "packed"`, DWARF lives in a sibling `<elf>.dSYM` bundle rather than embedded in the Mach-O. Open the first file under `<elf>.dSYM/Contents/Resources/DWARF/` and feed those bytes to `get_locations`. On other platforms the main ELF has DWARF embedded so we keep using `bytes` directly. Build: `cargo build` clean. Two pre-existing warnings on `gen-bc/main` (`unused_unsafe` in defmt/src/export/mod.rs and `unused defmt_section` in elf2table/mod.rs) are not introduced by this commit. Tests: `cargo test -p defmt-decoder --lib` — all 56 pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Currently without correct locations in symbol tables on mac, but everything else should work as expected, with no impact on embedded systems