This is the mail archive of the frysk@sources.redhat.com mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Initial core file notes extraction for elf


Patch included is an initial implementation. Exposes .note information found in core files via the Java libelf bindings. This work is needed so that core files can be modeled in the frysk-core.

Regards

Phil
Index: lib/elf/ChangeLog
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/ChangeLog,v
retrieving revision 1.62
diff -i -r1.62 ChangeLog
0a1,27
> 2007-02-12  Phil Muldoon  <pmuldoon@redhat.com>
> 
> 	* Elf.java (getRawData): New. Return raw elf data.
> 	* cni/Elf.cxx (elf_get_raw_data): Return raw byte data.
> 
> 	* tests/TestElf.java (testElfCorePrpsNotes): New.Test Prpsinfo notes.
> 	(testElfCorePrstatusNotes): New. Test Prstatus notes.
> 	(testElfCorePrAuxvNotes): New. Test Auxv notes.
> 	
> 	* cni/ElfPrpsinfo.cxx (getNoteData): New. Parse raw note
> 	data and find relevant note section.
> 	* cni/ElfPrAuxv.cxx (getNoteData): Ditto
> 	* cni/ElfPrstatus.cxx (getNoteData): Ditto
> 	* cni/ElfData.cxx (elf_data_create_native): New. Create underlying
> 	native data structures.
> 
> 	* ElfPrstatus.java (ElfPrstatus): New Constructor.
> 	(getRawCoreRegisters): New.
> 	(getThreadData): New.
> 	(getPrCurSig): Rename.
> 	* ElfPrpsinfo.java (ElfPrpsinfo): New Constructor.
> 	* ElfPrAuxv.java (ElfPrAuxv): New Constructor.
> 	(getAuxvBuffer): Return auxv data in raw form.	
> 	* ElfData.java (ElfData): New constructor to take raw byte[] data
> 	and package into an ElfData class.
> 	(setBuffer): Take a size argument.
> 
Index: lib/elf/Elf.java
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/Elf.java,v
retrieving revision 1.22
diff -i -r1.22 Elf.java
3c3
< // Copyright 2005, Red Hat Inc.
---
> // Copyright 2005, 2006, 2007 Red Hat Inc.
441a442,453
>   /**
>    * @return Elf data packaged in ElfData class from
>    * given offset and size.
>    *
>    */
>   public ElfData getRawData(long offset, long size)
>   {
> 
>     return elf_get_raw_data(offset,size);
>   }
> 
> 
514a527,528
>   protected native ElfData elf_get_raw_data(long offset, long size);
> 
Index: lib/elf/ElfData.java
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/ElfData.java,v
retrieving revision 1.9
diff -i -r1.9 ElfData.java
3c3
< // Copyright 2005, Red Hat Inc.
---
> // Copyright 2005,2007 Red Hat Inc.
41d40
< 
51a51,63
>   
>         /**
> 	 *
> 	 * Package buffer in an  ElfData object.
> 	 *
> 	 */
>         public ElfData(byte[] buffer, Elf parent)
>         {
>            this.parent = parent;
>            this.pointer = elf_data_create_native();
> 	   setBuffer(buffer);
>         }
> 
65c77
< 			elf_data_set_buff();
---
> 			elf_data_set_buff(e_buffer.length);
190a203
>         native protected long elf_data_create_native();
192c205
< 	native protected void elf_data_set_buff();
---
> 	native protected void elf_data_set_buff(long length);
Index: lib/elf/ElfPrAuxv.java
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/ElfPrAuxv.java,v
retrieving revision 1.1
diff -i -r1.1 ElfPrAuxv.java
3c3
< // Copyright 2006, Red Hat Inc.
---
> // Copyright 2006, 2007 Red Hat Inc.
50a51,62
> 
>   /** 
>    *
>    * Extract note information from a section
>    * containing note data
>    *
>    */
>   public ElfPrAuxv(ElfData noteData)
>   {
>     getNoteData(noteData);
>   }
> 
69a82,94
>   /**
>    *
>    * Return auxv data, in raw form
>    *
>    * @return: buffer - byte[] array containing buffer
>    *
>    */
>   public byte[] getAuxvBuffer()
>   {
>     return this.auxBuffer;
>   }
> 
> 
71a97
>   public native long getNoteData(ElfData data);
Index: lib/elf/ElfPrpsinfo.java
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/ElfPrpsinfo.java,v
retrieving revision 1.4
diff -i -r1.4 ElfPrpsinfo.java
3a4
> // Copyright 2007, Red Hat, Inc.
78c79,90
<   
---
> 
>   /** 
>    * 
>    * Extract note information from a section
>    * containing note data
>    *
>    */
>   public ElfPrpsinfo(ElfData noteData)
>   {
>     getNoteData(noteData);
>   }
> 
223c235,236
<   
---
>  
>   public native long getNoteData(ElfData data);
Index: lib/elf/ElfPrstatus.java
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/ElfPrstatus.java,v
retrieving revision 1.1
diff -i -r1.1 ElfPrstatus.java
3c3
< // Copyright 2006, Red Hat Inc.
---
> // Copyright 2006,2007, Red Hat Inc.
42a43
> import java.util.Iterator;
47c48
<  * Java Representation of the the PRSTATUS notes seciont
---
>  * Java Representation of the the PRSTATUS notes secion
59a61,65
>   private long pr_info_si_signo;
>   private long pr_info_si_code;
>   private long pr_info_si_errno;
>   private int pr_fpvalid;
> 
61a68
>   private byte raw_core_registers[];
63a71
>   ArrayList internalThreads = new ArrayList();
66a75,99
> 
>   /** 
>    * 
>    * Extract note information from a section
>    * containing note data
>    *
>    */
>   public  ElfPrstatus(ElfData noteData)
>   {
>     getNoteData(noteData);
>   }
> 
>   /** 
>    * Returns the raw byte[] data 
>    * representing the register data.
>    */
>   public byte[] getRawCoreRegisters()
>   {
>     return raw_core_registers;
>   }
> 
>   public ArrayList getThreadData()
>   {
>     return internalThreads;
>   }
203c236
<   public long getPrCurSigd()
---
>   public long getPrCurSig()
221c254,300
<   /**
---
>   public Iterator getPrGPRegIterator()
>   {
>     return pr_reg.iterator();
>   }
> 
>   public void setPrInfoSiSigno(long pr_info_si_signo)
>   {
>     this.pr_info_si_signo = pr_info_si_signo;
>   }
> 
>   public long getPrInfoSiSigno()
>   {
>     return this.pr_info_si_signo;
>   }
> 
>   public void setPrInfoSiCode(long pr_info_si_code)
>   {
>     this.pr_info_si_code = pr_info_si_code;
>   }
> 
>   public long getPrInfoSiCode()
>   {
>     return this.pr_info_si_code;
>   }
> 
>   public void setPrInfoSiErrno(long pr_info_si_errno)
>   {
>     this.pr_info_si_errno = pr_info_si_errno;
>   }
> 
>   public long getPrInfoSiErrno()
>   {
>     return this.pr_info_si_errno;
>   }
> 
>   public void setPrFPValid(int pr_fpvalid)
>   {
>     this.pr_fpvalid = pr_fpvalid;
>   }
> 
>   public long getPrFPValid()
>   {
>     return this.pr_fpvalid;
>   }
>  
> 
>   /** 
234a314
>   public native long getNoteData(ElfData data);
Index: lib/elf/cni/Elf.cxx
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/cni/Elf.cxx,v
retrieving revision 1.26
diff -i -r1.26 Elf.cxx
55a56
> #include "lib/elf/ElfData.h"
401a403,412
> lib::elf::ElfData* lib::elf::Elf::elf_get_raw_data (jlong offset, jlong size)
> {
>   char *mem = gelf_rawchunk((::Elf*) this->pointer,offset,size);
>   jbyteArray bytes = JvNewByteArray(size);
>   memcpy(elements(bytes),mem,size);
>   lib::elf::ElfData *data = new lib::elf::ElfData(bytes,this);
>   gelf_freechunk((::Elf*) this->pointer,mem);
>   return data;
> }
> 
Index: lib/elf/cni/ElfData.cxx
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/cni/ElfData.cxx,v
retrieving revision 1.7
diff -i -r1.7 ElfData.cxx
3c3
< // Copyright 2005, Red Hat Inc.
---
> // Copyright 2005,2007 Red Hat Inc.
51a52,53
>   Elf_Data *native = NULL; 
> 
54a57,66
>   JvFree(native);
> }
> 
> 
> jlong
> lib::elf::ElfData::elf_data_create_native ()
> {
>   native = (Elf_Data*)JvMalloc(sizeof(Elf_Data));  
>   native->d_type = ELF_T_BYTE;
>   return (jlong) native;
72c84
< lib::elf::ElfData::elf_data_set_buff (){
---
> lib::elf::ElfData::elf_data_set_buff (jlong size){
75a88
> 	((Elf_Data*) this->pointer)->d_size = size;
Index: lib/elf/cni/ElfPrAuxv.cxx
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/cni/ElfPrAuxv.cxx,v
retrieving revision 1.1
diff -i -r1.1 ElfPrAuxv.cxx
3c3
< // Copyright 2006, Red Hat Inc.
---
> // Copyright 2006,2007 Red Hat Inc.
46a47,51
> #include "lib/elf/ElfData.h"
> #include "lib/elf/ElfException.h"
> #include "libelf.h"
> #include "elf.h"
> #include "gelf.h"
71a77
> extern jbyteArray auxBuffer;
73c79,117
< 
---
> jlong
> lib::elf::ElfPrAuxv::getNoteData(ElfData *data)
> {
>   void *elf_data = ((Elf_Data*)data->getPointer())->d_buf;
>   GElf_Nhdr *nhdr = (GElf_Nhdr *)elf_data;
>   long note_loc =0;
>   long note_data_loc = 0;
> 
>   // Find auxv note data. If the first note header is not auxv
>   // loop through, adding up header + align + data till we find the
>   // next header. Continue until section end to find correct header.
>   while ((nhdr->n_type != NT_AUXV) && (note_loc <= data->getSize()))
>     {
>       note_loc += (sizeof (GElf_Nhdr) + ((nhdr->n_namesz + 0x03) & ~0x3)) + nhdr->n_descsz;
>       if (note_loc >= data->getSize())
> 	break;
>       nhdr = (GElf_Nhdr *) (((unsigned char *)elf_data) + note_loc);
>     }
> 
>   // If loop through entire note section, and header not found, return
>   // here with abnormal return code.
>   if (nhdr->n_type != NT_AUXV)
>       return 1;
> 
>   // Find data at current header + alignment
>   note_data_loc = (note_loc + sizeof(GElf_Nhdr) + ((nhdr->n_namesz +  0x03) & ~0x3));
> 
>   // Run some sanity checks, as we will be doing void pointer -> cast math.
>   if ((nhdr->n_descsz > data->getSize())  || (nhdr->n_descsz > (data->getSize()-note_data_loc)))
>     {
>       throw new lib::elf::ElfException(JvNewStringUTF("note size and elf_data size mismatch"));
>     }
> 
>   auxBuffer = JvNewByteArray(nhdr->n_descsz);
> 
>   memcpy(elements(this->auxBuffer),((unsigned char  *)elf_data)+note_data_loc, nhdr->n_descsz);
>   
>   return 0;
> }
Index: lib/elf/cni/ElfPrpsinfo.cxx
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/cni/ElfPrpsinfo.cxx,v
retrieving revision 1.3
diff -i -r1.3 ElfPrpsinfo.cxx
3a4
> // Copyright 2007, Red Hat Inc.
44a46,48
> #include <gelf.h>
> #include <errno.h>
> 
46a51,52
> #include "lib/elf/ElfData.h"
> #include "lib/elf/ElfException.h"
129a136,192
> 
> jlong
> lib::elf::ElfPrpsinfo::getNoteData(ElfData *data)
> {
>   void *elf_data = ((Elf_Data*)data->getPointer())->d_buf;
>   GElf_Nhdr *nhdr = (GElf_Nhdr *)elf_data;
>   elf_prpsinfo *prpsinfo;
>   long note_loc =0;
>   long note_data_loc = 0;
> 
>   // Find Prpsinfo note data. If the first note header is not prpsinfo
>   // loop through, adding up header + align + data till we find the
>   // next header. Continue until section end to find correct header.
>   while ((nhdr->n_type != NT_PRPSINFO) && (note_loc <= data->getSize()))
>     {
>       note_loc += (sizeof (GElf_Nhdr) + ((nhdr->n_namesz + 0x03) & ~0x3)) + nhdr->n_descsz;
>       if (note_loc >= data->getSize())
> 	break;
>       nhdr = (GElf_Nhdr *) (((unsigned char *)elf_data) + note_loc);
>     }
> 
>   // If loop through entire note section, and header not found, return
>   // here with abnormal return code.
>   if (nhdr->n_type != NT_PRPSINFO)
>       return 1;
> 
>   // Find data at current header + alignment
>   note_data_loc = (note_loc + sizeof(GElf_Nhdr) + ((nhdr->n_namesz +  0x03) & ~0x3));
> 
>   // Run some sanity checks, as we will be doing void pointer -> cast math.
>   if ((nhdr->n_descsz > sizeof(struct elf_prpsinfo)) || (nhdr->n_descsz > data->getSize()) 
>       || (nhdr->n_descsz > (data->getSize()-note_data_loc)))
>     {
>       throw new lib::elf::ElfException(JvNewStringUTF("note size and elf_data size mismatch"));
>     }
>   
>   // Point to the data, and cast.
>   prpsinfo = (elf_prpsinfo *) (((unsigned char *) elf_data) + note_data_loc);
> 
>   // Fill Java class structures
>   this->pr_state = prpsinfo->pr_state;
>   this->pr_sname = prpsinfo->pr_sname;
>   this->pr_zomb = prpsinfo->pr_zomb;
>   this->pr_nice = prpsinfo->pr_nice;
>   this->pr_flag = prpsinfo->pr_flag;	
>   this->pr_uid = prpsinfo->pr_uid;
>   this->pr_gid = prpsinfo->pr_gid;
>   this->pr_pid = prpsinfo->pr_pid;
>   this->pr_ppid = prpsinfo->pr_ppid;
>   this->pr_pgrp = prpsinfo->pr_pgrp;
>   this->pr_sid = prpsinfo->pr_sid;
>   this->pr_fname = JvNewStringLatin1(prpsinfo->pr_fname);
>   this->pr_psargs = JvNewStringLatin1(prpsinfo->pr_psargs);
>  
>   return 0;
> }
> 
Index: lib/elf/cni/ElfPrstatus.cxx
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/cni/ElfPrstatus.cxx,v
retrieving revision 1.3
diff -i -r1.3 ElfPrstatus.cxx
3c3
< // Copyright 2006, Red Hat, Inc.
---
> // Copyright 2006,2007 Red Hat, Inc.
52c52,55
< #include "lib/elf/ElfPrstatus.h"
---
> #include "elf.h"
> #include "libelf.h"
> #include "gelf.h"
> 
53a57,61
> #include "lib/elf/ElfPrstatus.h"
> #include "lib/elf/ElfData.h"
> #include "lib/elf/ElfException.h"
> #include <java/util/ArrayList.h>
> #include <java/math/BigInteger.h>
173a182,255
> 
> extern ArrayList internalThreads;
> jlong
> lib::elf::ElfPrstatus::getNoteData(ElfData *data)
> {
>   void *elf_data = ((Elf_Data*)data->getPointer())->d_buf;
>   GElf_Nhdr *nhdr = (GElf_Nhdr *)elf_data;
>   elf_prstatus *prstatus;
>   long note_loc =0;
>   long note_data_loc = 0;
> 
> 
>   // Can have more that on Prstatus note per core file. Collect all of them.
>   while (note_loc <= data->getSize())
>     {
>       // Find Prstatus note data. If the first note header is not prstatus
>       // loop through, adding up header + align + data till we find the
>       // next header. Continue until section end to find correct header.
>       
>       while ((nhdr->n_type != NT_PRSTATUS) && (note_loc <= data->getSize()))
> 	{
> 	  note_loc += (sizeof (GElf_Nhdr) + ((nhdr->n_namesz + 0x03) & ~0x3)) + nhdr->n_descsz;
> 	  if (note_loc >= data->getSize())
> 	    break;
> 	  nhdr = (GElf_Nhdr *) (((unsigned char *)elf_data) + note_loc);
> 	}
>       
>       // If loop through entire note section, and header not found, return
>       // here with abnormal return code.
>       if (nhdr->n_type != NT_PRSTATUS)
> 	return -1;
>       
>       // Find data at current header + alignment
>       note_data_loc = (note_loc + sizeof(GElf_Nhdr) + ((nhdr->n_namesz +  0x03) & ~0x3));
>       
>       // Run some sanity checks, as we will be doing void pointer -> cast math.
>       if ((nhdr->n_descsz > sizeof(struct elf_prstatus)) || (nhdr->n_descsz > data->getSize()) 
> 	  || (nhdr->n_descsz > (data->getSize()-note_data_loc)))
> 	{
> 	  throw new lib::elf::ElfException(JvNewStringUTF("note size and elf_data size mismatch"));
> 	}
>       
>       // Point to the data, and cast.
>       prstatus = (elf_prstatus *) (((unsigned char *) elf_data) + note_data_loc);
>       
>       // Fill Java class structures
>       
>       this->pr_info_si_signo = prstatus->pr_info.si_signo;
>       this->pr_info_si_code =  prstatus->pr_info.si_code;
>       this->pr_info_si_errno = prstatus->pr_info.si_errno;
>       
>       this->pr_cursig = prstatus->pr_cursig;
>       this->pr_sigpend = prstatus->pr_sigpend;
>       this->pr_sighold = prstatus->pr_sighold;
>       
>       this->pr_pid = prstatus->pr_pid;
>       this->pr_ppid = prstatus->pr_ppid;
>       this->pr_pgrp = prstatus->pr_pgrp;
>       this->pr_sid = prstatus->pr_sid;
>       this->pr_fpvalid = prstatus->pr_fpvalid;
>       
>       raw_core_registers = JvNewByteArray(sizeof (prstatus->pr_reg));
>   
>       memcpy(elements(raw_core_registers),prstatus->pr_reg,sizeof(prstatus->pr_reg));
>       
>       internalThreads->add(this);
> 
>       // Move pointer along, now we have processed the first thread
>       note_loc += (sizeof (GElf_Nhdr) + ((nhdr->n_namesz + 0x03) & ~0x3)) + nhdr->n_descsz;
>       nhdr = (GElf_Nhdr *) (((unsigned char *)elf_data) + note_loc);
>     }
>   
>   return 0;
> }
Index: lib/elf/tests/TestElf.java
===================================================================
RCS file: /cvs/frysk/frysk-imports/lib/elf/tests/TestElf.java,v
retrieving revision 1.15
diff -i -r1.15 TestElf.java
46a47,48
> import java.nio.ByteBuffer;
> import java.nio.ByteOrder;
52d53
< import lib.elf.ElfPHeader;
54a56
> import lib.elf.ElfPHeader;
57a60,64
> import lib.elf.ElfPrpsinfo;
> import lib.elf.ElfPrAuxv;
> import lib.elf.ElfPrstatus;
> 
> import frysk.sys.proc.AuxvBuilder;
128a136,344
> 
>     
>   }
> 
>   /**
>    * Test Prpsinfo note info. Read the note data segment, pass it to
>    * ElfPrpsinfo to find the relative pstatus data, and parse. 
>    *
>    */
>   public void testElfCorePrpsNotes () throws ElfException, ElfFileException
>   {
>     
>     Elf testElf = new Elf (new File (Config.getPkgDataDir (), "test-core")
> 			   .getAbsolutePath (), ElfCommand.ELF_C_READ);
>     assertEquals(testElf.getKind(), ElfKind.ELF_K_ELF);
>     assertEquals(testElf.getBase(), 0);
> 
>     ElfData noteData = findNoteSegment(testElf);
>     
>     assertNotNull("Cannot find notes section", noteData);
>     
>     ElfPrpsinfo elfPrpsinfo = new ElfPrpsinfo(noteData);
>     //assertEquals("note: state", 'R', elfPrpsinfo.getPrState());
>     assertEquals("note zombie", 0, elfPrpsinfo.getPrZomb());
>     assertEquals("note: nice", 0, elfPrpsinfo.getPrNice());
>     assertEquals("note: flags",8390144, elfPrpsinfo.getPrFlag());  //0x00800600
>     assertEquals("note: uid", 500, elfPrpsinfo.getPrUid());
>     assertEquals("note: gid", 100, elfPrpsinfo.getPrGid());
>     assertEquals("note: pid", 31497, elfPrpsinfo.getPrPid());
>     assertEquals("note: ppid", 20765, elfPrpsinfo.getPrPpid());
>     assertEquals("note: pgrp", 31497, elfPrpsinfo.getPrPgrp());
>     assertEquals("note: sid", 20765, elfPrpsinfo.getPrSid());
>     assertEquals("note: fname","a.out", elfPrpsinfo.getPrFname());
>     assertEquals("note: args","./a.out ", elfPrpsinfo.getPrPsargs());
> 
>   }
> 
>   /**
>    * Test Prstatus  note info. Read the note data segment, pass it to
>    * ElfPrstatus to find the relative pstatus data, and parse. 
>    *
>    */
> 
>   public void testElfCorePrstatusNotes () throws ElfException,  ElfFileException
>   {
> 
>     // Matched against eu-read -n on the core file.
>     // XXX: This tests need an x86_64 core file, as well.
> 
>     // Note segment of 472 bytes at offset 0x1f4:
>     //  Owner          Data size  Type
>     //  CORE                 144  PRSTATUS
>     //    SIGINFO:  signo: 6, code = 0, errno = 0
>     //    signal: 6, pending: 00000000, holding:        0
>     //    pid: 31497, ppid = 20765, pgrp = 31497, sid = 20765
>     //     utime:      0.000000s,  stime:      0.000000s
>     //    cutime:      0.000000s, cstime:      0.000000s
>     //    eax: 00000000  ebx: 00007b09  ecx: 00007b09  edx: 00000006
>     //    esi: bff0284c  edi: 00b2cff4  ebp: bff027ac  esp: bff02794
>     //    eip: 00170410  eflags: 00000246  original eax: 0000010e
>     //    cs: 0073  ds: 007b  es: 007b  fs: 0000  gs: 0033  ss: 007b
> 
>     Elf testElf = new Elf (new File (Config.getPkgDataDir (), "test-core")
> 			   .getAbsolutePath (), ElfCommand.ELF_C_READ);
>     assertEquals(testElf.getKind(), ElfKind.ELF_K_ELF);
>     assertEquals(testElf.getBase(), 0);
> 
>     ElfData noteData = findNoteSegment(testElf);
> 
>     ElfPrstatus threads =   new ElfPrstatus(noteData);
> 
>     // Should only be one thread in this core file.
>     assertEquals("Number of  threads",1,threads.getThreadData().size());
> 
>     ElfPrstatus elfPrstatusInfo = (ElfPrstatus) threads.getThreadData().get(0);
>     
>     assertEquals("note: Sig Info -> Sig No",6,elfPrstatusInfo.getPrInfoSiSigno());
>     assertEquals("note: Sig Info -> Sig code",0,elfPrstatusInfo.getPrInfoSiCode());
>     assertEquals("note: Sig Info -> Sig errno",0,elfPrstatusInfo.getPrInfoSiErrno());
>     assertEquals("note: Current signal",6,elfPrstatusInfo.getPrCurSig());
>     assertEquals("note: Pending signal",0,elfPrstatusInfo.getPrSigPending());
>     assertEquals("note: Holding signal",0,elfPrstatusInfo.getPrSigHold());
>     assertEquals("note: Pid",31497,elfPrstatusInfo.getPrPid());
>     assertEquals("note: PPid",20765,elfPrstatusInfo.getPrPpid());
>     assertEquals("note: Pgrp",31497,elfPrstatusInfo.getPrPgrp());
>     assertEquals("note: Sid",20765,elfPrstatusInfo.getPrSid());
> 
>     // Order of registers in the raw buffer is defined in 
>     // usr/include/asm.user.h
>     // ebc, ecx, edx, esi, edi and so on.
>     //
>     //	long ebx, ecx, edx, esi, edi, ebp, eax;
>     //  unsigned short ds, __ds, es, __es;
>     //  unsigned short fs, __fs, gs, __gs;
>     //  long orig_eax, eip;
>     //  unsigned short cs, __cs;
>     //  long eflags, esp;
>     //  unsigned short ss, __ss;
> 
>     // Get raw register buffer.
>     byte[] rawRegisterBuffer = elfPrstatusInfo.getRawCoreRegisters();
> 
>     assertEquals("note: ebx",0x00007b09,
> 		 getRegisterByOffset(rawRegisterBuffer,0,4,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: ecx",0x00007b09,
> 		 getRegisterByOffset(rawRegisterBuffer,4,4,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: edx",0x00000006,
> 		 getRegisterByOffset(rawRegisterBuffer,8,4,ByteOrder.LITTLE_ENDIAN));
> 
>     BigInteger tmp = new BigInteger("3220187212"); //0xbff0284c
>     assertEquals("note: esi",tmp.longValue(), 
> 		 getRegisterByOffset(rawRegisterBuffer,12,4,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: edi",0x00b2cff4,
> 		 getRegisterByOffset(rawRegisterBuffer,16,4,ByteOrder.LITTLE_ENDIAN));
> 
>     tmp = new BigInteger("3220187052"); //0xbff027ac
>     assertEquals("note: ebp",tmp.longValue(),
> 		 getRegisterByOffset(rawRegisterBuffer,20,4,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: eax",0x00000000,
> 		 getRegisterByOffset(rawRegisterBuffer,24,4,ByteOrder.LITTLE_ENDIAN));
> 
>     assertEquals("note: ds",0x0000007b,
> 		 getRegisterByOffset(rawRegisterBuffer,28,2,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: es",0x0000007b,
> 		 getRegisterByOffset(rawRegisterBuffer,32,2,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: fs",0x00000000,
> 		 getRegisterByOffset(rawRegisterBuffer,36,2,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: gs",0x00000033,
> 		 getRegisterByOffset(rawRegisterBuffer,40,2,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: oeax",0x0000010e,
> 		 getRegisterByOffset(rawRegisterBuffer,44,4,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: eip",0x00170410,
> 		 getRegisterByOffset(rawRegisterBuffer,48,4,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: cs",0x00000073,
> 		 getRegisterByOffset(rawRegisterBuffer,52,4,ByteOrder.LITTLE_ENDIAN));
>     assertEquals("note: eflags",0x00000246,
> 		 getRegisterByOffset(rawRegisterBuffer,56,4,ByteOrder.LITTLE_ENDIAN));
> 
>     tmp = new BigInteger("3220187028");
>     assertEquals("note: esp",tmp.longValue(),
> 		 getRegisterByOffset(rawRegisterBuffer,60,4,ByteOrder.LITTLE_ENDIAN));
> 
>   }
> 
>   /**
>    * Test PrAuxv  note info. Read the note data segment, pass it to
>    * ElfPrAuxv to find the relative pstatus data, and parse. 
>    *
>    */
> 
>   public void testElfCorePrAuxvNotes () throws ElfException,
>     ElfFileException 
>   {
> 
>     Elf testElf = new Elf (new File (Config.getPkgDataDir (), "test-core")
> 			   .getAbsolutePath (), ElfCommand.ELF_C_READ);
>     assertEquals(testElf.getKind(), ElfKind.ELF_K_ELF);
>     assertEquals(testElf.getBase(), 0);
> 
>     ElfData noteData = findNoteSegment(testElf);
> 
>     final ElfPrAuxv prAuxv = new ElfPrAuxv(noteData);
>     final int[] expectedIndex = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
>     final int[] expectedType = {32,33,16,6,17,3,4,5,7,8,9,11,12,13,14,23,15,0};
>     final BigInteger[] expectedVal = {new BigInteger("1508352",10),
> 				      new BigInteger("1507328",10), 				
> 				      new BigInteger("3219782655",10),						    	
> 				      new BigInteger("4096",10),
> 				      new BigInteger("100",10),
> 				      new BigInteger("134512692",10),
> 				      new BigInteger("32",10),
> 				      new BigInteger("7",10),
> 				      new BigInteger("0",10),
> 				      new BigInteger("0",10),
> 				      new BigInteger("134513376",10),
> 				      new BigInteger("500",10),
> 				      new BigInteger("500",10),
> 				      new BigInteger("100",10),
> 				      new BigInteger("100",10),
> 				      new BigInteger("0",10),
> 				      new BigInteger("3220187851",10),
> 				      new BigInteger("0",10)};
> 				
> 
>     AuxvBuilder builder = new AuxvBuilder()
>     {
> 
>       int auxvIndex=0;
>       public void buildBuffer (byte[] auxv)
>       {
>       }
> 
>       public void buildDimensions (int wordSize, boolean bigEndian, int length)
>       {
>       }
> 
>       public void buildAuxiliary (int index, int type, long val)
>       {
> 	// Test the entries in the core file against the entries
> 	// stored in the arrays
> 	assertEquals("AuxV Index "+auxvIndex,expectedIndex[auxvIndex],index);
> 	assertEquals("AuxV Type "+auxvIndex,expectedType[auxvIndex],type);
> 	assertEquals("AuxV Val "+auxvIndex,expectedVal[auxvIndex],new BigInteger("" + val, 10));
> 	auxvIndex++;
>       }
>     };
>     builder.construct(prAuxv.getAuxvBuffer());
> 
> 
205a422,486
>   // Copied from frysk-core/Register.java and reused here.
>   // Does this really not exist somewhere else?
>   private static void reverseArray(byte[] array) 
>   {
>     for (int left = 0, right = array.length - 1; left < right; left++, right--)
>       {
> 	byte temp = array[right];
> 	array[right] = array[left];
> 	array[left] = temp;
>       }
>   }
> 
>   /**
>    * Helper routine that given a buffer, offset and length returns a
>    * register value as a long
>    */
>   private long getRegisterByOffset(byte[] buffer, int offset, int length, ByteOrder endian)
>   {
>     // Wrap buffer.
>     ByteBuffer regBuffer = ByteBuffer.wrap(buffer);
>     regBuffer.order(endian);
>     long val = 0;
>     byte[] regBytes = new byte[length];
>     
>     // Get the bytes at the offset and length, and 
>     // reverse if necessary.
>     
>     regBuffer.position(offset);
>     regBuffer.get(regBytes, 0,length);
>     if (regBuffer.order() == ByteOrder.LITTLE_ENDIAN)
>       reverseArray(regBytes);
> 
>     // Convert byte array to long value.
>     for (int i = 0; i < length; i++) 
> 	val = val << 8 | (regBytes[i] & 0xff);
> 
>     return val;
>   }
>   
>   /**
>    * Helper routine that give an Elf object, find the
>    * note segment and returns the contents in ElfData
>    */
>   private ElfData findNoteSegment(Elf testElf) throws ElfException, ElfFileException
>   {
>     // Get Elf Header.
>     ElfEHeader eHeader = testElf.getEHeader();
>     ElfData noteData = null;
>     
>     // Get number of program header entries.
>     long phSize = eHeader.phnum;
>     for (int i=0; i<phSize; i++)
>       {
> 	// Test if pheader is of types notes..
> 	ElfPHeader pHeader = testElf.getPHeader(i);
> 	if (pHeader.type == ElfPHeader.PTYPE_NOTE)
> 	  {
> 	    // if so, copy, break an leave.
> 	    noteData = testElf.getRawData(pHeader.offset,pHeader.filesz);
> 	    break;
> 	  }
>       }
>     
>     return noteData;
>   }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]