gimli
gimli copied to clipboard
Read, modify, write?
Can I use gimli to patch some stuff in the eh_frame section of an executable? I saw there are two different structs for e.g. CIE's for read and write. So I assume reading, modifying and writing again is not really a use case? Probably because changing the size of anything would corrupt the whole binary? Is patching inline, without changing the size, out of scope as well?
This isn't really supported currently. There is write::FrameTable::from
to allow reading an entire table and then writing it again, but so far it's only been used for testing purposes that I know of, and support for modification is missing.
For patching individual entries, we could expose some of the internals of that if it helps, such as FrameDescriptionEntry::from
and FrameDescriptionEntry::write
, but I suspect you might be better of using only the read portion of gimli and doing the patching code yourself.
Does something prevent me in general from writing a converter from the read
data structures to the write
data structures?
Are there some information missing/not accessible where I would need to do more reading/writing myself?
E.g. I noticed that the CallFrameInstruction
enums do not contain the same amount of instructions for read
and write
.
FWIW, there are some half-baked ideas about similar transformations over DWARF in https://github.com/bytecodealliance/wasmtime/issues/5537
Note that patching an executable is a bit harder of a constraint because the size of the encoded DWARF can change depending on what you're doing (even just changing an index can change size because of LEB128 encoding).
Does something prevent me in general from writing a converter from the
read
data structures to thewrite
data structures?
These should already exist. I linked to some before.
Are there some information missing/not accessible where I would need to do more reading/writing myself?
The read API should provide all the information. The write API is aimed at producing DWARF, not patching it, so it may not support everything you need for patching.
E.g. I noticed that the
CallFrameInstruction
enums do not contain the same amount of instructions forread
andwrite
.
See write::CallFrameInstruction::from
to see which read instructions we support for writing; I think SetLoc
and Nop
are the only ones missing. For the others, there isn't a one to one correspondence because write
chooses between instructions as needed, so this isn't ideal for the patching scenario.
I know that patching will very likely result in having to extend the section in the binary and shift all following sections accordingly which is hard. So, I consider the patching use case to be rather niche.
In general, would you like gimli to have a patching ability anyway?
To be clear, by patching I mean to not just change existing CIE / FDE, but also adding new records of these including byte code instructions etc.
I know that patching will very likely result in having to extend the section in the binary and shift all following sections accordingly which is hard.
That part of the problem is outside the scope of gimli. You'll need to implement it in whatever is processing the ELF/Mach-O/COFF.
In general, would you like gimli to have a patching ability anyway?
It depends on how you are proposing to implement the patching ability. Options that might fit in gimli are adding mutation of the existing write data structures, or adding a visitor for the transformation as mentioned in https://github.com/bytecodealliance/wasmtime/issues/5537.
It might be best to implement a prototype first to see what meets your needs.