-
Notifications
You must be signed in to change notification settings - Fork 111
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
dwarfdump: handle relocations #337
Conversation
c7b4141
to
96c8487
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks really great, and it will be so nice to have this functionality implemented. Most of these changes are also great, but I do have one piece of feedback.
I'm skeptical on using a new trait for hooking underlying calls, instead of using composition the way that iterators, futures, etc work.
Here is a sketch of what I would expect this to look like:
#[derive(Clone, Debug)]
pub struct RelocReader<'a, R> {
reader: R,
section: R,
relocations: &'a RelocationMap,
}
impl Reader for RelocReader<R>
where
R: Reader,
{
type Endian = R::Endian;
type Offset = R::Offset;
// For the methods that need relocs applied, we wrap the underlying reader
// directly (instead of indirectly via a new hooks trait).
fn read_address(&mut self, address_size: u8) -> gimli::Result<u64> {
let offset = self.reader.offset_from(&self.section);
let value = self.reader.read_address(address_size)?;
Ok(self.relocate(offset, value))
}
fn read_length(&mut self, format: gimli::Format) -> gimli::Result<usize> {
let offset = self.reader.offset_from(&self.section);
let value = self.reader.read_length(format)?;
<usize as gimli::ReaderOffset>::from_u64(self.relocate(offset, value as u64))
}
// etc...
// And then delegate the other methods that don't need relocs applied
// directly to the underlying reader.
fn endian(&self) -> Self::Endian {
self.reader.endian()
}
fn len(&self) -> Self::Offset {
self.reader.len()
}
// etc...
}
What are your thoughts on this approach vs the hooks trait?
Yeah I'd love to have a better way of doing the hooking. The problem I want to solve is that I want whatever is doing the default delegations to be in gimli, so that we don't have a ton of boilerplate in every client that wants to handle relocations. For your suggestion, Is there some way to avoid the delegation boilerplate with a macro? It's not something I've looked into. |
Replace use of read_word() with either read_length() or read_offset() as appropriate.
This allows it to be distinguished from addresses when doing relocations.
Adding a There's a couple of crates with delegation macros, but they barely reduce the boilerplate in my opinion. I've updated the PR. I've deleted the hook stuff from gimli, and dwarfdump does the full |
@fitzgen can you take another look at this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
This applies relocations as we read values, as suggested in #180 (comment).
I've seen relocations for the
read_address
andread_offset
hooks. I expect DWARF 2 to need relocations for theread_sized_offset
hook. I'm not sure that theread_length
hook is required, but it doesn't hurt.Fixes #180