Skip to content

feat: Add ASSERT command parsing support to linker scripts#1607

Merged
davidlattimore merged 5 commits into
wild-linker:mainfrom
Blazearth:feat/linker-script-assert
Mar 9, 2026
Merged

feat: Add ASSERT command parsing support to linker scripts#1607
davidlattimore merged 5 commits into
wild-linker:mainfrom
Blazearth:feat/linker-script-assert

Conversation

@Blazearth

Copy link
Copy Markdown
Contributor

Adds parsing support for ASSERT(expression, "message") commands in linker scripts. Both top-level and within SECTIONS blocks are supported.

Assertions are parsed and stored in the AST but not yet evaluated. This is commonly used in Linux kernel linker scripts to validate memory layout constraints.

Changes

  • Added Assert variant to Command and SectionCommand enums
  • Implemented parse_assert() function
  • Added handling in layout_rules.rs (currently no-op with TODO)
  • Added 3 tests covering various ASSERT syntaxes

Evaluation will be implemented in a follow-up PR.

@Blazearth

Copy link
Copy Markdown
Contributor Author

The AArch64 test appears to be failing during the wild-action installation step (exit code 2), not during actual test execution. All other checks pass and tests pass locally. Let me know if I should investigate further or if this is a known CI issue.

@davidlattimore davidlattimore left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this :)

Comment thread libwild/src/linker_script.rs Outdated
Comment thread libwild/src/linker_script.rs Outdated
@Blazearth Blazearth marked this pull request as draft February 28, 2026 10:09
@Blazearth Blazearth marked this pull request as ready for review February 28, 2026 10:37
@Blazearth Blazearth marked this pull request as draft February 28, 2026 10:57
@Blazearth

Copy link
Copy Markdown
Contributor Author

Update: Expression Parsing Implemented

I've implemented full expression parsing as requested. The parser now handles:

Supported features:

  • Arithmetic operators: +, -, *, / with correct precedence
  • Comparison operators: <, >, <=, >=, ==, !=
  • Functions: SIZEOF(), ADDR(), ALIGN()
  • Numbers (hex/decimal), symbols, location counter (.)
  • Parentheses for grouping
  • Trailing input validation to catch parsing errors

Tests added:

  • Operator precedence: 1 + 2 * 3 == 7
  • Nested parentheses: (1 + 2) * (3 + 4) == 21
  • Functions in comparisons: SIZEOF(.data) + SIZEOF(.bss) < 0x2000
  • Hex number parsing: 0xDEADBEEF
  • ALIGN function with expressions

Scope documentation:
Added inline documentation listing what's currently supported and what's not yet implemented (unary operators, bitwise/logical ops, additional functions). This covers the common ASSERT patterns used in Linux kernel linker scripts.

@Blazearth Blazearth marked this pull request as ready for review February 28, 2026 15:59
Comment thread libwild/src/linker_script.rs Outdated
Comment thread libwild/src/linker_script.rs Outdated
Comment thread libwild/src/linker_script.rs Outdated
@Blazearth Blazearth requested a review from davidlattimore March 2, 2026 15:46

@davidlattimore davidlattimore left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the slow review. Looks like I started reviewing and had some draft comments, but forgot to send them and I only just noticed.


/// Parse comparison operators: <, >, <=, >=, ==, !=
fn parse_comparison<'a>(input: &mut &'a BStr) -> winnow::Result<Expression<'a>> {
let mut left = parse_additive.parse_next(input)?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect that the left hand side of a comparison would itself be an expression


/// Parse an expression - entry point for expression parsing
fn parse_expression<'a>(input: &mut &'a BStr) -> winnow::Result<Expression<'a>> {
parse_comparison.parse_next(input)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know for an assertion that an expression must be a comparison, but not all expressions need to be comparisons. I guess there are two options. You could change parse_assert to call parse_comparison, or you could parse an arbitrary expression, and then at some point we validate that that expression is indeed a comparison.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In gnu ld it treats any expression that resolve to non zero value as valid in assertion and if it reolves to zero it stops. So do you recommend i should check for comparison later after parsing the expression or i follow the same behaviour as gnu ld

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'd say that type checking should be a separate pass and that we shouldn't try to bake type checking into parsing.

Comment thread libwild/src/linker_script.rs Outdated
Comment thread libwild/src/linker_script.rs Outdated

alt((
// Parentheses - parse expression inside
delimited('(', parse_comparison, ')'),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is a comparison what we'd expect inside parenthesis? What about other expressions like a * (b - c)? Would a comparison as anything but the top-level be valid?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will change from parse_comparison to parse_expression

Comment thread libwild/src/linker_script.rs Outdated
@Blazearth

Copy link
Copy Markdown
Contributor Author

Thanks for reviewing will take my time to read more about this and resolve the issues.

@Blazearth Blazearth marked this pull request as draft March 5, 2026 17:41
… chaining

- Changed while to if in parse_comparison to prevent chaining (a < b < c)
- Use parse_expression in parentheses, ALIGN, MIN, MAX for clarity
- Separates parsing from validation per maintainer feedback
@Blazearth Blazearth marked this pull request as ready for review March 9, 2026 15:07
@Blazearth Blazearth requested a review from davidlattimore March 9, 2026 15:07

@davidlattimore davidlattimore left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you test that chaining and mixing of Edit: Never mind. This was a half finished comment that I changed my mind on and forgot to delete.

@davidlattimore davidlattimore merged commit 2bf38ca into wild-linker:main Mar 9, 2026
21 checks passed
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.

2 participants