Sunday, May 28, 2006

ELF CORE file optimizations in Linux, problems with non standardization of core files.

Well, all these days life is revolving on BINARY RECONSTRUCTION from the corefiles(although this is only one of the ideas I have currently for BINARY RECONSTRUCTION).

o After my deep observation of the fact why core files have some program headers which have phdr.p_filesiz==0, found that David Miller, had added some changes to the core file which the linux kernel dumps, the optimizations are ofcourse to reduce the core file size, so I guess these guys are taking off the text part of the executable and the text part of the dyanmic shared libraries.

o My Question is WHY?? WHY?? do these people just dont try to stick to standards (if some standard dont exist they should create one, and once they enhance some stuff then update the standard rather than just flushing the changes into the code), in this opensource community this is really bad that the current standard of the core file depends on few induviduals.

I checked the PHDRS (readelf --segments) the following are the PHDRS of the core.exe
=================================
Elf file type is EXEC (Executable file)
Entry point 0x8048364
There are 11 program headers, starting at offset 52

Program Headers:
 Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
 NOTE           0x000194 0x00000000 0x00000000 0x00a48 0x00000     0
 **LOAD           0x001000 0x08048000 0x00000000 0x00000 0x01000 R E 0x1000

 LOAD           0x001000 0x08049000 0x00000000 0x01000 0x01000 RWE 0x1000
 LOAD           0x002000 0xf649b000 0x00000000 0x01000 0x01000 RWE 0x1000
 **LOAD           0x003000 0xf649c000 0x00000000 0x00000 0x132000 R E 0x1000
 LOAD           0x003000 0xf65ce000 0x00000000 0x03000 0x03000 RWE 0x1000
 LOAD           0x006000 0xf65d1000 0x00000000 0x03000 0x03000 RWE 0x1000
 LOAD           0x009000 0xf65e8000 0x00000000 0x01000 0x01000 RWE 0x1000
 **LOAD           0x00a000 0xf65e9000 0x00000000 0x00000 0x15000 R E 0x1000
 LOAD           0x00a000 0xf65fe000 0x00000000 0x01000 0x01000 RWE 0x1000
 LOAD           0x00b000 0xfeffe000 0x00000000 0x02000 0x02000 RWE 0x1000
===================================

o As I said earlier I see some of the PHDRS are having FileSiz as zero, the
first (1st **ed ) PHDR which is having virtual address 0x08048000
(this is obviously) the start of the text of the program, and its not
having any memory in the core file.

o The other PHDRS for which FileSiz is zero correspond to the
dynamic shared objects (.so) text , example in the above we see (2
**ed ) PHDR with VirtAddr as 0xf649c000 , so this means the text of
some shared .so has been mapped here.

o I had a question about the memory mapping with permissions r--s or
r--p (gconv used by glibc gets mapped like this some time) , so does
the core file contains this information of the memory mappings? IMO this content
is also mapped as PROGBITS I guess not sure.

o Is there a way I can findout the standard which the OS follows to
write the core file? No absolutely no, solaris dumps the entire core.

o Rather than depending on the OS core file, hows your opinion on
writing out all the mappings form /proc//maps as PT_LOAD into a
elf formatted file of type ET_EXEC, do you think this works? rather
than converting core file to exe?

Should I start working to write the standard.

=======================================================
#include
#include
#include
#include
#include

#ifndef __64_BIT__
#define __32_BIT__
#endif

#ifdef __32_BIT__
#define ELF_EHDR Elf32_Ehdr
#else
#define ELF_EHDR Elf64_Ehdr
#endif

ELF_EHDR place_holder;

/*Chages the elf_header in the file with ptr */
int ChangeElfHeader(int CoreFd, int WriteFd, unsigned long vaddr){

     unsigned long got_len=0;

     if((got_len = read(CoreFd,&place_holder,sizeof(ELF_EHDR)))
             != sizeof(ELF_EHDR)){
             perror("Unable to read the ELF Header::");
             exit(1);
     }
     /*Change the ET_CORE tto ET_EXEC*/
     if(place_holder.e_type == ET_CORE) {
             place_holder.e_type = ET_EXEC;
     } else {
             fprintf(stderr,"The file is not of ELF core file");
             exit(1);
     }

     /*Change the entry */

     place_holder.e_entry = vaddr;

     /*Write back the header*/
     got_len = 0;
     if (( got_len = write(WriteFd,&place_holder,sizeof(ELF_EHDR)))
             != sizeof(ELF_EHDR)) {
             perror("Unable to write the header::");
             exit(1);
     }
     return 1;
}

static void finishWriting(int coreFd, int writeFd) {

     unsigned char write_buffer[4*1024];
     int got_len = -1;

     while( (got_len = read(coreFd,write_buffer,4096)) != 0) {
             if(write(writeFd,write_buffer,got_len) != got_len ){
                     perror("Unable to to write the length which was read:");
                     exit(1);
             }
     }
     close(writeFd);
     close(coreFd);

}

int main(int argc,char* argv[]){

     int coreFd;
     int writeFd;
     unsigned long vaddr;

     if( argc < 3 ) {
             fprintf(stderr,"Usage core2elf core.file exe.file.name");
             exit(1);
     }
     if( (coreFd = open(argv[1],O_RDONLY)) < 0) {
             perror("Unable to open the core file:");
             exit(1);
     }
     if ((writeFd = open(argv[2],O_WRONLY| O_CREAT)) < 0) {
             perror("Unable to open the write file::");
             exit(1);
     }
     sscanf(argv[3],"%lx",&vaddr);
     ChangeElfHeader(coreFd,writeFd,vaddr);
     finishWriting(coreFd,writeFd);


}
====================================================

No comments: