Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix parsing of Windows library archives #174

Merged
merged 3 commits into from
Jul 13, 2019
Merged

Fix parsing of Windows library archives #174

merged 3 commits into from
Jul 13, 2019

Conversation

raindev
Copy link
Contributor

@raindev raindev commented Jul 12, 2019

Implement parsing of Windows-specific Second Linker Member in SysV archives. Also fix the parser going out of boundaries if the archive is aligned.

I have verified that the parser succeeds on the samples from both #173 and #133. I was thinking about automated tests but it's quite ugly bringing binary data into the repository for testing. I think using cc crate to build binaries from source might be a better approach. With a Windows Travis pipeline the CI can verify parsing of PE binaries as well.

Use Windows-specific symbol index to replace SysV index if present

Fixes #173 and #133
Archive data sections are 2 byte aligned. Fix the parsing termination
condition which was going out of bounds otherwise.
index = Index::parse_sysv_index(data)?;
index = if sysv_symbol_index_seen {
// Second symbol index is Microsoft's extension of SysV format
Index::parse_windows_linker_member(data)?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Accordingly to Microsoft's documentation, the first symbol index entry (First Linker Member) is not used by linkers and is kept for compatibility reasons. Given this, it seems reasonable to simply replace the index parsed previously rather than providing access to both.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sounds good to me.

Copy link
Collaborator

@philipc philipc left a comment

Choose a reason for hiding this comment

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

Looks good, just some minor comments.

} else {
sysv_symbol_index_seen = true;
Index::parse_sysv_index(data)?
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
}
};

@@ -366,7 +398,13 @@ impl<'a> Archive<'a> {
let name = member.raw_name();
if name == INDEX_NAME {
let data: &[u8] = buffer.pread_with(member.offset as usize, member.size())?;
index = Index::parse_sysv_index(data)?;
index = if sysv_symbol_index_seen {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we should return an error if this is the third time or more.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or ignore them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure about this. We'll have to track then number of occurrences of index, including BSD index to have the behaviour consistent and allow only one index to be present (exept if it's Windows linker member). I think it would be better to tackle it systematically in a separate pull-request.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The current behaviour would be to threat all the subsequent SysV symbol indexes as Windows linker members, similar to running into multiple BSD symbol indexes.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm fine with doing this in another PR, but I don't like treating subsequent SysV symbol index as Windows linker members because that's the sort of sloppy parsing that caused the errors this PR is fixing. It's better to not support something, rather than try to parse it incorrectly.

Copy link
Contributor Author

@raindev raindev Jul 12, 2019

Choose a reason for hiding this comment

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

I agree that the parsing should be more strict. It's just the question of how much complexity is it worth introducing for. I've drafted a separate PR #175 to figure the best way forward.

index = Index::parse_sysv_index(data)?;
index = if sysv_symbol_index_seen {
// Second symbol index is Microsoft's extension of SysV format
Index::parse_windows_linker_member(data)?
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sounds good to me.

}
let mut symbol_offsets = Vec::with_capacity(symbols);
for i in symbol_indexes {
symbol_offsets.push(member_offsets[i - 1]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could this be done in the previous loop? That is, we don't actually need to create symbol_indexes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's right, done.

@raindev
Copy link
Contributor Author

raindev commented Jul 12, 2019

Thanks for the quick feedback Philip!

@raindev
Copy link
Contributor Author

raindev commented Jul 13, 2019

@philipc it would be great if you can release a version which contains the changes to crates.io.

@philipc
Copy link
Collaborator

philipc commented Jul 13, 2019

@m4b Can you do a release please?

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