Hi Jiri,
On Wed, 2013-10-09 at 12:15 +0200, Jiri Slaby wrote:
On 10/09/2013 12:04 PM, Mark Wielaard wrote:
> So your patch changes the section write loop in "updatefile".
> It ignores the check to see whether the byte order changed or the shdr
> comes from reading a file. Then always allocas a new shdr_data instead
> of reusing the data from the file. Then for each section memcpy the data
> into the new shdr_data ignoring the existing the existing elf state shdr
> from the file.
Yes, because the state might have changed as can be demostrated by the
attached program (I removed the "#if 0" so yo ucan see it explicitly now).
> I assume in your case the number of sections changed and the current
> test doesn't take that into account? So you also want to reallocate the
> shdr in that case?
Exactly.
OK, thanks for the cleaned up test case. I think I finally understand
now. I believe the correct check here is to see if the elf flags have
ELF_F_DIRTY set indicating something changed between what is in memory
and on disk. If so we need to realloc and explicit copy over the new scn
shdr. What do you think about the following?
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
index 296b1ac..c4af9c0 100644
--- a/libelf/elf32_updatefile.c
+++ b/libelf/elf32_updatefile.c
@@ -633,7 +633,8 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t
shnum)
#endif
ElfW2(LIBELFBITS,Shdr) *shdr_data;
- if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
+ if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL
+ || (elf->flags & ELF_F_DIRTY))
shdr_data = (ElfW2(LIBELFBITS,Shdr) *)
alloca (shnum * sizeof (ElfW2(LIBELFBITS,Shdr)));
else
@@ -764,7 +765,8 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t
shnum)
(*shdr_fctp) (&shdr_data[scn->index],
scn->shdr.ELFW(e,LIBELFBITS),
sizeof (ElfW2(LIBELFBITS,Shdr)), 1);
- else if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
+ else if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL
+ || (elf->flags & ELF_F_DIRTY))
memcpy (&shdr_data[scn->index], scn->shdr.ELFW(e,LIBELFBITS),
sizeof (ElfW2(LIBELFBITS,Shdr)));