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

modify elf #426

Closed
drahnr opened this issue May 8, 2019 · 14 comments
Closed

modify elf #426

drahnr opened this issue May 8, 2019 · 14 comments

Comments

@drahnr
Copy link

drahnr commented May 8, 2019

Attempting to get a kickstart from the examples, I tried to write a tool that adjusts some debugging symbols (mostly compileunit paths), but the exact requirement on what to pass to read::Dwarf::load and write::Dwarf::write is not clear (I consulted the manual and the source, but that did not help much either).

Can somebody shed some light on how to approach modifying a loaded DebugAbbrev and DebugInfo writing a fully valid elf out with the modified changes? I'd much appreciate that.

@philipc
Copy link
Collaborator

philipc commented May 8, 2019

The dwarfdump example contains a use of read::Dwarf::load. Probably what isn't clear is that the section and sup parameters need to return instances of Reader.

For write::Dwarf::write, you simply need to pass an instance of Sections which contains Writers. The convert_self test has an example usage.

If you're looking to write out a fully valid elf, then you'll need a Reader implementation that preserves relocations, and a Writer implementation that writes relocations. This is not an easy thing to do, particularly on the read side, because it wasn't designed for this use case. There's some code at https://github.com/philipc/rewrite that attempts to load and write an ELF file, but it is very much a work in progress. #409 is an example of something I want to do to make this better.

@philipc
Copy link
Collaborator

philipc commented May 9, 2019

Also, if you only need this to work for executables and dynamic libraries (and not .o files), then the debuginfo won't have relocations. In that case, you can use EndianSlice or EndianReader for the Reader and EndianVec for the Writer.

@drahnr
Copy link
Author

drahnr commented May 9, 2019

I only need it to work for execute from flash embedded devices without any relocations and also only modifying the debug information which is dwarf 3 / dwarf 4.

API wise I need to load every section indipendently put into read::Dwarf (so not use it's load?) followed by the conversion with from - but where do I apply my modifications, in the read or in the write tree? The read tree has far more convenience/rustic methods than write, but none which mutate the tree (or I missed them).

@philipc
Copy link
Collaborator

philipc commented May 9, 2019

API wise I need to load every section indipendently put into read::Dwarf (so not use it's load?)

Why not use load? All you need to do is provide load with a function that accepts a SectionId and returns the corresponding EndianSlice.

but where do I apply my modifications, in the read or in the write tree?

In the write tree, but note that write support is still under development. You're right that it has less convenience methods currently, but PRs to add them are welcome.

@drahnr
Copy link
Author

drahnr commented May 9, 2019

If I use load,the conversion to write::Dwarf fails with MissingCompilationDirectory

@philipc
Copy link
Collaborator

philipc commented May 9, 2019

That's a bug then. Can you give me the info required to reproduce it?

@drahnr
Copy link
Author

drahnr commented May 9, 2019

I created this repo https://github.com/drahnr/dwarfhammer
interestingly the issue only appears when using armcc (not by choice, obtainable here with a trial license https://developer.arm.com/tools-and-software/embedded/arm-compiler/downloads/version-5 ).

Sidenote: I also tried with gnu-arm-eabi-none generated elf I had around, but that fails differently during parsing already.

Thanks for having a look into it, I'll try to create an example elf that shows the error.

@drahnr
Copy link
Author

drahnr commented May 10, 2019

@philipc added a sample via a downloadable url to the repo with the commit called tmp

@philipc
Copy link
Collaborator

philipc commented May 11, 2019

The download link has expired.

@drahnr
Copy link
Author

drahnr commented May 11, 2019

Mea culpa, updated 51b946, I made the repo private and added you as contributor, link is in the same file as before.

@philipc
Copy link
Collaborator

philipc commented May 11, 2019

Ok got that. It's missing a DW_AT_comp_dir attribute, so probably what we should do is change this to use an empty string instead of returning an error. e.g.

                let comp_dir = match from_header.directory(0) {
                    Some(comp_dir) => LineString::from(comp_dir, dwarf, line_strings, strings)?,
                    None => LineString::String(Vec::new()),
                };

@drahnr
Copy link
Author

drahnr commented May 11, 2019

Works for me, though I am not sure what the dwarf3/4/5 has to say about requirement of DW_AT_comp_dir being present or not?

@bjorn3
Copy link
Contributor

bjorn3 commented May 11, 2019

It doesn't seem to say it is required.

@philipc
Copy link
Collaborator

philipc commented May 19, 2019

Missing DW_AT_comp_dir fix is in #430.

@drahnr drahnr closed this as completed Aug 23, 2019
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

No branches or pull requests

3 participants