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

dwarfdump: handle relocations #337

Merged
merged 5 commits into from
Nov 2, 2018
Merged

dwarfdump: handle relocations #337

merged 5 commits into from
Nov 2, 2018

Conversation

philipc
Copy link
Collaborator

@philipc philipc commented Oct 22, 2018

This applies relocations as we read values, as suggested in #180 (comment).

I've seen relocations for the read_address and read_offset hooks. I expect DWARF 2 to need relocations for the read_sized_offset hook. I'm not sure that the read_length hook is required, but it doesn't hurt.

Fixes #180

@philipc philipc force-pushed the reloc branch 2 times, most recently from c7b4141 to 96c8487 Compare October 25, 2018 03:29
@coveralls
Copy link

coveralls commented Oct 25, 2018

Coverage Status

Coverage decreased (-0.06%) to 85.499% when pulling 7af90a4 on philipc:reloc into 5398258 on gimli-rs:master.

@philipc philipc changed the title [WIP] dwarfdump: handle relocations dwarfdump: handle relocations Oct 25, 2018
@philipc philipc requested a review from fitzgen October 25, 2018 07:16
Copy link
Member

@fitzgen fitzgen left a 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?

@philipc
Copy link
Collaborator Author

philipc commented Oct 25, 2018

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, RelocReader would have to be in gimli, which means we need to also put RelocationMap in gimli, but I'm worried that RelocationMap is too dependent on the client's relocation parsing to be able to do that... unless we make RelocationMap be a trait too?

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.
@philipc
Copy link
Collaborator Author

philipc commented Oct 26, 2018

Adding a struct RelocReader and trait RelocationMap to gimli is basically the same as the struct HookedReader and trait ReaderHook but less flexible, so I don't think that gains us anything.

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 Reader impl now.

@philipc
Copy link
Collaborator Author

philipc commented Nov 1, 2018

@fitzgen can you take another look at this?

@philipc philipc mentioned this pull request Nov 2, 2018
Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Looks great!

@fitzgen fitzgen merged commit 4b765e4 into gimli-rs:master Nov 2, 2018
@philipc philipc deleted the reloc branch November 3, 2018 03:36
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.

3 participants