On 2020-08-13, David Blaikie via llvm-dev wrote:>Sounds like the llvm-objcopy source code (llvm/tools/llvm-objcopy) is >probably a good place to start. > >On Thu, Aug 13, 2020 at 8:11 AM Joseph via llvm-dev ><llvm-dev at lists.llvm.org> wrote: >> >> Hey, >> >> LLVM has logic to parse ELF and PE binaries using `llvm::object::createBinary`. I tried to search in the codebase to see if there's a possibility to add/remove sections after parsing a binary and re-write the binary to another location. Basically, like what llvm-objcopy does. Can you point me to the right classes to look into, if this is something that LLVM has? >> >> Many thanks >> >> JosephFor ELF, * adding a non-SHF_ALLOC section is simple. A non-SHF_ALLOC section is not part of the memory image and not used by the program (unless for some rare introspection use cases) * adding a SHF_ALLOC section is difficult. You likely need to fix the containing PT_LOAD segment. llvm-objcopy only does the base p_offset fix. You need to take care p_vaddr/p_paddr/p_filesz/p_memsz by your self. + adding a section smaller than the known lowest address (ET_EXEC with a non-zero image base) or larger than the known largest address: The PT_LOAD fixes are doable. + adding a section within the existing address ranges: this is very difficult due to many implicit inter-section references. If you have an advanced binary rewriting tool, this is still doable, but definitely brittle. File offsets (p_offset,sh_offset) can be reconstructed from addresses. llvm-objcopy/ELF/Object.cpp layoutSections has some code. A more sophisticated implementation is in the linker: lld/ELF/Writer.cpp assignFileOffsets
Many thanks for the great info. What about removing a section? Is there an implementation for that already in the codebase? On Thu, 13 Aug 2020, 20:14 Fangrui Song, <maskray at google.com> wrote:> On 2020-08-13, David Blaikie via llvm-dev wrote: > >Sounds like the llvm-objcopy source code (llvm/tools/llvm-objcopy) is > >probably a good place to start. > > > >On Thu, Aug 13, 2020 at 8:11 AM Joseph via llvm-dev > ><llvm-dev at lists.llvm.org> wrote: > >> > >> Hey, > >> > >> LLVM has logic to parse ELF and PE binaries using > `llvm::object::createBinary`. I tried to search in the codebase to see if > there's a possibility to add/remove sections after parsing a binary and > re-write the binary to another location. Basically, like what llvm-objcopy > does. Can you point me to the right classes to look into, if this is > something that LLVM has? > >> > >> Many thanks > >> > >> Joseph > > For ELF, > > * adding a non-SHF_ALLOC section is simple. A non-SHF_ALLOC section is not > part of > the memory image and not used by the program (unless for some rare > introspection use cases) > > * adding a SHF_ALLOC section is difficult. You likely need to fix the > containing PT_LOAD segment. llvm-objcopy only does the base p_offset > fix. > You need to take care p_vaddr/p_paddr/p_filesz/p_memsz by your self. > > + adding a section smaller than the known lowest address (ET_EXEC with a > non-zero image base) or larger than the known largest address: > The PT_LOAD fixes are doable. > + adding a section within the existing address ranges: this is very > difficult > due to many implicit inter-section references. If you have an advanced > binary rewriting tool, this is still doable, but definitely brittle. > > File offsets (p_offset,sh_offset) can be reconstructed from addresses. > llvm-objcopy/ELF/Object.cpp layoutSections has some code. > A more sophisticated implementation is in the linker: > lld/ELF/Writer.cpp assignFileOffsets >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200814/8079d00d/attachment.html>
Again, llvm-objcopy is the place to look for this. It has code for removing sections from ELF and other formats too, I believe. Again, speaking about ELF, the complexity depends on what you mean by removing a section though, and in what context - removing a section without SHF_ALLOC, or from an unlinked object is fairly straightforward - you simply remove its section header table entry and update any section indexes for references to sections that appear after it in the table. You can scrub over the section contents with e.g. 0. "Squashing" the ELF to remove the excess space left behind is also possible - best refer to llvm-objcopy's code again for this. Removing SHF_ALLOC sections is more complex, due to section references and addresses that will need fixing up, and borderline impossible if you are working with a linked image, without completely disassembling and reassembling the memory image. On Fri, 14 Aug 2020 at 06:44, Joseph via llvm-dev <llvm-dev at lists.llvm.org> wrote:> Many thanks for the great info. What about removing a section? Is there an > implementation for that already in the codebase? > > On Thu, 13 Aug 2020, 20:14 Fangrui Song, <maskray at google.com> wrote: > >> On 2020-08-13, David Blaikie via llvm-dev wrote: >> >Sounds like the llvm-objcopy source code (llvm/tools/llvm-objcopy) is >> >probably a good place to start. >> > >> >On Thu, Aug 13, 2020 at 8:11 AM Joseph via llvm-dev >> ><llvm-dev at lists.llvm.org> wrote: >> >> >> >> Hey, >> >> >> >> LLVM has logic to parse ELF and PE binaries using >> `llvm::object::createBinary`. I tried to search in the codebase to see if >> there's a possibility to add/remove sections after parsing a binary and >> re-write the binary to another location. Basically, like what llvm-objcopy >> does. Can you point me to the right classes to look into, if this is >> something that LLVM has? >> >> >> >> Many thanks >> >> >> >> Joseph >> >> For ELF, >> >> * adding a non-SHF_ALLOC section is simple. A non-SHF_ALLOC section is >> not part of >> the memory image and not used by the program (unless for some rare >> introspection use cases) >> >> * adding a SHF_ALLOC section is difficult. You likely need to fix the >> containing PT_LOAD segment. llvm-objcopy only does the base p_offset >> fix. >> You need to take care p_vaddr/p_paddr/p_filesz/p_memsz by your self. >> >> + adding a section smaller than the known lowest address (ET_EXEC with >> a >> non-zero image base) or larger than the known largest address: >> The PT_LOAD fixes are doable. >> + adding a section within the existing address ranges: this is very >> difficult >> due to many implicit inter-section references. If you have an >> advanced >> binary rewriting tool, this is still doable, but definitely brittle. >> >> File offsets (p_offset,sh_offset) can be reconstructed from addresses. >> llvm-objcopy/ELF/Object.cpp layoutSections has some code. >> A more sophisticated implementation is in the linker: >> lld/ELF/Writer.cpp assignFileOffsets >> > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200814/dc2d3261/attachment.html>