Skip to content

DWARF expression support for OxCaml LLDB#33

Open
spiessimon wants to merge 1 commit into
oxcaml-llvm-pluginfrom
dwarf-expressions-support
Open

DWARF expression support for OxCaml LLDB#33
spiessimon wants to merge 1 commit into
oxcaml-llvm-pluginfrom
dwarf-expressions-support

Conversation

@spiessimon
Copy link
Copy Markdown

This PR lets the OxCaml formatter evaluate DWARF expressions at format time so the compiler can describe layout facts that depend on the value being formatted—most importantly variant payload sizes that vary by active constructor.

Motivation

OxCaml's static type model assumed constant member offsets, constant sizes, and constant strides. That assumption broke down for variants: the formatter previously worked around dynamic allocation sizes with a two-pass estimator that inferred a maximum member end offset from the active variant members. The workaround did not match the compiler's actual layout knowledge, and could not express anything that needed process memory (e.g. a size derived from the OCaml block header).

LLDB already has a fully capable DWARF expression evaluator. The right fix is to keep the relevant DW_FORM_exprloc attributes around at parse time and evaluate them from the formatter with a live execution context.

What changes

  • Dynamic layout values. Layout-bearing attributes (DW_AT_byte_size, DW_AT_bit_size, DW_AT_data_member_location, DW_AT_data_bit_offset, DW_AT_count, DW_AT_byte_stride`) are stored as either a constant or a DWARF expression, tagged with the kind of result they produce (scalar bits/bytes/elements, or a location) and the initial-stack convention (empty, or pre-loaded with the object pointer).
  • Formatter context. A small context object is threaded through the recursive formatter so expressions can be evaluated with a real ExecutionContext, register context, and module. Raw OCaml object addresses are passed alongside so location-valued expressions and DW_OP_push_object_address work.
  • Variant sizing via the compiler. With the compiler emitting accurate sizes (constant where known, DW_FORM_exprloc for tag-dependent payloads), the two-pass discriminator-sizing workaround is removed. The formatter trusts the size attribute.
  • Raw-pointer member-offset convention. Member offsets and locations are now relative to the raw OCaml object pointer rather than the post-header address. The plugin reads the OCaml block header explicitly at object_address - WORD_SIZE when needed.
  • Removed custom attribute handling. Support for DW_AT_ocaml_offset_record_from_pointer (0x3106) is deleted along with the pointer-adjustment path. This is an intentional breaking change paired with the OxCaml compiler PR; old binaries that still emit the legacy attribute are not supported.
  • Malformed-expression handling. Expression evaluation failures and result-kind mismatches (a location-valued attribute that ends with DW_OP_stack_value, or a scalar attribute that returns a memory location) log under the OxCaml formatting category and fall back to the usual formatter error marker rather than fabricating an address.

Compatibility

Intentionally breaking with binaries produced by older OxCaml compilers that emit DW_AT_ocaml_offset_record_from_pointer and the header-relative DW_AT_data_member_location convention. The matching compiler change ships in the OxCaml repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant