Skip to content

fix: Use correct symbol priority when primary definition is dynamic#1601

Merged
davidlattimore merged 7 commits into
wild-linker:mainfrom
levietduc0712:test_symbol_binding
Feb 28, 2026
Merged

fix: Use correct symbol priority when primary definition is dynamic#1601
davidlattimore merged 7 commits into
wild-linker:mainfrom
levietduc0712:test_symbol_binding

Conversation

@levietduc0712

Copy link
Copy Markdown
Contributor

This pull request improves the symbol resolution logic to correctly prioritize symbol bindings (strong, common, weak, GNU unique) when multiple object files define the same symbol. It also adds new integration tests to verify the correct behavior.

Comment thread libwild/src/grouping.rs
self.parsed.object.is_dynamic()
}

pub(crate) fn symbol_strength(&self, symbol_id: crate::symbol_db::SymbolId) -> SymbolStrength {

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.

It looks like this function is more or less a copy of ObjectFile::symbol_strength. Can you deduplicate?

Comment thread libwild/src/symbol_db.rs Outdated
Comment on lines +1105 to +1141
let mut max_common: Option<(u64, SymbolId)> = None;
let mut first_weak: Option<SymbolId> = None;

for &alt in alternatives {
let file_id = symbol_db.file_id_for_symbol(alt);
let file = symbol_db.file(file_id);
if file.is_dynamic() {
continue;
}
let strength = file.symbol_strength(alt);
match strength {
SymbolStrength::Strong => {
return Some(alt);
}
SymbolStrength::Weak | SymbolStrength::GnuUnique => {
if first_weak.is_none() {
first_weak = Some(alt);
}
}
SymbolStrength::Common(size) => {
if let Some((prev_size, _)) = max_common {
if size > prev_size {
max_common = Some((size, alt));
}
} else {
max_common = Some((size, alt));
}
}
SymbolStrength::Undefined => {}
}
}

if let Some((_, id)) = max_common {
return Some(id);
}

first_weak

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.

The logic here seems to be more or less the same as select_symbol. Can they share code?

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 suspect this test passes even without your change. Can you adapt the test so that tests what you changed? You'll need to look at where get_non_dynamic is called and figure out when that code path is exercised. That will hopefully also allow you to make the commit message more specific as to what's being fixed.

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.

That makes sense now. However, I just tried reverting your non test changes and the test still passes. Does it fail for you?

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.

It passes for me as well

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.

Any idea why it passes without your fix?

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.

The test passes without the fix because of how definition() works with two-level indirection. So the test can't distinguish between the old and new get_non_dynamic because select_symbol + definition() always resolves the correct winner regardless of which non-dynamic alternative get_non_dynamic picks.

Let me update it.

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. I can confirm that the test now fails for me without your fix.

@levietduc0712

Copy link
Copy Markdown
Contributor Author

All 3 review comments have been addressed.

@davidlattimore davidlattimore changed the title feat: enhance symbol binding logic in get_non_dynamic function fix: Use correct symbol priority when primary definition is dynamic Feb 27, 2026
@levietduc0712 levietduc0712 marked this pull request as draft February 28, 2026 01:31
@levietduc0712 levietduc0712 marked this pull request as ready for review February 28, 2026 01:50

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. I can confirm that the test now fails for me without your fix.

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 think the names of the two secondary files now don't make so much sense since they each contain one weak and one strong symbol.

@levietduc0712 levietduc0712 Feb 28, 2026

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.

Do you have a suggestion for better names?

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'm not sure what you're asking

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.

Sorry, I got a bit lost.

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.

The two files have been renamed.

@davidlattimore davidlattimore merged commit d3f3895 into wild-linker:main Feb 28, 2026
20 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