public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
* fcore status
@ 2006-10-15 21:48 Phil Muldoon
  2006-10-16 13:00 ` Yong Zheng
  0 siblings, 1 reply; 14+ messages in thread
From: Phil Muldoon @ 2006-10-15 21:48 UTC (permalink / raw)
  To: Frysk Hackers

I've updated FCore and relevant sections of the Java elf bindings as shown by the Changelog entries below.

FCore utility class core files now have a complete elf header, program segment header, section string table, section and corresponding data. It does not have Notes yet, that's for the coming week. So  "basic" core files can be produced. There are buckets of caveats/bugs, but will get to those later.

For posterity, here is a little run down of how core files are right now:

There seems to be two ways to create basic core files:

- Do as the kernel appears to do, construct the elf header, construct the program header table, notes, and dump the relevant maps directly after that. The kernel does not use libelf, and does this manually.

- Libelf (and gcore). Construct the elf header, construct the program header table, notes, section string table, section headers and elf_data structs in there.

The former (kernel) is simpler, but you have to do the data dumping yourself without libelf. You could use libelf to construct the headers, but after that you are on your own (and would have to back-update the headers with proper offsets post dump).

If you choose to do it via libelf, the only elf data structure (Elf_Data) to hold raw data belongs to the sections api, and therefore you have to dump into sections and map them back to the program header. This appears to be exactly the way gdb does it (except gdb uses bfd, and fcore uses direct elf bindings). I really did not want to lose the large amount of lib elf abstractions, and this seemed to be the best way to maintain maximum libelf compatibility. Ultimately, I'm not 100% swayed on either method, but the libelf method will work for now.

Caveats:

- MapsBuilder seems to sometimes not produce complete map tables from /proc/$$/map
- fcore writes *all* maps right now, that is for debugging purposes
- large core file train wreck. I suspect as mixing ints (byte[] arrays size) with long (MapsBuilder api), with ints (inua.eio.ByteBuffer get parameters), we will smash on huge core files.
- Task.getMemory() only seems to map up the maximum for 32 bit architectures?
- large core file train wreck * 2: some elf headers don't match their corresponding Java types. Will fix these.
- I set the EI_CLASS size to either ELFCLASS32 or ELFCLASS64 depending on the architecture, but on my IA32 box it always seems to revert to ELFCLASS64. (This messes up some sections table entries on 32 bit)
- Arch tests. I have a horrible arch check in fcore. It's not a question of if it will fail, but when. I need to ISA to tell me what machine it is (PPC64, IA32 and so on), and the size 32/64 bit, 32 on 64 bit. Can anyone advise?
- Program header offsets are not correctly written back after the section Elf_Data is written. Bug.
- Program header alignments are not working.

I'll create bugs for all those.

The Elf bindings changes are mainly additions to the section ElfData and ElfSection API. What exited in the existing bindings only supported reading functions, and not updating back to the native elf structs, and writing those to disk

 

2006-10-15  Phil Muldoon  <pmuldoon@redhat.com>
	
	* frysk/util/FCore.java (write_elf_file): Rewritten with these changes:
	- Build elf header manually with full complement of data.
	- Build string table section/section header and update to disk.
	- (Still) Ugly arch test hack.
	* frysk/util/FCore.java (FCore.MapsCounter): Renamed.
	* frysk/util/FCore.java (FCore.CoreMapsBuilder): Renamed.
	(buildMap):Rewritten with these changes:
	- build section headers
	- define section headers in concert with program headers.
	- build section from header, create contextual Elf_Data class, and
	byte copy maps data.



2006-10-15  Phil Muldoon  <pmuldoon@redhat.com>
	
	* Elf.java (getElfVersion): New function.
	(initializeCoreHeader): Remove. Deprecated.
	* ElfData.java (setBuffer): New function. Set elf buffer.
	(setType): New.
	(setSize): New.
	(setOffset): New.
	* ElfEHeader.java: Added Data, Class and Type constants.
	* ElfPHeader.java : Added Type constants.
	* ElfSection (update):  New Function. Update class
	back to native elf header.
	* ElfSectionHeader.java: Changed constructor access to public.
	* ElfSectionHeaderTypes.java : New.
	
	* cni/Elf.cxx (elf_init_core_header): Removed. Deprecated.
	* cni/ElfData.cxx (elf_data_set_buff): New function.
	(elf_data_set_type): Ditto.
	(elf_data_set_version): Ditto.
	(elf_data_set_size): Ditto.
	(elf_data_set_off): Ditto.
	(elf_data_set_align): Ditto.
	* cni/ElfSection.cxx:
	(ElfSection): Check if ehdr->e_shstrndx exists before
	attempting to calculate name from string table.
	(elf_updateshdr): New.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-15 21:48 fcore status Phil Muldoon
@ 2006-10-16 13:00 ` Yong Zheng
  2006-10-16 13:18   ` Phil Muldoon
  0 siblings, 1 reply; 14+ messages in thread
From: Yong Zheng @ 2006-10-16 13:00 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Frysk Hackers

On Sun, 2006-10-15 at 16:47 -0500, Phil Muldoon wrote: 
> I've updated FCore and relevant sections of the Java elf bindings as shown by the Changelog entries below.
> 
> FCore utility class core files now have a complete elf header, program segment header, section string table, section and corresponding data. It does not have Notes yet, that's for the coming week. So  "basic" core files can be produced. There are buckets of caveats/bugs, but will get to those later.
> 
Phil, I notice one issue. In gdb, one map whose is unwritable won't be
dumped out by gcore. However, in our fcore, it is dumped out. I'm not
sure whether we should rethink of this. 

On one hand, if one map unwritable is dumped out, it will make the core
file larger. In gdb, it consider the map unwritable can be got from the
executable program in disk, which is the reason why gcore doesn't dump
out such kind of maps. For some application with large size, this will
dump out a large core file! 

On the other hand, if we dump out all entries in /proc/self/maps, we
maybe do more things on core file debugging than that gdb can do(now, we
must use gdb like this for core file debugging: gdb executable-file
core-file. And under such a circumstance we can't input step/next
commands. If we dump all, we maybe provide support for running step/next
commands in core file debugging. But it's just maybe.)

So what should we choose, dump out one map unwritable or not?

> Caveats:
> 
> - MapsBuilder seems to sometimes not produce complete map tables from /proc/$$/map

Some items in maps table are filtered out! Those items who are unreadable won't be built, such as 
[vdso] item in /proc/self/maps. So sometimes you will get one uncomplete map tables. But this doesn't matter.

> - I suspect as mixing ints (byte[] arrays size) with long (MapsBuilder api), with ints (inua.eio.ByteBuffer get parameters), we will smash on huge core files.
If you can detail this, it's very appreciated!

> - Task.getMemory() only seems to map up the maximum for 32 bit architectures?
I also notice this. But in PtraceByteBuffer.cxx, there's some comments about "maxOffset". The maxOffset isnot
checked in ByteBuffer interface. So it won't bring trouble to us now. 

Phil, we should add some new class for arch-dependent operations on ELF header and PT_NOTE dumping out. I hope I can post one
patches and have some discussion based on it.

Best regards
Yong Zheng

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-16 13:00 ` Yong Zheng
@ 2006-10-16 13:18   ` Phil Muldoon
  2006-10-17  2:39     ` Yong Zheng
  2006-10-17 17:06     ` Andrew Cagney
  0 siblings, 2 replies; 14+ messages in thread
From: Phil Muldoon @ 2006-10-16 13:18 UTC (permalink / raw)
  To: Yong Zheng; +Cc: Frysk Hackers

>
> Phil, I notice one issue. In gdb, one map whose is unwritable won't be
> dumped out by gcore. However, in our fcore, it is dumped out. I'm not
> sure whether we should rethink of this. 
>
> On one hand, if one map unwritable is dumped out, it will make the core
> file larger. In gdb, it consider the map unwritable can be got from the
> executable program in disk, which is the reason why gcore doesn't dump
> out such kind of maps. For some application with large size, this will
> dump out a large core file! 
>   
> On the other hand, if we dump out all entries in /proc/self/maps, we
> maybe do more things on core file debugging than that gdb can do(now, we
> must use gdb like this for core file debugging: gdb executable-file
> core-file. And under such a circumstance we can't input step/next
> commands. If we dump all, we maybe provide support for running step/next
> commands in core file debugging. But it's just maybe.)
>   

Right now fcore dumps out all maps it can ( this is for debugging more 
than practice) and we can easily tweak what maps to dump in the future 
by adjusting CoreMapsBuilder. It's just a matter of reading the flags 
really, and deciding on a map by map basis.
> So what should we choose, dump out one map unwritable or not?
>   

I think ultimately we should only dump out maps that are only writable, 
but to change it one way or the other is just an additional if () 
condition, so very easy to alter.
>   
>> Caveats:
>>
>> - MapsBuilder seems to sometimes not produce complete map tables from /proc/$$/map
>>     
>
> Some items in maps table are filtered out! Those items who are unreadable won't be built, such as 
> [vdso] item in /proc/self/maps. So sometimes you will get one uncomplete map tables. But this doesn't matter.
>   

It seems worse than that. If you dump gedit, there are a lot of maps 
that we never see (resulting in a large core file for gcore,  and a much 
much smaller one for fcore). I'm still not sure where this problem is 
yet, of if it even is a problem.
>   
>> - I suspect as mixing ints (byte[] arrays size) with long (MapsBuilder api), with ints (inua.eio.ByteBuffer get parameters), we will smash on huge core files.
>>     
> If you can detail this, it's very appreciated!
>   
I'm not sure if this will be an issue, need to talk to Andrew. On a 
large scale architecture, if the core file map > byte[int] max then it 
might be an issue.

>> - Task.getMemory() only seems to map up the maximum for 32 bit architectures?
>>     
> I also notice this. But in PtraceByteBuffer.cxx, there's some comments about "maxOffset". The maxOffset isnot
> checked in ByteBuffer interface. So it won't bring trouble to us now. 
>
> Phil, we should add some new class for arch-dependent operations on ELF header and PT_NOTE dumping out. I hope I can post one
> patches and have some discussion based on it.
>   

I do all my operations on the header via gelf which is arch dependent, 
so we are arch dependent on all elf operations?

Yes, I totally agree on PT_NOTE arch dependent information if that is 
what you mean.

Regards

Phil


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-16 13:18   ` Phil Muldoon
@ 2006-10-17  2:39     ` Yong Zheng
  2006-10-17 23:14       ` Phil Muldoon
  2006-10-17 17:06     ` Andrew Cagney
  1 sibling, 1 reply; 14+ messages in thread
From: Yong Zheng @ 2006-10-17  2:39 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Frysk Hackers

[-- Attachment #1: Type: text/plain, Size: 765 bytes --]

On Mon, 2006-10-16 at 08:17 -0500, Phil Muldoon wrote:

> I do all my operations on the header via gelf which is arch dependent, 
> so we are arch dependent on all elf operations?
> Yes, I totally agree on PT_NOTE arch dependent information if that is 
> what you mean.

Yes, fcore do all operations on the header via gelf. But some
information, such as little-endian, big-endian, including PT_NOTE
section we need to fill is still arch depentent! So it's necessary for
us to refactor fcore code in order to dump out PT_NOTE and further
operations on core file. So I write one small patch to show how we could
refactor fcore codes. Its main purpose is for our discussion, not for
checking in, so I just write one general code framework.

Best regards

Yong Zheng



[-- Attachment #2: fcore-refactor-20061017.patch --]
[-- Type: text/x-patch, Size: 8523 bytes --]

Index: frysk-core/frysk/util/FCore.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/util/FCore.java,v
retrieving revision 1.5
diff -u -r1.5 FCore.java
--- frysk-core/frysk/util/FCore.java	16 Oct 2006 21:27:28 -0000	1.5
+++ frysk-core/frysk/util/FCore.java	17 Oct 2006 02:17:36 -0000
@@ -75,6 +75,8 @@
 import frysk.proc.Task;
 import frysk.proc.TaskException;
 import frysk.sys.proc.MapsBuilder;
+import frysk.util.core.LinuxElfCoreFiller;
+import frysk.util.core.LinuxElfCoreFillerFactory;
 import gnu.classpath.tools.getopt.FileArgumentCallback;
 import gnu.classpath.tools.getopt.Option;
 import gnu.classpath.tools.getopt.OptionException;
@@ -238,49 +240,9 @@
 		local_elf = new Elf(System.getProperty("user.dir") + "/fcore."
 				+ proc.getPid(), ElfCommand.ELF_C_WRITE, true);
 
-		// Create the elf header
-		local_elf.createNewEHeader();
-		ElfEHeader elf_header = local_elf.getEHeader();
-		
-		Isa arch = proc.getMainTask().getIsa();		
-		ByteOrder order = arch.getByteOrder();
-		
-		if (order == inua.eio.ByteOrder.BIG_ENDIAN)
-			elf_header.ident[5] = ElfEHeader.PHEADER_ELFDATA2MSB;
-		else
-			elf_header.ident[5] = ElfEHeader.PHEADER_ELFDATA2LSB;
-		
-		// Version
-		elf_header.ident[6] = (byte) local_elf.getElfVersion();
-		
-		// EXEC for now, ET_CORE later
-		elf_header.type = ElfEHeader.PHEADER_ET_EXEC;
-		
-		// Version
-		elf_header.version = local_elf.getElfVersion();
-		
-		// String Index
-		elf_header.shstrndx = 1;
-		
-		// XXX: I hate this, there must be a better way to get architecture than this ugly, ugly hack
-		String arch_test = arch.toString();
-		String type = arch_test.substring(0, arch_test.lastIndexOf("@"));
-		
-		if (type.equals("frysk.proc.LinuxIa32")) {
-			elf_header.machine = ElfEMachine.EM_386;
-			elf_header.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
-		}
-		if (type.equals("frysk.proc.LinuxPPC64")) {
-			elf_header.machine = ElfEMachine.EM_PPC64;
-			elf_header.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
-		}
-		if (type.equals("frysk.proc.LinuxX8664")) {
-			elf_header.machine = ElfEMachine.EM_X86_64;
-			elf_header.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
-		}
-		
-		local_elf.updateEHeader(elf_header);
-
+		LinuxElfCoreFiller coreFiller = LinuxElfCoreFillerFactory.getElfCoreFiller(proc);
+		coreFiller.fillElfHeader(local_elf);
+        
 		// Count maps
 		final MapsCounter counter = new MapsCounter();
 		counter.construct(proc.getMainTask().getTid());
@@ -320,7 +282,7 @@
 		stringSection.update(stringSectionHeader);
 		
 		// Repoint shstrndx to string segment number
-		elf_header = local_elf.getEHeader();
+		ElfEHeader elf_header = local_elf.getEHeader();
 		elf_header.shstrndx = (int) stringSection.getIndex();
 		local_elf.updateEHeader(elf_header);
 
@@ -450,7 +412,6 @@
 				data.setType(0);
 				section.update(sectionHeader);
 				
-				
 				// inefficient to do this for each map, but alternative is to rerun another builder
 				// so for right now, less of two evil. Needs a rethinks.
 				final long i = local_elf.update(ElfCommand.ELF_C_NULL);
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/util/core/LinuxElfCoreFillerFactory.java	2006-10-17 10:15:58.000000000 +0800
@@ -0,0 +1,38 @@
+package frysk.util.core;
+
+import java.util.logging.Level;
+
+import lib.elf.Elf;
+import lib.elf.ElfCommand;
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfException;
+import lib.elf.ElfFileException;
+import frysk.proc.Isa;
+import frysk.proc.LinuxIa32;
+import frysk.proc.LinuxPPC64;
+import frysk.proc.LinuxX8664;
+import frysk.proc.Proc;
+import frysk.proc.Task;
+import frysk.proc.TaskException;
+
+public class LinuxElfCoreFillerFactory
+{
+
+  public static LinuxElfCoreFiller getElfCoreFiller(Proc proc) 
+    throws TaskException
+  {
+    Isa procIsa = proc.getMainTask().getIsa();     
+    
+    //XXX if more ISA is available, add them here.
+    //XXX LinuxIa32On64 and LinuxPPC32On64 should be added.
+    if (procIsa instanceof LinuxIa32)
+      return new LinuxElfX86Core(proc);
+    else if (procIsa instanceof LinuxX8664)
+      return new LinuxElfX8664Core(proc);
+    else if (procIsa instanceof LinuxPPC64)
+      return new LinuxElfPPC64Core(proc);
+    else
+      return null;
+  }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/util/core/LinuxElfCoreFiller.java	2006-10-17 10:16:03.000000000 +0800
@@ -0,0 +1,66 @@
+package frysk.util.core;
+
+import inua.eio.ByteOrder;
+import frysk.proc.Isa;
+import frysk.proc.Proc;
+import frysk.proc.TaskException;
+import lib.elf.Elf;
+import lib.elf.ElfEHeader;
+import lib.elf.ElfSection;
+
+public abstract class LinuxElfCoreFiller
+{
+  Proc proc = null;
+  
+  public LinuxElfCoreFiller(Proc proc)
+  {
+    this.proc = proc;
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader)
+  throws TaskException
+  {
+    Isa arch = proc.getMainTask().getIsa();     
+    ByteOrder order = arch.getByteOrder();
+    
+    if (order == ByteOrder.BIG_ENDIAN)
+        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2MSB;
+    else
+        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2LSB;  
+  }
+  
+  public abstract void fillENoteSection(ElfSection noteSection);
+  
+  /**
+   * Fill the ELF header information for the ELF core file.
+   * 
+   * @param elfCore
+   * @param proc
+   * @return null if fail to construct ELF header.
+   */
+  public ElfEHeader fillElfHeader(Elf elfCore) throws TaskException
+  {
+    //XXX: construct ELF header for elf object. 
+    elfCore.createNewEHeader();
+    ElfEHeader elf_header = elfCore.getEHeader();
+    
+    fillEHArchInfo(elf_header);
+    // Version
+    elf_header.ident[6] = (byte) elfCore.getElfVersion();
+    
+    // EXEC for now, ET_CORE later
+    elf_header.type = ElfEHeader.PHEADER_ET_EXEC;
+    //elf_header.type = ElfEHeader.PHEADER_ET_CORE;
+    
+    // Version
+    elf_header.version = elfCore.getElfVersion();
+    
+    // String Index
+    elf_header.shstrndx = 1;
+        
+    elfCore.updateEHeader(elf_header);
+    
+    return elf_header;
+  }
+}
+
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/util/core/LinuxElfPPC64Core.java	2006-10-17 10:16:08.000000000 +0800
@@ -0,0 +1,29 @@
+package frysk.util.core;
+
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfSection;
+import frysk.proc.Proc;
+import frysk.proc.TaskException;
+
+public class LinuxElfPPC64Core extends LinuxElfCoreFiller
+{
+  public LinuxElfPPC64Core(Proc proc)
+  {
+    super(proc);
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader)
+  throws TaskException
+  {
+    super.fillEHArchInfo(elfHeader);
+    
+    elfHeader.machine = ElfEMachine.EM_PPC64;
+    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    //XXX: arch-dependent. 
+  }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/util/core/LinuxElfX8664Core.java	2006-10-17 10:16:15.000000000 +0800
@@ -0,0 +1,30 @@
+package frysk.util.core;
+
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfSection;
+import frysk.proc.Proc;
+import frysk.proc.TaskException;
+
+public class LinuxElfX8664Core extends LinuxElfCoreFiller
+{
+
+  public LinuxElfX8664Core(Proc proc)
+  {
+    super(proc);
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader)
+  throws TaskException
+  {
+    super.fillEHArchInfo(elfHeader);
+    
+    elfHeader.machine = ElfEMachine.EM_X86_64;
+    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    //XXX: arch-dependent. 
+  }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/util/core/LinuxElfX86Core.java	2006-10-17 10:16:20.000000000 +0800
@@ -0,0 +1,29 @@
+package frysk.util.core;
+
+import frysk.proc.Proc;
+import frysk.proc.TaskException;
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfSection;
+
+public class LinuxElfX86Core extends LinuxElfCoreFiller
+{
+  public LinuxElfX86Core(Proc proc)
+  {
+    super(proc);
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader) throws TaskException
+  {
+     
+    super.fillEHArchInfo(elfHeader);
+    
+    elfHeader.machine = ElfEMachine.EM_386;
+    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    //XXX: arch-dependent. 
+  }
+}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-16 13:18   ` Phil Muldoon
  2006-10-17  2:39     ` Yong Zheng
@ 2006-10-17 17:06     ` Andrew Cagney
  1 sibling, 0 replies; 14+ messages in thread
From: Andrew Cagney @ 2006-10-17 17:06 UTC (permalink / raw)
  To: Phil Muldoon, Yong Zheng, Tim Moore; +Cc: Frysk Hackers

Phil Muldoon wrote:
>
>>  
>>> - I suspect as mixing ints (byte[] arrays size) with long 
>>> (MapsBuilder api), with ints (inua.eio.ByteBuffer get parameters), 
>>> we will smash on huge core files.
>>>     
>> If you can detail this, it's very appreciated!
>>   
> I'm not sure if this will be an issue, need to talk to Andrew. On a 
> large scale architecture, if the core file map > byte[int] max then it 
> might be an issue. 
Yes, there will be problems there.  For instance, there continues to be 
a long-standing bug with inua.eio not quite being 64-bit (it is 63-bit).

Andrew

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-17  2:39     ` Yong Zheng
@ 2006-10-17 23:14       ` Phil Muldoon
  2006-10-18 13:35         ` Yong Zheng
  0 siblings, 1 reply; 14+ messages in thread
From: Phil Muldoon @ 2006-10-17 23:14 UTC (permalink / raw)
  To: Yong Zheng; +Cc: Frysk Hackers

Yong Zheng wrote:
> On Mon, 2006-10-16 at 08:17 -0500, Phil Muldoon wrote:
>
>   
>> I do all my operations on the header via gelf which is arch dependent, 
>> so we are arch dependent on all elf operations?
>> Yes, I totally agree on PT_NOTE arch dependent information if that is 
>> what you mean.
>>     
>
> Yes, fcore do all operations on the header via gelf. But some
> information, such as little-endian, big-endian, including PT_NOTE
> section we need to fill is still arch depentent! So it's necessary for
> us to refactor fcore code in order to dump out PT_NOTE and further
> operations on core file. 

Other than PTNOTE section (which will contain architecture dependent 
registers), the only arch dependent data is:

- word size
- LSB or MSB
- Machine name

All of the above are just setting byte values. So there is not a huge 
amount.  GElf helps a lot with its abstractions here.
> So I write one small patch to show how we could
> refactor fcore codes. 

I was hoping that the Isa factory based abstraction would already help 
here. OTOH, I like the idea you proposed here though I am wary of 
building factories (ours) on top of ISA's own.  However it really 
cleanly cuts the code up into arch dependent parts within the FCore 
code. So I agree we should go ahead and implement it down the line.

What I am doing today/this week is exposing the notes section to the 
core file. First thing I'll have to do is expose the notes structures to 
the Java bindings of Libelf, then build on the population of those 
structures. So I'll think on this some more during that time ;)

Regards

Phil

> Its main purpose is for our discussion, not for
> checking in, so I just write one general code framework.
>
> Best regards
>
> Yong Zheng
>
>
>   
> ------------------------------------------------------------------------
>
> Index: frysk-core/frysk/util/FCore.java
> ===================================================================
> RCS file: /cvs/frysk/frysk-core/frysk/util/FCore.java,v
> retrieving revision 1.5
> diff -u -r1.5 FCore.java
> --- frysk-core/frysk/util/FCore.java	16 Oct 2006 21:27:28 -0000	1.5
> +++ frysk-core/frysk/util/FCore.java	17 Oct 2006 02:17:36 -0000
> @@ -75,6 +75,8 @@
>  import frysk.proc.Task;
>  import frysk.proc.TaskException;
>  import frysk.sys.proc.MapsBuilder;
> +import frysk.util.core.LinuxElfCoreFiller;
> +import frysk.util.core.LinuxElfCoreFillerFactory;
>  import gnu.classpath.tools.getopt.FileArgumentCallback;
>  import gnu.classpath.tools.getopt.Option;
>  import gnu.classpath.tools.getopt.OptionException;
> @@ -238,49 +240,9 @@
>  		local_elf = new Elf(System.getProperty("user.dir") + "/fcore."
>  				+ proc.getPid(), ElfCommand.ELF_C_WRITE, true);
>  
> -		// Create the elf header
> -		local_elf.createNewEHeader();
> -		ElfEHeader elf_header = local_elf.getEHeader();
> -		
> -		Isa arch = proc.getMainTask().getIsa();		
> -		ByteOrder order = arch.getByteOrder();
> -		
> -		if (order == inua.eio.ByteOrder.BIG_ENDIAN)
> -			elf_header.ident[5] = ElfEHeader.PHEADER_ELFDATA2MSB;
> -		else
> -			elf_header.ident[5] = ElfEHeader.PHEADER_ELFDATA2LSB;
> -		
> -		// Version
> -		elf_header.ident[6] = (byte) local_elf.getElfVersion();
> -		
> -		// EXEC for now, ET_CORE later
> -		elf_header.type = ElfEHeader.PHEADER_ET_EXEC;
> -		
> -		// Version
> -		elf_header.version = local_elf.getElfVersion();
> -		
> -		// String Index
> -		elf_header.shstrndx = 1;
> -		
> -		// XXX: I hate this, there must be a better way to get architecture than this ugly, ugly hack
> -		String arch_test = arch.toString();
> -		String type = arch_test.substring(0, arch_test.lastIndexOf("@"));
> -		
> -		if (type.equals("frysk.proc.LinuxIa32")) {
> -			elf_header.machine = ElfEMachine.EM_386;
> -			elf_header.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
> -		}
> -		if (type.equals("frysk.proc.LinuxPPC64")) {
> -			elf_header.machine = ElfEMachine.EM_PPC64;
> -			elf_header.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
> -		}
> -		if (type.equals("frysk.proc.LinuxX8664")) {
> -			elf_header.machine = ElfEMachine.EM_X86_64;
> -			elf_header.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
> -		}
> -		
> -		local_elf.updateEHeader(elf_header);
> -
> +		LinuxElfCoreFiller coreFiller = LinuxElfCoreFillerFactory.getElfCoreFiller(proc);
> +		coreFiller.fillElfHeader(local_elf);
> +        
>  		// Count maps
>  		final MapsCounter counter = new MapsCounter();
>  		counter.construct(proc.getMainTask().getTid());
> @@ -320,7 +282,7 @@
>  		stringSection.update(stringSectionHeader);
>  		
>  		// Repoint shstrndx to string segment number
> -		elf_header = local_elf.getEHeader();
> +		ElfEHeader elf_header = local_elf.getEHeader();
>  		elf_header.shstrndx = (int) stringSection.getIndex();
>  		local_elf.updateEHeader(elf_header);
>  
> @@ -450,7 +412,6 @@
>  				data.setType(0);
>  				section.update(sectionHeader);
>  				
> -				
>  				// inefficient to do this for each map, but alternative is to rerun another builder
>  				// so for right now, less of two evil. Needs a rethinks.
>  				final long i = local_elf.update(ElfCommand.ELF_C_NULL);
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/util/core/LinuxElfCoreFillerFactory.java	2006-10-17 10:15:58.000000000 +0800
> @@ -0,0 +1,38 @@
> +package frysk.util.core;
> +
> +import java.util.logging.Level;
> +
> +import lib.elf.Elf;
> +import lib.elf.ElfCommand;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfException;
> +import lib.elf.ElfFileException;
> +import frysk.proc.Isa;
> +import frysk.proc.LinuxIa32;
> +import frysk.proc.LinuxPPC64;
> +import frysk.proc.LinuxX8664;
> +import frysk.proc.Proc;
> +import frysk.proc.Task;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfCoreFillerFactory
> +{
> +
> +  public static LinuxElfCoreFiller getElfCoreFiller(Proc proc) 
> +    throws TaskException
> +  {
> +    Isa procIsa = proc.getMainTask().getIsa();     
> +    
> +    //XXX if more ISA is available, add them here.
> +    //XXX LinuxIa32On64 and LinuxPPC32On64 should be added.
> +    if (procIsa instanceof LinuxIa32)
> +      return new LinuxElfX86Core(proc);
> +    else if (procIsa instanceof LinuxX8664)
> +      return new LinuxElfX8664Core(proc);
> +    else if (procIsa instanceof LinuxPPC64)
> +      return new LinuxElfPPC64Core(proc);
> +    else
> +      return null;
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/util/core/LinuxElfCoreFiller.java	2006-10-17 10:16:03.000000000 +0800
> @@ -0,0 +1,66 @@
> +package frysk.util.core;
> +
> +import inua.eio.ByteOrder;
> +import frysk.proc.Isa;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +import lib.elf.Elf;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfSection;
> +
> +public abstract class LinuxElfCoreFiller
> +{
> +  Proc proc = null;
> +  
> +  public LinuxElfCoreFiller(Proc proc)
> +  {
> +    this.proc = proc;
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    Isa arch = proc.getMainTask().getIsa();     
> +    ByteOrder order = arch.getByteOrder();
> +    
> +    if (order == ByteOrder.BIG_ENDIAN)
> +        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2MSB;
> +    else
> +        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2LSB;  
> +  }
> +  
> +  public abstract void fillENoteSection(ElfSection noteSection);
> +  
> +  /**
> +   * Fill the ELF header information for the ELF core file.
> +   * 
> +   * @param elfCore
> +   * @param proc
> +   * @return null if fail to construct ELF header.
> +   */
> +  public ElfEHeader fillElfHeader(Elf elfCore) throws TaskException
> +  {
> +    //XXX: construct ELF header for elf object. 
> +    elfCore.createNewEHeader();
> +    ElfEHeader elf_header = elfCore.getEHeader();
> +    
> +    fillEHArchInfo(elf_header);
> +    // Version
> +    elf_header.ident[6] = (byte) elfCore.getElfVersion();
> +    
> +    // EXEC for now, ET_CORE later
> +    elf_header.type = ElfEHeader.PHEADER_ET_EXEC;
> +    //elf_header.type = ElfEHeader.PHEADER_ET_CORE;
> +    
> +    // Version
> +    elf_header.version = elfCore.getElfVersion();
> +    
> +    // String Index
> +    elf_header.shstrndx = 1;
> +        
> +    elfCore.updateEHeader(elf_header);
> +    
> +    return elf_header;
> +  }
> +}
> +
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/util/core/LinuxElfPPC64Core.java	2006-10-17 10:16:08.000000000 +0800
> @@ -0,0 +1,29 @@
> +package frysk.util.core;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfPPC64Core extends LinuxElfCoreFiller
> +{
> +  public LinuxElfPPC64Core(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_PPC64;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/util/core/LinuxElfX8664Core.java	2006-10-17 10:16:15.000000000 +0800
> @@ -0,0 +1,30 @@
> +package frysk.util.core;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfX8664Core extends LinuxElfCoreFiller
> +{
> +
> +  public LinuxElfX8664Core(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_X86_64;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/util/core/LinuxElfX86Core.java	2006-10-17 10:16:20.000000000 +0800
> @@ -0,0 +1,29 @@
> +package frysk.util.core;
> +
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +
> +public class LinuxElfX86Core extends LinuxElfCoreFiller
> +{
> +  public LinuxElfX86Core(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader) throws TaskException
> +  {
> +     
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_386;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
>   

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-17 23:14       ` Phil Muldoon
@ 2006-10-18 13:35         ` Yong Zheng
  2006-10-18 14:37           ` Phil Muldoon
  2006-10-18 15:55           ` Phil Muldoon
  0 siblings, 2 replies; 14+ messages in thread
From: Yong Zheng @ 2006-10-18 13:35 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Frysk Hackers

[-- Attachment #1: Type: text/plain, Size: 1097 bytes --]


> I was hoping that the Isa factory based abstraction would already help 
> here. OTOH, I like the idea you proposed here though I am wary of 
> building factories (ours) on top of ISA's own.  However it really 
> cleanly cuts the code up into arch dependent parts within the FCore 
> code. So I agree we should go ahead and implement it down the line.
> 
> What I am doing today/this week is exposing the notes section to the 
> core file. First thing I'll have to do is expose the notes structures to 
> the Java bindings of Libelf, then build on the population of those 
> structures. So I'll think on this some more during that time ;)
> 
> Regards
> 
> Phil
> 

Phil, when I try to construct prpsinfo, there's no any definition in
elfutils package. So I have to use <linux/elfcore.h> for java binding.
And at the sametime, I refactor the arch-dependent code on CORE dumping
again in order to dump out prpsinfo more easily. I just write some
source codes now and post them out for comments from anybody who is
interested in this. 

Looking forward to your commends.

Best regards.
Yong Zheng

[-- Attachment #2: fcore-experimental-1017.patch --]
[-- Type: text/x-patch, Size: 28702 bytes --]

--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-imports/lib/elf/ElfNhdr.java	2006-10-18 21:02:35.000000000 +0800
@@ -0,0 +1,136 @@
+package lib.elf;
+
+public class ElfNhdr
+{
+  private long namesz = 4;
+  private long descsz = 0;
+  private int type = ElfNhdrType.NT_INVALID.getValue();
+  
+  private String name = "CORE";
+  private ElfNoteSectionEntry desc = null;
+  
+  public static abstract class ElfNoteSectionEntry
+  {
+    public abstract long getEntrySize();
+    public abstract long fillMemRegion(byte[] buffer, long startAddress);
+  }
+  
+  //XXX: no ElfNhdr struct in elfutils package now(2006-10-18).
+  //private long pointer;
+  
+  public ElfNhdr()
+  {
+
+  }
+  
+  public String getName()
+  {
+    return this.name;
+  }
+  public long getNameSize()
+  {
+    return this.namesz;
+  }
+  public void setName(String nhdrName)
+  {
+    if (null == nhdrName)
+      return;
+    
+    this.name = nhdrName;
+    this.namesz = nhdrName.length();
+  }
+  
+  public ElfNhdrType getNhdrType()
+  {
+    return ElfNhdrType.intern(this.type);
+  }
+  public ElfNoteSectionEntry getNhdrDesc()
+  {
+    return this.desc;
+  }
+  public long getDescSize()
+  {
+    return this.descsz;
+  }
+  
+  public void setNhdrDesc(ElfNhdrType nhdrType, ElfNoteSectionEntry nhdrDesc)
+  {
+    this.type = nhdrType.getValue();
+    this.desc = nhdrDesc;
+    this.descsz = nhdrDesc.getEntrySize();
+  }
+ 
+  /**
+   * Get the whole size of Nhdr (incluing the namesz and descsz).
+   * 
+   * @return
+   */
+  public long getNhdrEntrySize()
+  {
+    long size = 0;
+    
+    int nhdrSize = 0;
+    
+    nhdrSize = getNhdrSize();
+    if ((nhdrSize <= 0) ||
+        (namesz <= 0) || (descsz <= 0))
+      {
+        //Invalid object.
+        return size;
+      }
+    
+    size = nhdrSize + namesz + descsz;
+    
+    return size;
+  }
+ 
+  /**
+   * Just get the size of Nhdr struct.
+   * 
+   * @return
+   */
+  public native int getNhdrSize();
+  
+  protected native long fillNhdr(byte[] buffer, long startAddress);
+  protected native long fillNhdrName(byte[] buffer, long startAddress);
+  
+  /**
+   * Fill the region starting from startAddress in buffer according to this ElfNhdr object.
+   * 
+   * @param noteSecBuffer
+   * @param startAddress
+   * @return
+   */
+  public long fillMemRegion(byte[] buffer, long startAddress)
+  {
+    long nhdrEntrySize = 0;
+    
+    long fillSize = 0;
+    
+    fillSize = fillNhdr(buffer, startAddress);
+    if (fillSize != getNhdrSize())
+      {
+        //XXX: error occurred. throw excetpion?
+      }
+    
+    nhdrEntrySize += fillSize;
+    startAddress += fillSize;
+    fillSize = fillNhdrName(buffer, startAddress);
+    if (fillSize != this.namesz)
+      {
+        //XXX: error occurred. Throw exception?
+      }
+    
+    nhdrEntrySize += fillSize;
+    startAddress += fillSize;
+    fillSize = this.desc.fillMemRegion(buffer, startAddress);
+    if (fillSize != this.descsz)
+      {
+        //XXX: error occurred. Throw exception?
+      }
+    
+    nhdrEntrySize += fillSize;
+    return fillSize;
+  }
+  
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-imports/lib/elf/ElfNhdrType.java	2006-10-18 21:02:38.000000000 +0800
@@ -0,0 +1,70 @@
+package lib.elf;
+
+public class ElfNhdrType
+{
+    public static final ElfNhdrType NT_INVALID = new ElfNhdrType(0, "NT_INVALID");
+    public static final ElfNhdrType NT_PRSTATUS = new ElfNhdrType(1, "NT_PRSTATUS");
+    public static final ElfNhdrType NT_FPREGSET = new ElfNhdrType(2, "NT_FPREGSET");
+    public static final ElfNhdrType NT_PRPSINFO = new ElfNhdrType(3, "NT_PRPSINFO");
+    public static final ElfNhdrType NT_PRXREG = new ElfNhdrType(4, "NT_PRXREG");
+    
+    public static final ElfNhdrType NT_TASKSTRUCT = new ElfNhdrType(4, "NT_TASKSTRUCT");
+    public static final ElfNhdrType NT_PLATFORM = new ElfNhdrType(5, "NT_PLATFORM");
+    public static final ElfNhdrType NT_AUXV = new ElfNhdrType(6, "NT_AUXV");
+    public static final ElfNhdrType NT_GWINDOWS = new ElfNhdrType(7, "NT_GWINDOWS");
+    public static final ElfNhdrType NT_ASRS = new ElfNhdrType(8, "NT_ASRS");
+    
+    public static final ElfNhdrType NT_PSTATUS = new ElfNhdrType(10, "NT_PSTATUS");
+    public static final ElfNhdrType NT_PSINFO = new ElfNhdrType(13, "NT_PSINFO");
+    public static final ElfNhdrType NT_PRCRED = new ElfNhdrType(14, "NT_PRCRED");
+    
+    public static final ElfNhdrType NT_UTSNAME = new ElfNhdrType(15, "NT_UTSNAME");
+    public static final ElfNhdrType NT_LWPSTATUS = new ElfNhdrType(16, "NT_LWPSTATUS");
+    public static final ElfNhdrType NT_LWPSINFO = new ElfNhdrType(17, "NT_LWPSINFO");
+    public static final ElfNhdrType NT_PRFPXREG = new ElfNhdrType(20, "NT_PRFPXREG");
+    
+    private static ElfNhdrType[] types = {NT_INVALID, 
+        NT_PRSTATUS, NT_FPREGSET, NT_PRPSINFO, NT_PRXREG, NT_PLATFORM,
+        NT_AUXV, NT_GWINDOWS, NT_ASRS, NT_INVALID, NT_PSTATUS,
+        NT_INVALID, NT_INVALID, NT_PSINFO, NT_PRCRED, NT_UTSNAME,
+        NT_LWPSTATUS, NT_LWPSINFO, NT_INVALID, NT_INVALID, NT_PRFPXREG
+    };
+    
+    private int value = 0;
+    private String name = null;
+    
+    private ElfNhdrType(int value, String name)
+    {
+      this.value = value;
+      this.name = name;
+    }
+    
+    /**
+     * @return true iff the object is an ElfType and equal to this object
+     */
+    public boolean equals(Object obj)
+    {
+        if(!(obj instanceof ElfNhdrType))
+            return false;
+        
+        return ((ElfNhdrType)obj).value == this.value;
+    }
+    
+    public int getValue()
+    {
+        return this.value;
+    }
+    
+    public static ElfNhdrType intern(int type)
+    {
+      if ((type <= 0) || (type > (types.length - 1)))
+        return NT_INVALID;
+      else
+        return types[type];
+    }
+    
+    public String toString()
+    {
+        return this.name + "(" + this.value + ")";
+    }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-imports/lib/elf/ElfPrpsinfo.java	2006-10-18 21:02:55.000000000 +0800
@@ -0,0 +1,242 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, IBM Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+package lib.elf;
+
+public class ElfPrpsinfo extends ElfNhdr.ElfNoteSectionEntry
+{
+  private char pr_state;
+  private char pr_sname;
+  private char pr_zomb;
+  private char pr_nice;
+  
+  private long pr_flag;
+  
+  // on most platform, pr_uid is unsigned int. 
+  // In java, "int" it sigend, so we have to use long type.
+  private long pr_uid;
+  private long pr_gid;
+  
+  private int pr_pid;
+  private int pr_ppid;
+  private int pr_pgrp;
+  private int pr_sid;
+  
+  //XXX: the following two value must keep the same with the elfutils package.
+  public static int ELF_PRPSINFO_FNAME_MAXLEN = 16;
+  public static int ELF_PRPSINFO_ARGS_MAXLEN = 80;
+  
+  // filename of executable
+  private char[] pr_fname = new char[ELF_PRPSINFO_FNAME_MAXLEN];
+  
+  // initial part of arg list
+  private char[] pr_psargs = new char[ELF_PRPSINFO_ARGS_MAXLEN];
+  
+  private int pid;
+  
+  public ElfPrpsinfo(int pid)
+  {
+    this.pid = pid;
+  }
+  
+  public void setPrState(char state)
+  {
+    this.pr_state = state;
+  }
+  
+  public char getPrState()
+  {
+    return this.pr_state;
+  }
+  
+  public void setPrSname(char sname)
+  {
+    this.pr_sname = sname;
+  }
+  
+  public char getPrSname()
+  {
+    return this.pr_sname;
+  }
+  
+  public void setPrZomb(char zomb)
+  {
+    this.pr_zomb = zomb;
+  }
+  
+  public char getPrZomb()
+  {
+    return this.pr_zomb;
+  }
+  
+  public void setPrNice(char nice)
+  {
+    this.pr_nice = nice;
+  }
+  
+  public char getPrNice()
+  {
+    return this.pr_nice;
+  }
+  
+  public void setPrFlag(long flag)
+  {
+    this.pr_flag = flag;
+  }
+  
+  public long getPrFlag()
+  {
+    return this.pr_flag;
+  }
+  
+  public void setPrUid(long uid)
+  {
+    this.pr_uid = uid;
+  }
+  
+  public long getPrUid()
+  {
+    return this.pr_uid;
+  }
+  
+  public void setPrGid(long gid)
+  {
+    this.pr_gid = gid;
+  }
+  
+  public long getPrGid()
+  {
+    return this.pr_gid;
+  }
+  
+  public void setPrPid(int pid)
+  {
+    this.pr_pid = pid;
+  }
+  public int getPrPid()
+  {
+    return this.pr_pid;
+  }
+  
+  public void setPrPpid(int ppid)
+  {
+    this.pr_ppid = ppid;
+  }
+
+  public int getPrPpid()
+  {
+    return this.pr_ppid;
+  }
+  
+  public void setPrPgrp(int pgrp)
+  {
+    this.pr_pgrp = pgrp;
+  }
+  
+  public int setPrPgrp()
+  {
+    return this.pr_pgrp;
+  }
+  
+  public void setPrSid(int sid)
+  {
+    this.pr_sid = sid;
+  }
+
+  public int getPrSid()
+  {
+    return this.pr_sid;
+  }
+  
+  public void setPrFname(String fname)
+  {
+    if (null == fname)
+      return;
+    
+    int length = fname.length();
+    if (length < ELF_PRPSINFO_FNAME_MAXLEN)
+    {
+      this.pr_fname = fname.toCharArray();
+      this.pr_fname[length] = '0';
+    }
+    else
+      {
+        String name = fname.substring(0, ELF_PRPSINFO_FNAME_MAXLEN);
+        
+        this.pr_fname = name.toCharArray();
+        this.pr_fname[ELF_PRPSINFO_FNAME_MAXLEN] = '0';  
+      }
+  }
+  public char[] getPrFname()
+  {
+    return this.pr_fname;
+  }
+
+  public void getPrPsargs(String args)
+  {
+    if (null == args)
+      return;
+    
+    int length = args.length();
+    if (length < ELF_PRPSINFO_ARGS_MAXLEN)
+    {
+      this.pr_psargs = args.toCharArray();
+      this.pr_psargs[length] = '0';
+    }
+    else
+      {
+        String name = args.substring(0, ELF_PRPSINFO_ARGS_MAXLEN);
+        
+        this.pr_psargs = name.toCharArray();
+        this.pr_psargs[ELF_PRPSINFO_ARGS_MAXLEN] = '0';  
+      }
+  }
+  public char[] getPrPsargs()
+  {
+    return this.pr_psargs;
+  }
+  
+  public int getPid()
+  {
+    return this.pid;
+  }
+  
+  public native long getEntrySize();
+  public native long fillMemRegion(byte[] buffer, long startAddress);
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-imports/lib/elf/cni/ElfNhdr.cxx	2006-10-18 21:03:09.000000000 +0800
@@ -0,0 +1,102 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, IBM Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <gelf.h>
+#include <gcj/cni.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <gelf.h>
+
+#include "lib/elf/ElfNhdr.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+jint
+lib::elf::ElfNhdr::getNhdrSize()
+{
+	return sizeof(GElf_Nhdr);
+}
+
+jlong 
+lib::elf::ElfNhdr::fillNhdr(jbyteArray buffer, jlong startAddress)
+{
+	jbyte *bs = elements(buffer) + startAddress;
+	
+	errno = 0;
+	GElf_Nhdr *nhdr = (GElf_Nhdr *)malloc(sizeof(GElf_Nhdr));
+	
+	memset(nhdr, 0, sizeof(GElf_Nhdr));
+	
+	// copy the GElf_Nhdr struct into buffer.
+	//
+	nhdr->n_namesz = this->namesz;
+	nhdr->n_descsz = this->descsz;
+	
+	nhdr->n_type = this->type;
+	
+	memcpy(bs, nhdr, sizeof(GElf_Nhdr));
+	
+	return sizeof(GElf_Nhdr);
+}
+
+jlong 
+lib::elf::ElfNhdr::fillNhdrName(jbyteArray buffer, jlong startAddress)
+{
+	jlong size = 0; 
+	jbyte *bs = elements(buffer) + startAddress;
+
+	//Copy the name infor into buffer.
+	size = (jlong)JvGetStringUTFRegion(this->name, 0, this->namesz, (char *)bs);
+	return size;
+}
+ 
+  
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-imports/lib/elf/cni/ElfPrpsinfo.cxx	2006-10-18 21:03:15.000000000 +0800
@@ -0,0 +1,108 @@
+// This file is part of the program FRYSK.
+//
+// Copyright 2005, IBM Inc.
+//
+// FRYSK is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// FRYSK is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with FRYSK; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+// 
+// In addition, as a special exception, Red Hat, Inc. gives You the
+// additional right to link the code of FRYSK with code not covered
+// under the GNU General Public License ("Non-GPL Code") and to
+// distribute linked combinations including the two, subject to the
+// limitations in this paragraph. Non-GPL Code permitted under this
+// exception must only link to the code of FRYSK through those well
+// defined interfaces identified in the file named EXCEPTION found in
+// the source code files (the "Approved Interfaces"). The files of
+// Non-GPL Code may instantiate templates or use macros or inline
+// functions from the Approved Interfaces without causing the
+// resulting work to be covered by the GNU General Public
+// License. Only Red Hat, Inc. may make changes or additions to the
+// list of Approved Interfaces. You must obey the GNU General Public
+// License in all respects for all of the FRYSK code and other code
+// used in conjunction with FRYSK except the Non-GPL Code covered by
+// this exception. If you modify this file, you may extend this
+// exception to your version of the file, but you are not obligated to
+// do so. If you do not wish to provide this exception without
+// modification, you must delete this exception statement from your
+// version and license this file solely under the GPL without
+// exception.
+
+#include <linux/elfcore.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <gcj/cni.h>
+//#include <string.h>
+//#include <sys/types.h>
+//#include <sys/stat.h>
+//#include <fcntl.h>
+//#include <stdio.h>
+//#include <errno.h>
+
+
+#include "lib/elf/ElfPrpsinfo.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+jlong
+lib::elf::ElfPrpsinfo::getEntrySize()
+{
+	int entrySize = sizeof(elf_prpsinfo);
+	
+	return (jlong)entrySize;
+}
+
+jlong 
+lib::elf::ElfPrpsinfo::fillMemRegion(jbyteArray buffer, jlong startAddress)
+{
+	jbyte *bs = elements(buffer);
+	struct elf_prpsinfo *prpsinfo = NULL;
+	
+	prpsinfo = (struct elf_prpsinfo *)malloc(sizeof(struct elf_prpsinfo));
+	
+	memset(prpsinfo, 0, sizeof(struct elf_prpsinfo));
+	
+	prpsinfo->pr_state = this->pr_state;
+	prpsinfo->pr_sname = this->pr_sname;
+	prpsinfo->pr_zomb = this->pr_zomb;
+	prpsinfo->pr_nice = this->pr_nice;
+	prpsinfo->pr_flag = this->pr_flag;
+	
+	prpsinfo->pr_uid = this->pr_uid;
+	prpsinfo->pr_gid = this->pr_gid;
+
+	prpsinfo->pr_pid = this->pr_pid;
+	prpsinfo->pr_ppid = this->pr_ppid;
+	prpsinfo->pr_pgrp = this->pr_pgrp;
+	
+	prpsinfo->pr_sid = this->pr_sid;
+	
+	jchar *fname = elements(this->pr_fname);		
+	jchar *args = elements(this->pr_psargs);
+	
+	memcpy(prpsinfo->pr_fname, fname, sizeof(fname));
+	prpsinfo->pr_fname[sizeof(fname)] = '\0';
+	
+	memcpy(prpsinfo->pr_psargs, args, sizeof(args));
+	prpsinfo->pr_psargs[sizeof(args)] = '\0';
+	
+	memcpy(bs + startAddress, prpsinfo, sizeof(prpsinfo));
+	
+	return sizeof(prpsinfo);
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/proc/LinuxElfCoreFactory.java	2006-10-18 21:03:41.000000000 +0800
@@ -0,0 +1,38 @@
+package frysk.proc;
+
+import java.util.logging.Level;
+
+import lib.elf.Elf;
+import lib.elf.ElfCommand;
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfException;
+import lib.elf.ElfFileException;
+import frysk.proc.Isa;
+import frysk.proc.LinuxIa32;
+import frysk.proc.LinuxPPC64;
+import frysk.proc.LinuxX8664;
+import frysk.proc.Proc;
+import frysk.proc.Task;
+import frysk.proc.TaskException;
+
+public class LinuxElfCoreFactory
+{
+
+  public static LinuxElfCore getElfCore(Proc proc) 
+    throws TaskException
+  {
+    Isa procIsa = proc.getMainTask().getIsa();     
+    
+    //XXX if more ISA is available, add them here.
+    //XXX LinuxIa32On64 and LinuxPPC32On64 should be added.
+    if (procIsa instanceof LinuxIa32)
+      return new LinuxElfCoreIa32(proc);
+    else if (procIsa instanceof LinuxX8664)
+      return new LinuxElfCoreX8664(proc);
+    else if (procIsa instanceof LinuxPPC64)
+      return new LinuxElfCorePPC64(proc);
+    else
+      return null;
+  }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/proc/LinuxElfCoreIa32On64.java	2006-10-18 21:03:49.000000000 +0800
@@ -0,0 +1,27 @@
+package frysk.proc;
+
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfSection;
+
+public class LinuxElfCoreIa32On64 extends LinuxElfCore
+{
+  public LinuxElfCoreIa32On64(Proc proc)
+  {
+    super(proc);
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader) throws TaskException
+  {
+     
+    super.fillEHArchInfo(elfHeader);
+    
+    elfHeader.machine = ElfEMachine.EM_386;
+    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    //XXX: arch-dependent. 
+  }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/proc/LinuxElfCorePPC32On64.java	2006-10-18 21:03:56.000000000 +0800
@@ -0,0 +1,27 @@
+package frysk.proc;
+
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfSection;
+
+public class LinuxElfCorePPC32On64 extends LinuxElfCore
+{
+  public LinuxElfCorePPC32On64(Proc proc)
+  {
+    super(proc);
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader)
+  throws TaskException
+  {
+    super.fillEHArchInfo(elfHeader);
+    
+    elfHeader.machine = ElfEMachine.EM_PPC;
+    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    //XXX: arch-dependent. 
+  }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/proc/LinuxElfCoreX8664.java	2006-10-18 21:04:01.000000000 +0800
@@ -0,0 +1,30 @@
+package frysk.proc;
+
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfSection;
+import frysk.proc.Proc;
+import frysk.proc.TaskException;
+
+public class LinuxElfCoreX8664 extends LinuxElfCore
+{
+
+  public LinuxElfCoreX8664(Proc proc)
+  {
+    super(proc);
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader)
+  throws TaskException
+  {
+    super.fillEHArchInfo(elfHeader);
+    
+    elfHeader.machine = ElfEMachine.EM_X86_64;
+    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    //XXX: arch-dependent. 
+  }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/proc/LinuxElfCoreIa32.java	2006-10-18 21:04:06.000000000 +0800
@@ -0,0 +1,29 @@
+package frysk.proc;
+
+import frysk.proc.Proc;
+import frysk.proc.TaskException;
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfSection;
+
+public class LinuxElfCoreIa32 extends LinuxElfCore
+{
+  public LinuxElfCoreIa32(Proc proc)
+  {
+    super(proc);
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader) throws TaskException
+  {
+     
+    super.fillEHArchInfo(elfHeader);
+    
+    elfHeader.machine = ElfEMachine.EM_386;
+    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    //XXX: arch-dependent. 
+  }
+}
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/proc/LinuxElfCore.java	2006-10-18 21:04:10.000000000 +0800
@@ -0,0 +1,164 @@
+package frysk.util.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import inua.eio.ByteOrder;
+import frysk.proc.Isa;
+import frysk.proc.Proc;
+import frysk.proc.TaskException;
+import lib.elf.Elf;
+import lib.elf.ElfData;
+import lib.elf.ElfEHeader;
+import lib.elf.ElfNhdr;
+import lib.elf.ElfNoteSectionEntry;
+import lib.elf.ElfSection;
+
+public abstract class LinuxElfCore
+{
+  Proc proc = null;
+  
+  public LinuxElfCore(Proc proc)
+  {
+    this.proc = proc;
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader)
+  throws TaskException
+  {
+    Isa arch = proc.getMainTask().getIsa();     
+    ByteOrder order = arch.getByteOrder();
+    
+    if (order == ByteOrder.BIG_ENDIAN)
+        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2MSB;
+    else
+        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2LSB;  
+  }
+  
+  /**
+   * Fill the ElfNhdr object according to Proc object.
+   * 
+   * @param nhdrEntry
+   * @param proc
+   * @return less than zero when error occurs, or return one value 
+   *         that is equal to zero or more than zero.
+   */
+  protected int fillENotePrpsinfo(ElfNhdr nhdrEntry, Proc proc)
+  {
+    //XXX: fill the elf_prpsinfo here.
+  }
+  
+  /**
+   * Transform all information carried by list into ElfData object.
+   * 
+   * @param noteSectionData
+   * @param list ElfNhdr list.
+   * @return the number of invalid ElfNhdr objects.
+   */
+  protected int constructSectionData(ElfData noteSectionData, List nhdrList)
+  {
+    int size = 0;
+    
+    long secSize = 0;
+    long entrySize = 0;
+    
+    size = nhdrList.size();
+    if (size <= 0)
+      return 0;
+    
+    // Count the size of the whole PT_NOTE section.
+    for (int index = 0; index < size; index++)
+      {
+        ElfNhdr entry = (ElfNhdr)nhdrList.get(index);
+        
+        entrySize = entry.getNhdrEntrySize();
+        if (entrySize <= 0)
+          {
+            //One invalid entry, ignore it.
+            nhdrList.remove(index);
+            size--;
+            index--;
+            continue;
+          }
+        
+        secSize += entrySize;
+      }
+    //XXX: in the operation "new byte[count]", count must be "int". 
+    // If secSize is bigger than the max of "int' type, how can we do?
+    byte[] noteSecBuffer = new byte[(int)secSize];
+    long startAddress = 0;
+    
+    // Begin to fill the noteSection memory region.
+    size = nhdrList.size();
+    for (int index = 0; index < size; index++)
+      {
+        ElfNhdr entry = (ElfNhdr)nhdrList.get(index);
+        
+        entry.fillMemRegion(noteSecBuffer, startAddress);
+        
+        startAddress += entry.getNhdrEntrySize();
+      }
+    
+    return size;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    int ret = -1;
+    int entryCount = 0;
+    
+    ArrayList list = new ArrayList();
+    
+    ElfNhdr prpsinfoNhdr = new ElfNhdr();
+    noteSection.getPointer()
+    ret = this.fillENotePrpsinfo(prpsinfoNhdr, this.proc);
+    if (ret >= 0)
+      {
+        // Fill PRPSINFO correctly.
+        list.add(entryCount, prpsinfoNhdr);
+        entryCount++;
+      }
+    
+    //XXX: Continue to fill other ElfNhdr object, such as NT_PRSTATUS info.
+    // ElfNhdr psstatusNhdr = new ...
+    
+    if (list.size() <= 0)
+      return;
+    
+    ElfData sectionDate = noteSection.createNewElfData();
+    constructSectionData(sectionDate, list);
+  }
+  
+  /**
+   * Fill the ELF header information for the ELF core file.
+   * 
+   * @param elfCore
+   * @param proc
+   * @return null if fail to construct ELF header.
+   */
+  public ElfEHeader fillElfHeader(Elf elfCore) throws TaskException
+  {
+    //XXX: construct ELF header for elf object. 
+    elfCore.createNewEHeader();
+    ElfEHeader elf_header = elfCore.getEHeader();
+    
+    fillEHArchInfo(elf_header);
+    // Version
+    elf_header.ident[6] = (byte) elfCore.getElfVersion();
+    
+    // EXEC for now, ET_CORE later
+    elf_header.type = ElfEHeader.PHEADER_ET_EXEC;
+    //elf_header.type = ElfEHeader.PHEADER_ET_CORE;
+    
+    // Version
+    elf_header.version = elfCore.getElfVersion();
+    
+    // String Index
+    elf_header.shstrndx = 1;
+        
+    elfCore.updateEHeader(elf_header);
+    
+    return elf_header;
+  }
+}
+
--- /dev/null	2006-10-16 17:26:51.467209250 +0800
+++ frysk-core/frysk/proc/LinuxElfCorePPC64.java	2006-10-18 21:04:17.000000000 +0800
@@ -0,0 +1,29 @@
+package frysk.proc;
+
+import lib.elf.ElfEHeader;
+import lib.elf.ElfEMachine;
+import lib.elf.ElfSection;
+import frysk.proc.Proc;
+import frysk.proc.TaskException;
+
+public class LinuxElfCorePPC64 extends LinuxElfCore
+{
+  public LinuxElfCorePPC64(Proc proc)
+  {
+    super(proc);
+  }
+  
+  public void fillEHArchInfo(ElfEHeader elfHeader)
+  throws TaskException
+  {
+    super.fillEHArchInfo(elfHeader);
+    
+    elfHeader.machine = ElfEMachine.EM_PPC64;
+    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
+  }
+  
+  public void fillENoteSection(ElfSection noteSection)
+  {
+    //XXX: arch-dependent. 
+  }
+}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-18 13:35         ` Yong Zheng
@ 2006-10-18 14:37           ` Phil Muldoon
  2006-10-18 15:55           ` Phil Muldoon
  1 sibling, 0 replies; 14+ messages in thread
From: Phil Muldoon @ 2006-10-18 14:37 UTC (permalink / raw)
  To: Yong Zheng; +Cc: Frysk Hackers

Yong,

I'll take a look at this today, but in an initial look, it looks good!

Others

For context, this patch came out of a long irc conversation last night, 
regarding the best way to write note data as one section using one Elf 
Data. Yong volunteered to code up a proof of concept for prspinfo (the 
smallest structure). If it worked out, we (Yong and I) would proceed 
same for all notes and attempt the pstatus struct which is complex and 
has n * threads amount.


Yong Zheng wrote:
>> I was hoping that the Isa factory based abstraction would already help 
>> here. OTOH, I like the idea you proposed here though I am wary of 
>> building factories (ours) on top of ISA's own.  However it really 
>> cleanly cuts the code up into arch dependent parts within the FCore 
>> code. So I agree we should go ahead and implement it down the line.
>>
>> What I am doing today/this week is exposing the notes section to the 
>> core file. First thing I'll have to do is expose the notes structures to 
>> the Java bindings of Libelf, then build on the population of those 
>> structures. So I'll think on this some more during that time ;)
>>
>> Regards
>>
>> Phil
>>
>>     
>
> Phil, when I try to construct prpsinfo, there's no any definition in
> elfutils package. So I have to use <linux/elfcore.h> for java binding.
> And at the sametime, I refactor the arch-dependent code on CORE dumping
> again in order to dump out prpsinfo more easily. I just write some
> source codes now and post them out for comments from anybody who is
> interested in this. 
>
> Looking forward to your commends.
>
> Best regards.
> Yong Zheng
>   
> ------------------------------------------------------------------------
>
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/ElfNhdr.java	2006-10-18 21:02:35.000000000 +0800
> @@ -0,0 +1,136 @@
> +package lib.elf;
> +
> +public class ElfNhdr
> +{
> +  private long namesz = 4;
> +  private long descsz = 0;
> +  private int type = ElfNhdrType.NT_INVALID.getValue();
> +  
> +  private String name = "CORE";
> +  private ElfNoteSectionEntry desc = null;
> +  
> +  public static abstract class ElfNoteSectionEntry
> +  {
> +    public abstract long getEntrySize();
> +    public abstract long fillMemRegion(byte[] buffer, long startAddress);
> +  }
> +  
> +  //XXX: no ElfNhdr struct in elfutils package now(2006-10-18).
> +  //private long pointer;
> +  
> +  public ElfNhdr()
> +  {
> +
> +  }
> +  
> +  public String getName()
> +  {
> +    return this.name;
> +  }
> +  public long getNameSize()
> +  {
> +    return this.namesz;
> +  }
> +  public void setName(String nhdrName)
> +  {
> +    if (null == nhdrName)
> +      return;
> +    
> +    this.name = nhdrName;
> +    this.namesz = nhdrName.length();
> +  }
> +  
> +  public ElfNhdrType getNhdrType()
> +  {
> +    return ElfNhdrType.intern(this.type);
> +  }
> +  public ElfNoteSectionEntry getNhdrDesc()
> +  {
> +    return this.desc;
> +  }
> +  public long getDescSize()
> +  {
> +    return this.descsz;
> +  }
> +  
> +  public void setNhdrDesc(ElfNhdrType nhdrType, ElfNoteSectionEntry nhdrDesc)
> +  {
> +    this.type = nhdrType.getValue();
> +    this.desc = nhdrDesc;
> +    this.descsz = nhdrDesc.getEntrySize();
> +  }
> + 
> +  /**
> +   * Get the whole size of Nhdr (incluing the namesz and descsz).
> +   * 
> +   * @return
> +   */
> +  public long getNhdrEntrySize()
> +  {
> +    long size = 0;
> +    
> +    int nhdrSize = 0;
> +    
> +    nhdrSize = getNhdrSize();
> +    if ((nhdrSize <= 0) ||
> +        (namesz <= 0) || (descsz <= 0))
> +      {
> +        //Invalid object.
> +        return size;
> +      }
> +    
> +    size = nhdrSize + namesz + descsz;
> +    
> +    return size;
> +  }
> + 
> +  /**
> +   * Just get the size of Nhdr struct.
> +   * 
> +   * @return
> +   */
> +  public native int getNhdrSize();
> +  
> +  protected native long fillNhdr(byte[] buffer, long startAddress);
> +  protected native long fillNhdrName(byte[] buffer, long startAddress);
> +  
> +  /**
> +   * Fill the region starting from startAddress in buffer according to this ElfNhdr object.
> +   * 
> +   * @param noteSecBuffer
> +   * @param startAddress
> +   * @return
> +   */
> +  public long fillMemRegion(byte[] buffer, long startAddress)
> +  {
> +    long nhdrEntrySize = 0;
> +    
> +    long fillSize = 0;
> +    
> +    fillSize = fillNhdr(buffer, startAddress);
> +    if (fillSize != getNhdrSize())
> +      {
> +        //XXX: error occurred. throw excetpion?
> +      }
> +    
> +    nhdrEntrySize += fillSize;
> +    startAddress += fillSize;
> +    fillSize = fillNhdrName(buffer, startAddress);
> +    if (fillSize != this.namesz)
> +      {
> +        //XXX: error occurred. Throw exception?
> +      }
> +    
> +    nhdrEntrySize += fillSize;
> +    startAddress += fillSize;
> +    fillSize = this.desc.fillMemRegion(buffer, startAddress);
> +    if (fillSize != this.descsz)
> +      {
> +        //XXX: error occurred. Throw exception?
> +      }
> +    
> +    nhdrEntrySize += fillSize;
> +    return fillSize;
> +  }
> +  
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/ElfNhdrType.java	2006-10-18 21:02:38.000000000 +0800
> @@ -0,0 +1,70 @@
> +package lib.elf;
> +
> +public class ElfNhdrType
> +{
> +    public static final ElfNhdrType NT_INVALID = new ElfNhdrType(0, "NT_INVALID");
> +    public static final ElfNhdrType NT_PRSTATUS = new ElfNhdrType(1, "NT_PRSTATUS");
> +    public static final ElfNhdrType NT_FPREGSET = new ElfNhdrType(2, "NT_FPREGSET");
> +    public static final ElfNhdrType NT_PRPSINFO = new ElfNhdrType(3, "NT_PRPSINFO");
> +    public static final ElfNhdrType NT_PRXREG = new ElfNhdrType(4, "NT_PRXREG");
> +    
> +    public static final ElfNhdrType NT_TASKSTRUCT = new ElfNhdrType(4, "NT_TASKSTRUCT");
> +    public static final ElfNhdrType NT_PLATFORM = new ElfNhdrType(5, "NT_PLATFORM");
> +    public static final ElfNhdrType NT_AUXV = new ElfNhdrType(6, "NT_AUXV");
> +    public static final ElfNhdrType NT_GWINDOWS = new ElfNhdrType(7, "NT_GWINDOWS");
> +    public static final ElfNhdrType NT_ASRS = new ElfNhdrType(8, "NT_ASRS");
> +    
> +    public static final ElfNhdrType NT_PSTATUS = new ElfNhdrType(10, "NT_PSTATUS");
> +    public static final ElfNhdrType NT_PSINFO = new ElfNhdrType(13, "NT_PSINFO");
> +    public static final ElfNhdrType NT_PRCRED = new ElfNhdrType(14, "NT_PRCRED");
> +    
> +    public static final ElfNhdrType NT_UTSNAME = new ElfNhdrType(15, "NT_UTSNAME");
> +    public static final ElfNhdrType NT_LWPSTATUS = new ElfNhdrType(16, "NT_LWPSTATUS");
> +    public static final ElfNhdrType NT_LWPSINFO = new ElfNhdrType(17, "NT_LWPSINFO");
> +    public static final ElfNhdrType NT_PRFPXREG = new ElfNhdrType(20, "NT_PRFPXREG");
> +    
> +    private static ElfNhdrType[] types = {NT_INVALID, 
> +        NT_PRSTATUS, NT_FPREGSET, NT_PRPSINFO, NT_PRXREG, NT_PLATFORM,
> +        NT_AUXV, NT_GWINDOWS, NT_ASRS, NT_INVALID, NT_PSTATUS,
> +        NT_INVALID, NT_INVALID, NT_PSINFO, NT_PRCRED, NT_UTSNAME,
> +        NT_LWPSTATUS, NT_LWPSINFO, NT_INVALID, NT_INVALID, NT_PRFPXREG
> +    };
> +    
> +    private int value = 0;
> +    private String name = null;
> +    
> +    private ElfNhdrType(int value, String name)
> +    {
> +      this.value = value;
> +      this.name = name;
> +    }
> +    
> +    /**
> +     * @return true iff the object is an ElfType and equal to this object
> +     */
> +    public boolean equals(Object obj)
> +    {
> +        if(!(obj instanceof ElfNhdrType))
> +            return false;
> +        
> +        return ((ElfNhdrType)obj).value == this.value;
> +    }
> +    
> +    public int getValue()
> +    {
> +        return this.value;
> +    }
> +    
> +    public static ElfNhdrType intern(int type)
> +    {
> +      if ((type <= 0) || (type > (types.length - 1)))
> +        return NT_INVALID;
> +      else
> +        return types[type];
> +    }
> +    
> +    public String toString()
> +    {
> +        return this.name + "(" + this.value + ")";
> +    }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/ElfPrpsinfo.java	2006-10-18 21:02:55.000000000 +0800
> @@ -0,0 +1,242 @@
> +// This file is part of the program FRYSK.
> +//
> +// Copyright 2005, IBM Inc.
> +//
> +// FRYSK is free software; you can redistribute it and/or modify it
> +// under the terms of the GNU General Public License as published by
> +// the Free Software Foundation; version 2 of the License.
> +//
> +// FRYSK is distributed in the hope that it will be useful, but
> +// WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// General Public License for more details.
> +// 
> +// You should have received a copy of the GNU General Public License
> +// along with FRYSK; if not, write to the Free Software Foundation,
> +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> +// 
> +// In addition, as a special exception, Red Hat, Inc. gives You the
> +// additional right to link the code of FRYSK with code not covered
> +// under the GNU General Public License ("Non-GPL Code") and to
> +// distribute linked combinations including the two, subject to the
> +// limitations in this paragraph. Non-GPL Code permitted under this
> +// exception must only link to the code of FRYSK through those well
> +// defined interfaces identified in the file named EXCEPTION found in
> +// the source code files (the "Approved Interfaces"). The files of
> +// Non-GPL Code may instantiate templates or use macros or inline
> +// functions from the Approved Interfaces without causing the
> +// resulting work to be covered by the GNU General Public
> +// License. Only Red Hat, Inc. may make changes or additions to the
> +// list of Approved Interfaces. You must obey the GNU General Public
> +// License in all respects for all of the FRYSK code and other code
> +// used in conjunction with FRYSK except the Non-GPL Code covered by
> +// this exception. If you modify this file, you may extend this
> +// exception to your version of the file, but you are not obligated to
> +// do so. If you do not wish to provide this exception without
> +// modification, you must delete this exception statement from your
> +// version and license this file solely under the GPL without
> +// exception.
> +
> +package lib.elf;
> +
> +public class ElfPrpsinfo extends ElfNhdr.ElfNoteSectionEntry
> +{
> +  private char pr_state;
> +  private char pr_sname;
> +  private char pr_zomb;
> +  private char pr_nice;
> +  
> +  private long pr_flag;
> +  
> +  // on most platform, pr_uid is unsigned int. 
> +  // In java, "int" it sigend, so we have to use long type.
> +  private long pr_uid;
> +  private long pr_gid;
> +  
> +  private int pr_pid;
> +  private int pr_ppid;
> +  private int pr_pgrp;
> +  private int pr_sid;
> +  
> +  //XXX: the following two value must keep the same with the elfutils package.
> +  public static int ELF_PRPSINFO_FNAME_MAXLEN = 16;
> +  public static int ELF_PRPSINFO_ARGS_MAXLEN = 80;
> +  
> +  // filename of executable
> +  private char[] pr_fname = new char[ELF_PRPSINFO_FNAME_MAXLEN];
> +  
> +  // initial part of arg list
> +  private char[] pr_psargs = new char[ELF_PRPSINFO_ARGS_MAXLEN];
> +  
> +  private int pid;
> +  
> +  public ElfPrpsinfo(int pid)
> +  {
> +    this.pid = pid;
> +  }
> +  
> +  public void setPrState(char state)
> +  {
> +    this.pr_state = state;
> +  }
> +  
> +  public char getPrState()
> +  {
> +    return this.pr_state;
> +  }
> +  
> +  public void setPrSname(char sname)
> +  {
> +    this.pr_sname = sname;
> +  }
> +  
> +  public char getPrSname()
> +  {
> +    return this.pr_sname;
> +  }
> +  
> +  public void setPrZomb(char zomb)
> +  {
> +    this.pr_zomb = zomb;
> +  }
> +  
> +  public char getPrZomb()
> +  {
> +    return this.pr_zomb;
> +  }
> +  
> +  public void setPrNice(char nice)
> +  {
> +    this.pr_nice = nice;
> +  }
> +  
> +  public char getPrNice()
> +  {
> +    return this.pr_nice;
> +  }
> +  
> +  public void setPrFlag(long flag)
> +  {
> +    this.pr_flag = flag;
> +  }
> +  
> +  public long getPrFlag()
> +  {
> +    return this.pr_flag;
> +  }
> +  
> +  public void setPrUid(long uid)
> +  {
> +    this.pr_uid = uid;
> +  }
> +  
> +  public long getPrUid()
> +  {
> +    return this.pr_uid;
> +  }
> +  
> +  public void setPrGid(long gid)
> +  {
> +    this.pr_gid = gid;
> +  }
> +  
> +  public long getPrGid()
> +  {
> +    return this.pr_gid;
> +  }
> +  
> +  public void setPrPid(int pid)
> +  {
> +    this.pr_pid = pid;
> +  }
> +  public int getPrPid()
> +  {
> +    return this.pr_pid;
> +  }
> +  
> +  public void setPrPpid(int ppid)
> +  {
> +    this.pr_ppid = ppid;
> +  }
> +
> +  public int getPrPpid()
> +  {
> +    return this.pr_ppid;
> +  }
> +  
> +  public void setPrPgrp(int pgrp)
> +  {
> +    this.pr_pgrp = pgrp;
> +  }
> +  
> +  public int setPrPgrp()
> +  {
> +    return this.pr_pgrp;
> +  }
> +  
> +  public void setPrSid(int sid)
> +  {
> +    this.pr_sid = sid;
> +  }
> +
> +  public int getPrSid()
> +  {
> +    return this.pr_sid;
> +  }
> +  
> +  public void setPrFname(String fname)
> +  {
> +    if (null == fname)
> +      return;
> +    
> +    int length = fname.length();
> +    if (length < ELF_PRPSINFO_FNAME_MAXLEN)
> +    {
> +      this.pr_fname = fname.toCharArray();
> +      this.pr_fname[length] = '0';
> +    }
> +    else
> +      {
> +        String name = fname.substring(0, ELF_PRPSINFO_FNAME_MAXLEN);
> +        
> +        this.pr_fname = name.toCharArray();
> +        this.pr_fname[ELF_PRPSINFO_FNAME_MAXLEN] = '0';  
> +      }
> +  }
> +  public char[] getPrFname()
> +  {
> +    return this.pr_fname;
> +  }
> +
> +  public void getPrPsargs(String args)
> +  {
> +    if (null == args)
> +      return;
> +    
> +    int length = args.length();
> +    if (length < ELF_PRPSINFO_ARGS_MAXLEN)
> +    {
> +      this.pr_psargs = args.toCharArray();
> +      this.pr_psargs[length] = '0';
> +    }
> +    else
> +      {
> +        String name = args.substring(0, ELF_PRPSINFO_ARGS_MAXLEN);
> +        
> +        this.pr_psargs = name.toCharArray();
> +        this.pr_psargs[ELF_PRPSINFO_ARGS_MAXLEN] = '0';  
> +      }
> +  }
> +  public char[] getPrPsargs()
> +  {
> +    return this.pr_psargs;
> +  }
> +  
> +  public int getPid()
> +  {
> +    return this.pid;
> +  }
> +  
> +  public native long getEntrySize();
> +  public native long fillMemRegion(byte[] buffer, long startAddress);
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/cni/ElfNhdr.cxx	2006-10-18 21:03:09.000000000 +0800
> @@ -0,0 +1,102 @@
> +// This file is part of the program FRYSK.
> +//
> +// Copyright 2005, IBM Inc.
> +//
> +// FRYSK is free software; you can redistribute it and/or modify it
> +// under the terms of the GNU General Public License as published by
> +// the Free Software Foundation; version 2 of the License.
> +//
> +// FRYSK is distributed in the hope that it will be useful, but
> +// WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// General Public License for more details.
> +// 
> +// You should have received a copy of the GNU General Public License
> +// along with FRYSK; if not, write to the Free Software Foundation,
> +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> +// 
> +// In addition, as a special exception, Red Hat, Inc. gives You the
> +// additional right to link the code of FRYSK with code not covered
> +// under the GNU General Public License ("Non-GPL Code") and to
> +// distribute linked combinations including the two, subject to the
> +// limitations in this paragraph. Non-GPL Code permitted under this
> +// exception must only link to the code of FRYSK through those well
> +// defined interfaces identified in the file named EXCEPTION found in
> +// the source code files (the "Approved Interfaces"). The files of
> +// Non-GPL Code may instantiate templates or use macros or inline
> +// functions from the Approved Interfaces without causing the
> +// resulting work to be covered by the GNU General Public
> +// License. Only Red Hat, Inc. may make changes or additions to the
> +// list of Approved Interfaces. You must obey the GNU General Public
> +// License in all respects for all of the FRYSK code and other code
> +// used in conjunction with FRYSK except the Non-GPL Code covered by
> +// this exception. If you modify this file, you may extend this
> +// exception to your version of the file, but you are not obligated to
> +// do so. If you do not wish to provide this exception without
> +// modification, you must delete this exception statement from your
> +// version and license this file solely under the GPL without
> +// exception.
> +
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <gelf.h>
> +#include <gcj/cni.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <gelf.h>
> +
> +#include "lib/elf/ElfNhdr.h"
> +
> +#ifdef __cplusplus
> +extern "C"
> +{
> +#endif
> +
> +
> +jint
> +lib::elf::ElfNhdr::getNhdrSize()
> +{
> +	return sizeof(GElf_Nhdr);
> +}
> +
> +jlong 
> +lib::elf::ElfNhdr::fillNhdr(jbyteArray buffer, jlong startAddress)
> +{
> +	jbyte *bs = elements(buffer) + startAddress;
> +	
> +	errno = 0;
> +	GElf_Nhdr *nhdr = (GElf_Nhdr *)malloc(sizeof(GElf_Nhdr));
> +	
> +	memset(nhdr, 0, sizeof(GElf_Nhdr));
> +	
> +	// copy the GElf_Nhdr struct into buffer.
> +	//
> +	nhdr->n_namesz = this->namesz;
> +	nhdr->n_descsz = this->descsz;
> +	
> +	nhdr->n_type = this->type;
> +	
> +	memcpy(bs, nhdr, sizeof(GElf_Nhdr));
> +	
> +	return sizeof(GElf_Nhdr);
> +}
> +
> +jlong 
> +lib::elf::ElfNhdr::fillNhdrName(jbyteArray buffer, jlong startAddress)
> +{
> +	jlong size = 0; 
> +	jbyte *bs = elements(buffer) + startAddress;
> +
> +	//Copy the name infor into buffer.
> +	size = (jlong)JvGetStringUTFRegion(this->name, 0, this->namesz, (char *)bs);
> +	return size;
> +}
> + 
> +  
> +#ifdef __cplusplus
> +}
> +#endif
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/cni/ElfPrpsinfo.cxx	2006-10-18 21:03:15.000000000 +0800
> @@ -0,0 +1,108 @@
> +// This file is part of the program FRYSK.
> +//
> +// Copyright 2005, IBM Inc.
> +//
> +// FRYSK is free software; you can redistribute it and/or modify it
> +// under the terms of the GNU General Public License as published by
> +// the Free Software Foundation; version 2 of the License.
> +//
> +// FRYSK is distributed in the hope that it will be useful, but
> +// WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// General Public License for more details.
> +// 
> +// You should have received a copy of the GNU General Public License
> +// along with FRYSK; if not, write to the Free Software Foundation,
> +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> +// 
> +// In addition, as a special exception, Red Hat, Inc. gives You the
> +// additional right to link the code of FRYSK with code not covered
> +// under the GNU General Public License ("Non-GPL Code") and to
> +// distribute linked combinations including the two, subject to the
> +// limitations in this paragraph. Non-GPL Code permitted under this
> +// exception must only link to the code of FRYSK through those well
> +// defined interfaces identified in the file named EXCEPTION found in
> +// the source code files (the "Approved Interfaces"). The files of
> +// Non-GPL Code may instantiate templates or use macros or inline
> +// functions from the Approved Interfaces without causing the
> +// resulting work to be covered by the GNU General Public
> +// License. Only Red Hat, Inc. may make changes or additions to the
> +// list of Approved Interfaces. You must obey the GNU General Public
> +// License in all respects for all of the FRYSK code and other code
> +// used in conjunction with FRYSK except the Non-GPL Code covered by
> +// this exception. If you modify this file, you may extend this
> +// exception to your version of the file, but you are not obligated to
> +// do so. If you do not wish to provide this exception without
> +// modification, you must delete this exception statement from your
> +// version and license this file solely under the GPL without
> +// exception.
> +
> +#include <linux/elfcore.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <gcj/cni.h>
> +//#include <string.h>
> +//#include <sys/types.h>
> +//#include <sys/stat.h>
> +//#include <fcntl.h>
> +//#include <stdio.h>
> +//#include <errno.h>
> +
> +
> +#include "lib/elf/ElfPrpsinfo.h"
> +
> +#ifdef __cplusplus
> +extern "C"
> +{
> +#endif
> +
> +jlong
> +lib::elf::ElfPrpsinfo::getEntrySize()
> +{
> +	int entrySize = sizeof(elf_prpsinfo);
> +	
> +	return (jlong)entrySize;
> +}
> +
> +jlong 
> +lib::elf::ElfPrpsinfo::fillMemRegion(jbyteArray buffer, jlong startAddress)
> +{
> +	jbyte *bs = elements(buffer);
> +	struct elf_prpsinfo *prpsinfo = NULL;
> +	
> +	prpsinfo = (struct elf_prpsinfo *)malloc(sizeof(struct elf_prpsinfo));
> +	
> +	memset(prpsinfo, 0, sizeof(struct elf_prpsinfo));
> +	
> +	prpsinfo->pr_state = this->pr_state;
> +	prpsinfo->pr_sname = this->pr_sname;
> +	prpsinfo->pr_zomb = this->pr_zomb;
> +	prpsinfo->pr_nice = this->pr_nice;
> +	prpsinfo->pr_flag = this->pr_flag;
> +	
> +	prpsinfo->pr_uid = this->pr_uid;
> +	prpsinfo->pr_gid = this->pr_gid;
> +
> +	prpsinfo->pr_pid = this->pr_pid;
> +	prpsinfo->pr_ppid = this->pr_ppid;
> +	prpsinfo->pr_pgrp = this->pr_pgrp;
> +	
> +	prpsinfo->pr_sid = this->pr_sid;
> +	
> +	jchar *fname = elements(this->pr_fname);		
> +	jchar *args = elements(this->pr_psargs);
> +	
> +	memcpy(prpsinfo->pr_fname, fname, sizeof(fname));
> +	prpsinfo->pr_fname[sizeof(fname)] = '\0';
> +	
> +	memcpy(prpsinfo->pr_psargs, args, sizeof(args));
> +	prpsinfo->pr_psargs[sizeof(args)] = '\0';
> +	
> +	memcpy(bs + startAddress, prpsinfo, sizeof(prpsinfo));
> +	
> +	return sizeof(prpsinfo);
> +}
> +
> +#ifdef __cplusplus
> +}
> +#endif
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCoreFactory.java	2006-10-18 21:03:41.000000000 +0800
> @@ -0,0 +1,38 @@
> +package frysk.proc;
> +
> +import java.util.logging.Level;
> +
> +import lib.elf.Elf;
> +import lib.elf.ElfCommand;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfException;
> +import lib.elf.ElfFileException;
> +import frysk.proc.Isa;
> +import frysk.proc.LinuxIa32;
> +import frysk.proc.LinuxPPC64;
> +import frysk.proc.LinuxX8664;
> +import frysk.proc.Proc;
> +import frysk.proc.Task;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfCoreFactory
> +{
> +
> +  public static LinuxElfCore getElfCore(Proc proc) 
> +    throws TaskException
> +  {
> +    Isa procIsa = proc.getMainTask().getIsa();     
> +    
> +    //XXX if more ISA is available, add them here.
> +    //XXX LinuxIa32On64 and LinuxPPC32On64 should be added.
> +    if (procIsa instanceof LinuxIa32)
> +      return new LinuxElfCoreIa32(proc);
> +    else if (procIsa instanceof LinuxX8664)
> +      return new LinuxElfCoreX8664(proc);
> +    else if (procIsa instanceof LinuxPPC64)
> +      return new LinuxElfCorePPC64(proc);
> +    else
> +      return null;
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCoreIa32On64.java	2006-10-18 21:03:49.000000000 +0800
> @@ -0,0 +1,27 @@
> +package frysk.proc;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +
> +public class LinuxElfCoreIa32On64 extends LinuxElfCore
> +{
> +  public LinuxElfCoreIa32On64(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader) throws TaskException
> +  {
> +     
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_386;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCorePPC32On64.java	2006-10-18 21:03:56.000000000 +0800
> @@ -0,0 +1,27 @@
> +package frysk.proc;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +
> +public class LinuxElfCorePPC32On64 extends LinuxElfCore
> +{
> +  public LinuxElfCorePPC32On64(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_PPC;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCoreX8664.java	2006-10-18 21:04:01.000000000 +0800
> @@ -0,0 +1,30 @@
> +package frysk.proc;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfCoreX8664 extends LinuxElfCore
> +{
> +
> +  public LinuxElfCoreX8664(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_X86_64;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCoreIa32.java	2006-10-18 21:04:06.000000000 +0800
> @@ -0,0 +1,29 @@
> +package frysk.proc;
> +
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +
> +public class LinuxElfCoreIa32 extends LinuxElfCore
> +{
> +  public LinuxElfCoreIa32(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader) throws TaskException
> +  {
> +     
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_386;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCore.java	2006-10-18 21:04:10.000000000 +0800
> @@ -0,0 +1,164 @@
> +package frysk.util.core;
> +
> +import java.util.ArrayList;
> +import java.util.List;
> +
> +import inua.eio.ByteOrder;
> +import frysk.proc.Isa;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +import lib.elf.Elf;
> +import lib.elf.ElfData;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfNhdr;
> +import lib.elf.ElfNoteSectionEntry;
> +import lib.elf.ElfSection;
> +
> +public abstract class LinuxElfCore
> +{
> +  Proc proc = null;
> +  
> +  public LinuxElfCore(Proc proc)
> +  {
> +    this.proc = proc;
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    Isa arch = proc.getMainTask().getIsa();     
> +    ByteOrder order = arch.getByteOrder();
> +    
> +    if (order == ByteOrder.BIG_ENDIAN)
> +        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2MSB;
> +    else
> +        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2LSB;  
> +  }
> +  
> +  /**
> +   * Fill the ElfNhdr object according to Proc object.
> +   * 
> +   * @param nhdrEntry
> +   * @param proc
> +   * @return less than zero when error occurs, or return one value 
> +   *         that is equal to zero or more than zero.
> +   */
> +  protected int fillENotePrpsinfo(ElfNhdr nhdrEntry, Proc proc)
> +  {
> +    //XXX: fill the elf_prpsinfo here.
> +  }
> +  
> +  /**
> +   * Transform all information carried by list into ElfData object.
> +   * 
> +   * @param noteSectionData
> +   * @param list ElfNhdr list.
> +   * @return the number of invalid ElfNhdr objects.
> +   */
> +  protected int constructSectionData(ElfData noteSectionData, List nhdrList)
> +  {
> +    int size = 0;
> +    
> +    long secSize = 0;
> +    long entrySize = 0;
> +    
> +    size = nhdrList.size();
> +    if (size <= 0)
> +      return 0;
> +    
> +    // Count the size of the whole PT_NOTE section.
> +    for (int index = 0; index < size; index++)
> +      {
> +        ElfNhdr entry = (ElfNhdr)nhdrList.get(index);
> +        
> +        entrySize = entry.getNhdrEntrySize();
> +        if (entrySize <= 0)
> +          {
> +            //One invalid entry, ignore it.
> +            nhdrList.remove(index);
> +            size--;
> +            index--;
> +            continue;
> +          }
> +        
> +        secSize += entrySize;
> +      }
> +    //XXX: in the operation "new byte[count]", count must be "int". 
> +    // If secSize is bigger than the max of "int' type, how can we do?
> +    byte[] noteSecBuffer = new byte[(int)secSize];
> +    long startAddress = 0;
> +    
> +    // Begin to fill the noteSection memory region.
> +    size = nhdrList.size();
> +    for (int index = 0; index < size; index++)
> +      {
> +        ElfNhdr entry = (ElfNhdr)nhdrList.get(index);
> +        
> +        entry.fillMemRegion(noteSecBuffer, startAddress);
> +        
> +        startAddress += entry.getNhdrEntrySize();
> +      }
> +    
> +    return size;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    int ret = -1;
> +    int entryCount = 0;
> +    
> +    ArrayList list = new ArrayList();
> +    
> +    ElfNhdr prpsinfoNhdr = new ElfNhdr();
> +    noteSection.getPointer()
> +    ret = this.fillENotePrpsinfo(prpsinfoNhdr, this.proc);
> +    if (ret >= 0)
> +      {
> +        // Fill PRPSINFO correctly.
> +        list.add(entryCount, prpsinfoNhdr);
> +        entryCount++;
> +      }
> +    
> +    //XXX: Continue to fill other ElfNhdr object, such as NT_PRSTATUS info.
> +    // ElfNhdr psstatusNhdr = new ...
> +    
> +    if (list.size() <= 0)
> +      return;
> +    
> +    ElfData sectionDate = noteSection.createNewElfData();
> +    constructSectionData(sectionDate, list);
> +  }
> +  
> +  /**
> +   * Fill the ELF header information for the ELF core file.
> +   * 
> +   * @param elfCore
> +   * @param proc
> +   * @return null if fail to construct ELF header.
> +   */
> +  public ElfEHeader fillElfHeader(Elf elfCore) throws TaskException
> +  {
> +    //XXX: construct ELF header for elf object. 
> +    elfCore.createNewEHeader();
> +    ElfEHeader elf_header = elfCore.getEHeader();
> +    
> +    fillEHArchInfo(elf_header);
> +    // Version
> +    elf_header.ident[6] = (byte) elfCore.getElfVersion();
> +    
> +    // EXEC for now, ET_CORE later
> +    elf_header.type = ElfEHeader.PHEADER_ET_EXEC;
> +    //elf_header.type = ElfEHeader.PHEADER_ET_CORE;
> +    
> +    // Version
> +    elf_header.version = elfCore.getElfVersion();
> +    
> +    // String Index
> +    elf_header.shstrndx = 1;
> +        
> +    elfCore.updateEHeader(elf_header);
> +    
> +    return elf_header;
> +  }
> +}
> +
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCorePPC64.java	2006-10-18 21:04:17.000000000 +0800
> @@ -0,0 +1,29 @@
> +package frysk.proc;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfCorePPC64 extends LinuxElfCore
> +{
> +  public LinuxElfCorePPC64(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_PPC64;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
>   

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-18 13:35         ` Yong Zheng
  2006-10-18 14:37           ` Phil Muldoon
@ 2006-10-18 15:55           ` Phil Muldoon
  2006-10-19 10:39             ` Yong Zheng
  1 sibling, 1 reply; 14+ messages in thread
From: Phil Muldoon @ 2006-10-18 15:55 UTC (permalink / raw)
  To: Yong Zheng; +Cc: Frysk Hackers

It seems this patch addresses two ideas:

- create prspinfo data structures in part;
- re-factor FCore into an arch-based factory solution.

First I would like to address the second part..

I do not think there is an answer just yet for the question: Is a 
separate factory instantiation needed for each architecture?  Not until 
fcore has a core file written completely for one architecture. There is 
still the notes section left to do. Looking at other code that generates 
core files, they do not follow this approach of different factories (and 
therefore different method) of constructing core file data.  As far as I 
can see, the only arch-dependent data that exists for the headers is:

LSB or MSB (one byte flag)
32 or 64 bit (one byte flag)
Machine name (one byte flag)

And General Register/fp register Info.

The register info is accessed already in a generic and independent way 
via an iterator pattern. I am wondering if "right now" the re-factor  is 
a little heavyweight for a lightweight solution. And the other thing 
that concerns me is the construction of the core factories relies 
heavily on the generation of Isa factories. I get the idea that Isa will 
be re-factored soon, and that will cause ripple down implications. 
However I can see great use for it, if/when there is useful additional 
data beyond what are in corefiles right now, to extend notes for Frysk's 
own purposes. Then I think the factory solution would be ideal then.

The first part of the patch looks great (prspinfo specific solution: 
ElfNhdr.cxx, 
ElfNhdr.java,ElfNhdrType.java,ElfPrpsinfo.cxx,ElfPrpsinfo.java) and I 
would check it in. Good work, I really like the solution there.

I would like to propose keeping the FCore -> (Factory) re-factor out for 
now.  Let's get the core file written in a generic and simple fashion 
like other generators do first.  Then perhaps the question about needing 
the factories can be answered. As most of FCore is done, no code will be 
lost, and can always go back later and redo with your patch. I qualify 
later as being "days from now", pretty short term.

Regards


Phil
Yong Zheng wrote:
>> I was hoping that the Isa factory based abstraction would already help 
>> here. OTOH, I like the idea you proposed here though I am wary of 
>> building factories (ours) on top of ISA's own.  However it really 
>> cleanly cuts the code up into arch dependent parts within the FCore 
>> code. So I agree we should go ahead and implement it down the line.
>>
>> What I am doing today/this week is exposing the notes section to the 
>> core file. First thing I'll have to do is expose the notes structures to 
>> the Java bindings of Libelf, then build on the population of those 
>> structures. So I'll think on this some more during that time ;)
>>
>> Regards
>>
>> Phil
>>
>>     
>
> Phil, when I try to construct prpsinfo, there's no any definition in
> elfutils package. So I have to use <linux/elfcore.h> for java binding.
> And at the sametime, I refactor the arch-dependent code on CORE dumping
> again in order to dump out prpsinfo more easily. I just write some
> source codes now and post them out for comments from anybody who is
> interested in this. 
>
> Looking forward to your commends.
>
> Best regards.
> Yong Zheng
>   
> ------------------------------------------------------------------------
>
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/ElfNhdr.java	2006-10-18 21:02:35.000000000 +0800
> @@ -0,0 +1,136 @@
> +package lib.elf;
> +
> +public class ElfNhdr
> +{
> +  private long namesz = 4;
> +  private long descsz = 0;
> +  private int type = ElfNhdrType.NT_INVALID.getValue();
> +  
> +  private String name = "CORE";
> +  private ElfNoteSectionEntry desc = null;
> +  
> +  public static abstract class ElfNoteSectionEntry
> +  {
> +    public abstract long getEntrySize();
> +    public abstract long fillMemRegion(byte[] buffer, long startAddress);
> +  }
> +  
> +  //XXX: no ElfNhdr struct in elfutils package now(2006-10-18).
> +  //private long pointer;
> +  
> +  public ElfNhdr()
> +  {
> +
> +  }
> +  
> +  public String getName()
> +  {
> +    return this.name;
> +  }
> +  public long getNameSize()
> +  {
> +    return this.namesz;
> +  }
> +  public void setName(String nhdrName)
> +  {
> +    if (null == nhdrName)
> +      return;
> +    
> +    this.name = nhdrName;
> +    this.namesz = nhdrName.length();
> +  }
> +  
> +  public ElfNhdrType getNhdrType()
> +  {
> +    return ElfNhdrType.intern(this.type);
> +  }
> +  public ElfNoteSectionEntry getNhdrDesc()
> +  {
> +    return this.desc;
> +  }
> +  public long getDescSize()
> +  {
> +    return this.descsz;
> +  }
> +  
> +  public void setNhdrDesc(ElfNhdrType nhdrType, ElfNoteSectionEntry nhdrDesc)
> +  {
> +    this.type = nhdrType.getValue();
> +    this.desc = nhdrDesc;
> +    this.descsz = nhdrDesc.getEntrySize();
> +  }
> + 
> +  /**
> +   * Get the whole size of Nhdr (incluing the namesz and descsz).
> +   * 
> +   * @return
> +   */
> +  public long getNhdrEntrySize()
> +  {
> +    long size = 0;
> +    
> +    int nhdrSize = 0;
> +    
> +    nhdrSize = getNhdrSize();
> +    if ((nhdrSize <= 0) ||
> +        (namesz <= 0) || (descsz <= 0))
> +      {
> +        //Invalid object.
> +        return size;
> +      }
> +    
> +    size = nhdrSize + namesz + descsz;
> +    
> +    return size;
> +  }
> + 
> +  /**
> +   * Just get the size of Nhdr struct.
> +   * 
> +   * @return
> +   */
> +  public native int getNhdrSize();
> +  
> +  protected native long fillNhdr(byte[] buffer, long startAddress);
> +  protected native long fillNhdrName(byte[] buffer, long startAddress);
> +  
> +  /**
> +   * Fill the region starting from startAddress in buffer according to this ElfNhdr object.
> +   * 
> +   * @param noteSecBuffer
> +   * @param startAddress
> +   * @return
> +   */
> +  public long fillMemRegion(byte[] buffer, long startAddress)
> +  {
> +    long nhdrEntrySize = 0;
> +    
> +    long fillSize = 0;
> +    
> +    fillSize = fillNhdr(buffer, startAddress);
> +    if (fillSize != getNhdrSize())
> +      {
> +        //XXX: error occurred. throw excetpion?
> +      }
> +    
> +    nhdrEntrySize += fillSize;
> +    startAddress += fillSize;
> +    fillSize = fillNhdrName(buffer, startAddress);
> +    if (fillSize != this.namesz)
> +      {
> +        //XXX: error occurred. Throw exception?
> +      }
> +    
> +    nhdrEntrySize += fillSize;
> +    startAddress += fillSize;
> +    fillSize = this.desc.fillMemRegion(buffer, startAddress);
> +    if (fillSize != this.descsz)
> +      {
> +        //XXX: error occurred. Throw exception?
> +      }
> +    
> +    nhdrEntrySize += fillSize;
> +    return fillSize;
> +  }
> +  
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/ElfNhdrType.java	2006-10-18 21:02:38.000000000 +0800
> @@ -0,0 +1,70 @@
> +package lib.elf;
> +
> +public class ElfNhdrType
> +{
> +    public static final ElfNhdrType NT_INVALID = new ElfNhdrType(0, "NT_INVALID");
> +    public static final ElfNhdrType NT_PRSTATUS = new ElfNhdrType(1, "NT_PRSTATUS");
> +    public static final ElfNhdrType NT_FPREGSET = new ElfNhdrType(2, "NT_FPREGSET");
> +    public static final ElfNhdrType NT_PRPSINFO = new ElfNhdrType(3, "NT_PRPSINFO");
> +    public static final ElfNhdrType NT_PRXREG = new ElfNhdrType(4, "NT_PRXREG");
> +    
> +    public static final ElfNhdrType NT_TASKSTRUCT = new ElfNhdrType(4, "NT_TASKSTRUCT");
> +    public static final ElfNhdrType NT_PLATFORM = new ElfNhdrType(5, "NT_PLATFORM");
> +    public static final ElfNhdrType NT_AUXV = new ElfNhdrType(6, "NT_AUXV");
> +    public static final ElfNhdrType NT_GWINDOWS = new ElfNhdrType(7, "NT_GWINDOWS");
> +    public static final ElfNhdrType NT_ASRS = new ElfNhdrType(8, "NT_ASRS");
> +    
> +    public static final ElfNhdrType NT_PSTATUS = new ElfNhdrType(10, "NT_PSTATUS");
> +    public static final ElfNhdrType NT_PSINFO = new ElfNhdrType(13, "NT_PSINFO");
> +    public static final ElfNhdrType NT_PRCRED = new ElfNhdrType(14, "NT_PRCRED");
> +    
> +    public static final ElfNhdrType NT_UTSNAME = new ElfNhdrType(15, "NT_UTSNAME");
> +    public static final ElfNhdrType NT_LWPSTATUS = new ElfNhdrType(16, "NT_LWPSTATUS");
> +    public static final ElfNhdrType NT_LWPSINFO = new ElfNhdrType(17, "NT_LWPSINFO");
> +    public static final ElfNhdrType NT_PRFPXREG = new ElfNhdrType(20, "NT_PRFPXREG");
> +    
> +    private static ElfNhdrType[] types = {NT_INVALID, 
> +        NT_PRSTATUS, NT_FPREGSET, NT_PRPSINFO, NT_PRXREG, NT_PLATFORM,
> +        NT_AUXV, NT_GWINDOWS, NT_ASRS, NT_INVALID, NT_PSTATUS,
> +        NT_INVALID, NT_INVALID, NT_PSINFO, NT_PRCRED, NT_UTSNAME,
> +        NT_LWPSTATUS, NT_LWPSINFO, NT_INVALID, NT_INVALID, NT_PRFPXREG
> +    };
> +    
> +    private int value = 0;
> +    private String name = null;
> +    
> +    private ElfNhdrType(int value, String name)
> +    {
> +      this.value = value;
> +      this.name = name;
> +    }
> +    
> +    /**
> +     * @return true iff the object is an ElfType and equal to this object
> +     */
> +    public boolean equals(Object obj)
> +    {
> +        if(!(obj instanceof ElfNhdrType))
> +            return false;
> +        
> +        return ((ElfNhdrType)obj).value == this.value;
> +    }
> +    
> +    public int getValue()
> +    {
> +        return this.value;
> +    }
> +    
> +    public static ElfNhdrType intern(int type)
> +    {
> +      if ((type <= 0) || (type > (types.length - 1)))
> +        return NT_INVALID;
> +      else
> +        return types[type];
> +    }
> +    
> +    public String toString()
> +    {
> +        return this.name + "(" + this.value + ")";
> +    }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/ElfPrpsinfo.java	2006-10-18 21:02:55.000000000 +0800
> @@ -0,0 +1,242 @@
> +// This file is part of the program FRYSK.
> +//
> +// Copyright 2005, IBM Inc.
> +//
> +// FRYSK is free software; you can redistribute it and/or modify it
> +// under the terms of the GNU General Public License as published by
> +// the Free Software Foundation; version 2 of the License.
> +//
> +// FRYSK is distributed in the hope that it will be useful, but
> +// WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// General Public License for more details.
> +// 
> +// You should have received a copy of the GNU General Public License
> +// along with FRYSK; if not, write to the Free Software Foundation,
> +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> +// 
> +// In addition, as a special exception, Red Hat, Inc. gives You the
> +// additional right to link the code of FRYSK with code not covered
> +// under the GNU General Public License ("Non-GPL Code") and to
> +// distribute linked combinations including the two, subject to the
> +// limitations in this paragraph. Non-GPL Code permitted under this
> +// exception must only link to the code of FRYSK through those well
> +// defined interfaces identified in the file named EXCEPTION found in
> +// the source code files (the "Approved Interfaces"). The files of
> +// Non-GPL Code may instantiate templates or use macros or inline
> +// functions from the Approved Interfaces without causing the
> +// resulting work to be covered by the GNU General Public
> +// License. Only Red Hat, Inc. may make changes or additions to the
> +// list of Approved Interfaces. You must obey the GNU General Public
> +// License in all respects for all of the FRYSK code and other code
> +// used in conjunction with FRYSK except the Non-GPL Code covered by
> +// this exception. If you modify this file, you may extend this
> +// exception to your version of the file, but you are not obligated to
> +// do so. If you do not wish to provide this exception without
> +// modification, you must delete this exception statement from your
> +// version and license this file solely under the GPL without
> +// exception.
> +
> +package lib.elf;
> +
> +public class ElfPrpsinfo extends ElfNhdr.ElfNoteSectionEntry
> +{
> +  private char pr_state;
> +  private char pr_sname;
> +  private char pr_zomb;
> +  private char pr_nice;
> +  
> +  private long pr_flag;
> +  
> +  // on most platform, pr_uid is unsigned int. 
> +  // In java, "int" it sigend, so we have to use long type.
> +  private long pr_uid;
> +  private long pr_gid;
> +  
> +  private int pr_pid;
> +  private int pr_ppid;
> +  private int pr_pgrp;
> +  private int pr_sid;
> +  
> +  //XXX: the following two value must keep the same with the elfutils package.
> +  public static int ELF_PRPSINFO_FNAME_MAXLEN = 16;
> +  public static int ELF_PRPSINFO_ARGS_MAXLEN = 80;
> +  
> +  // filename of executable
> +  private char[] pr_fname = new char[ELF_PRPSINFO_FNAME_MAXLEN];
> +  
> +  // initial part of arg list
> +  private char[] pr_psargs = new char[ELF_PRPSINFO_ARGS_MAXLEN];
> +  
> +  private int pid;
> +  
> +  public ElfPrpsinfo(int pid)
> +  {
> +    this.pid = pid;
> +  }
> +  
> +  public void setPrState(char state)
> +  {
> +    this.pr_state = state;
> +  }
> +  
> +  public char getPrState()
> +  {
> +    return this.pr_state;
> +  }
> +  
> +  public void setPrSname(char sname)
> +  {
> +    this.pr_sname = sname;
> +  }
> +  
> +  public char getPrSname()
> +  {
> +    return this.pr_sname;
> +  }
> +  
> +  public void setPrZomb(char zomb)
> +  {
> +    this.pr_zomb = zomb;
> +  }
> +  
> +  public char getPrZomb()
> +  {
> +    return this.pr_zomb;
> +  }
> +  
> +  public void setPrNice(char nice)
> +  {
> +    this.pr_nice = nice;
> +  }
> +  
> +  public char getPrNice()
> +  {
> +    return this.pr_nice;
> +  }
> +  
> +  public void setPrFlag(long flag)
> +  {
> +    this.pr_flag = flag;
> +  }
> +  
> +  public long getPrFlag()
> +  {
> +    return this.pr_flag;
> +  }
> +  
> +  public void setPrUid(long uid)
> +  {
> +    this.pr_uid = uid;
> +  }
> +  
> +  public long getPrUid()
> +  {
> +    return this.pr_uid;
> +  }
> +  
> +  public void setPrGid(long gid)
> +  {
> +    this.pr_gid = gid;
> +  }
> +  
> +  public long getPrGid()
> +  {
> +    return this.pr_gid;
> +  }
> +  
> +  public void setPrPid(int pid)
> +  {
> +    this.pr_pid = pid;
> +  }
> +  public int getPrPid()
> +  {
> +    return this.pr_pid;
> +  }
> +  
> +  public void setPrPpid(int ppid)
> +  {
> +    this.pr_ppid = ppid;
> +  }
> +
> +  public int getPrPpid()
> +  {
> +    return this.pr_ppid;
> +  }
> +  
> +  public void setPrPgrp(int pgrp)
> +  {
> +    this.pr_pgrp = pgrp;
> +  }
> +  
> +  public int setPrPgrp()
> +  {
> +    return this.pr_pgrp;
> +  }
> +  
> +  public void setPrSid(int sid)
> +  {
> +    this.pr_sid = sid;
> +  }
> +
> +  public int getPrSid()
> +  {
> +    return this.pr_sid;
> +  }
> +  
> +  public void setPrFname(String fname)
> +  {
> +    if (null == fname)
> +      return;
> +    
> +    int length = fname.length();
> +    if (length < ELF_PRPSINFO_FNAME_MAXLEN)
> +    {
> +      this.pr_fname = fname.toCharArray();
> +      this.pr_fname[length] = '0';
> +    }
> +    else
> +      {
> +        String name = fname.substring(0, ELF_PRPSINFO_FNAME_MAXLEN);
> +        
> +        this.pr_fname = name.toCharArray();
> +        this.pr_fname[ELF_PRPSINFO_FNAME_MAXLEN] = '0';  
> +      }
> +  }
> +  public char[] getPrFname()
> +  {
> +    return this.pr_fname;
> +  }
> +
> +  public void getPrPsargs(String args)
> +  {
> +    if (null == args)
> +      return;
> +    
> +    int length = args.length();
> +    if (length < ELF_PRPSINFO_ARGS_MAXLEN)
> +    {
> +      this.pr_psargs = args.toCharArray();
> +      this.pr_psargs[length] = '0';
> +    }
> +    else
> +      {
> +        String name = args.substring(0, ELF_PRPSINFO_ARGS_MAXLEN);
> +        
> +        this.pr_psargs = name.toCharArray();
> +        this.pr_psargs[ELF_PRPSINFO_ARGS_MAXLEN] = '0';  
> +      }
> +  }
> +  public char[] getPrPsargs()
> +  {
> +    return this.pr_psargs;
> +  }
> +  
> +  public int getPid()
> +  {
> +    return this.pid;
> +  }
> +  
> +  public native long getEntrySize();
> +  public native long fillMemRegion(byte[] buffer, long startAddress);
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/cni/ElfNhdr.cxx	2006-10-18 21:03:09.000000000 +0800
> @@ -0,0 +1,102 @@
> +// This file is part of the program FRYSK.
> +//
> +// Copyright 2005, IBM Inc.
> +//
> +// FRYSK is free software; you can redistribute it and/or modify it
> +// under the terms of the GNU General Public License as published by
> +// the Free Software Foundation; version 2 of the License.
> +//
> +// FRYSK is distributed in the hope that it will be useful, but
> +// WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// General Public License for more details.
> +// 
> +// You should have received a copy of the GNU General Public License
> +// along with FRYSK; if not, write to the Free Software Foundation,
> +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> +// 
> +// In addition, as a special exception, Red Hat, Inc. gives You the
> +// additional right to link the code of FRYSK with code not covered
> +// under the GNU General Public License ("Non-GPL Code") and to
> +// distribute linked combinations including the two, subject to the
> +// limitations in this paragraph. Non-GPL Code permitted under this
> +// exception must only link to the code of FRYSK through those well
> +// defined interfaces identified in the file named EXCEPTION found in
> +// the source code files (the "Approved Interfaces"). The files of
> +// Non-GPL Code may instantiate templates or use macros or inline
> +// functions from the Approved Interfaces without causing the
> +// resulting work to be covered by the GNU General Public
> +// License. Only Red Hat, Inc. may make changes or additions to the
> +// list of Approved Interfaces. You must obey the GNU General Public
> +// License in all respects for all of the FRYSK code and other code
> +// used in conjunction with FRYSK except the Non-GPL Code covered by
> +// this exception. If you modify this file, you may extend this
> +// exception to your version of the file, but you are not obligated to
> +// do so. If you do not wish to provide this exception without
> +// modification, you must delete this exception statement from your
> +// version and license this file solely under the GPL without
> +// exception.
> +
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <gelf.h>
> +#include <gcj/cni.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <gelf.h>
> +
> +#include "lib/elf/ElfNhdr.h"
> +
> +#ifdef __cplusplus
> +extern "C"
> +{
> +#endif
> +
> +
> +jint
> +lib::elf::ElfNhdr::getNhdrSize()
> +{
> +	return sizeof(GElf_Nhdr);
> +}
> +
> +jlong 
> +lib::elf::ElfNhdr::fillNhdr(jbyteArray buffer, jlong startAddress)
> +{
> +	jbyte *bs = elements(buffer) + startAddress;
> +	
> +	errno = 0;
> +	GElf_Nhdr *nhdr = (GElf_Nhdr *)malloc(sizeof(GElf_Nhdr));
> +	
> +	memset(nhdr, 0, sizeof(GElf_Nhdr));
> +	
> +	// copy the GElf_Nhdr struct into buffer.
> +	//
> +	nhdr->n_namesz = this->namesz;
> +	nhdr->n_descsz = this->descsz;
> +	
> +	nhdr->n_type = this->type;
> +	
> +	memcpy(bs, nhdr, sizeof(GElf_Nhdr));
> +	
> +	return sizeof(GElf_Nhdr);
> +}
> +
> +jlong 
> +lib::elf::ElfNhdr::fillNhdrName(jbyteArray buffer, jlong startAddress)
> +{
> +	jlong size = 0; 
> +	jbyte *bs = elements(buffer) + startAddress;
> +
> +	//Copy the name infor into buffer.
> +	size = (jlong)JvGetStringUTFRegion(this->name, 0, this->namesz, (char *)bs);
> +	return size;
> +}
> + 
> +  
> +#ifdef __cplusplus
> +}
> +#endif
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-imports/lib/elf/cni/ElfPrpsinfo.cxx	2006-10-18 21:03:15.000000000 +0800
> @@ -0,0 +1,108 @@
> +// This file is part of the program FRYSK.
> +//
> +// Copyright 2005, IBM Inc.
> +//
> +// FRYSK is free software; you can redistribute it and/or modify it
> +// under the terms of the GNU General Public License as published by
> +// the Free Software Foundation; version 2 of the License.
> +//
> +// FRYSK is distributed in the hope that it will be useful, but
> +// WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// General Public License for more details.
> +// 
> +// You should have received a copy of the GNU General Public License
> +// along with FRYSK; if not, write to the Free Software Foundation,
> +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> +// 
> +// In addition, as a special exception, Red Hat, Inc. gives You the
> +// additional right to link the code of FRYSK with code not covered
> +// under the GNU General Public License ("Non-GPL Code") and to
> +// distribute linked combinations including the two, subject to the
> +// limitations in this paragraph. Non-GPL Code permitted under this
> +// exception must only link to the code of FRYSK through those well
> +// defined interfaces identified in the file named EXCEPTION found in
> +// the source code files (the "Approved Interfaces"). The files of
> +// Non-GPL Code may instantiate templates or use macros or inline
> +// functions from the Approved Interfaces without causing the
> +// resulting work to be covered by the GNU General Public
> +// License. Only Red Hat, Inc. may make changes or additions to the
> +// list of Approved Interfaces. You must obey the GNU General Public
> +// License in all respects for all of the FRYSK code and other code
> +// used in conjunction with FRYSK except the Non-GPL Code covered by
> +// this exception. If you modify this file, you may extend this
> +// exception to your version of the file, but you are not obligated to
> +// do so. If you do not wish to provide this exception without
> +// modification, you must delete this exception statement from your
> +// version and license this file solely under the GPL without
> +// exception.
> +
> +#include <linux/elfcore.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <gcj/cni.h>
> +//#include <string.h>
> +//#include <sys/types.h>
> +//#include <sys/stat.h>
> +//#include <fcntl.h>
> +//#include <stdio.h>
> +//#include <errno.h>
> +
> +
> +#include "lib/elf/ElfPrpsinfo.h"
> +
> +#ifdef __cplusplus
> +extern "C"
> +{
> +#endif
> +
> +jlong
> +lib::elf::ElfPrpsinfo::getEntrySize()
> +{
> +	int entrySize = sizeof(elf_prpsinfo);
> +	
> +	return (jlong)entrySize;
> +}
> +
> +jlong 
> +lib::elf::ElfPrpsinfo::fillMemRegion(jbyteArray buffer, jlong startAddress)
> +{
> +	jbyte *bs = elements(buffer);
> +	struct elf_prpsinfo *prpsinfo = NULL;
> +	
> +	prpsinfo = (struct elf_prpsinfo *)malloc(sizeof(struct elf_prpsinfo));
> +	
> +	memset(prpsinfo, 0, sizeof(struct elf_prpsinfo));
> +	
> +	prpsinfo->pr_state = this->pr_state;
> +	prpsinfo->pr_sname = this->pr_sname;
> +	prpsinfo->pr_zomb = this->pr_zomb;
> +	prpsinfo->pr_nice = this->pr_nice;
> +	prpsinfo->pr_flag = this->pr_flag;
> +	
> +	prpsinfo->pr_uid = this->pr_uid;
> +	prpsinfo->pr_gid = this->pr_gid;
> +
> +	prpsinfo->pr_pid = this->pr_pid;
> +	prpsinfo->pr_ppid = this->pr_ppid;
> +	prpsinfo->pr_pgrp = this->pr_pgrp;
> +	
> +	prpsinfo->pr_sid = this->pr_sid;
> +	
> +	jchar *fname = elements(this->pr_fname);		
> +	jchar *args = elements(this->pr_psargs);
> +	
> +	memcpy(prpsinfo->pr_fname, fname, sizeof(fname));
> +	prpsinfo->pr_fname[sizeof(fname)] = '\0';
> +	
> +	memcpy(prpsinfo->pr_psargs, args, sizeof(args));
> +	prpsinfo->pr_psargs[sizeof(args)] = '\0';
> +	
> +	memcpy(bs + startAddress, prpsinfo, sizeof(prpsinfo));
> +	
> +	return sizeof(prpsinfo);
> +}
> +
> +#ifdef __cplusplus
> +}
> +#endif
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCoreFactory.java	2006-10-18 21:03:41.000000000 +0800
> @@ -0,0 +1,38 @@
> +package frysk.proc;
> +
> +import java.util.logging.Level;
> +
> +import lib.elf.Elf;
> +import lib.elf.ElfCommand;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfException;
> +import lib.elf.ElfFileException;
> +import frysk.proc.Isa;
> +import frysk.proc.LinuxIa32;
> +import frysk.proc.LinuxPPC64;
> +import frysk.proc.LinuxX8664;
> +import frysk.proc.Proc;
> +import frysk.proc.Task;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfCoreFactory
> +{
> +
> +  public static LinuxElfCore getElfCore(Proc proc) 
> +    throws TaskException
> +  {
> +    Isa procIsa = proc.getMainTask().getIsa();     
> +    
> +    //XXX if more ISA is available, add them here.
> +    //XXX LinuxIa32On64 and LinuxPPC32On64 should be added.
> +    if (procIsa instanceof LinuxIa32)
> +      return new LinuxElfCoreIa32(proc);
> +    else if (procIsa instanceof LinuxX8664)
> +      return new LinuxElfCoreX8664(proc);
> +    else if (procIsa instanceof LinuxPPC64)
> +      return new LinuxElfCorePPC64(proc);
> +    else
> +      return null;
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCoreIa32On64.java	2006-10-18 21:03:49.000000000 +0800
> @@ -0,0 +1,27 @@
> +package frysk.proc;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +
> +public class LinuxElfCoreIa32On64 extends LinuxElfCore
> +{
> +  public LinuxElfCoreIa32On64(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader) throws TaskException
> +  {
> +     
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_386;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCorePPC32On64.java	2006-10-18 21:03:56.000000000 +0800
> @@ -0,0 +1,27 @@
> +package frysk.proc;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +
> +public class LinuxElfCorePPC32On64 extends LinuxElfCore
> +{
> +  public LinuxElfCorePPC32On64(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_PPC;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCoreX8664.java	2006-10-18 21:04:01.000000000 +0800
> @@ -0,0 +1,30 @@
> +package frysk.proc;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfCoreX8664 extends LinuxElfCore
> +{
> +
> +  public LinuxElfCoreX8664(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_X86_64;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCoreIa32.java	2006-10-18 21:04:06.000000000 +0800
> @@ -0,0 +1,29 @@
> +package frysk.proc;
> +
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +
> +public class LinuxElfCoreIa32 extends LinuxElfCore
> +{
> +  public LinuxElfCoreIa32(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader) throws TaskException
> +  {
> +     
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_386;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS32;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCore.java	2006-10-18 21:04:10.000000000 +0800
> @@ -0,0 +1,164 @@
> +package frysk.util.core;
> +
> +import java.util.ArrayList;
> +import java.util.List;
> +
> +import inua.eio.ByteOrder;
> +import frysk.proc.Isa;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +import lib.elf.Elf;
> +import lib.elf.ElfData;
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfNhdr;
> +import lib.elf.ElfNoteSectionEntry;
> +import lib.elf.ElfSection;
> +
> +public abstract class LinuxElfCore
> +{
> +  Proc proc = null;
> +  
> +  public LinuxElfCore(Proc proc)
> +  {
> +    this.proc = proc;
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    Isa arch = proc.getMainTask().getIsa();     
> +    ByteOrder order = arch.getByteOrder();
> +    
> +    if (order == ByteOrder.BIG_ENDIAN)
> +        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2MSB;
> +    else
> +        elfHeader.ident[5] = ElfEHeader.PHEADER_ELFDATA2LSB;  
> +  }
> +  
> +  /**
> +   * Fill the ElfNhdr object according to Proc object.
> +   * 
> +   * @param nhdrEntry
> +   * @param proc
> +   * @return less than zero when error occurs, or return one value 
> +   *         that is equal to zero or more than zero.
> +   */
> +  protected int fillENotePrpsinfo(ElfNhdr nhdrEntry, Proc proc)
> +  {
> +    //XXX: fill the elf_prpsinfo here.
> +  }
> +  
> +  /**
> +   * Transform all information carried by list into ElfData object.
> +   * 
> +   * @param noteSectionData
> +   * @param list ElfNhdr list.
> +   * @return the number of invalid ElfNhdr objects.
> +   */
> +  protected int constructSectionData(ElfData noteSectionData, List nhdrList)
> +  {
> +    int size = 0;
> +    
> +    long secSize = 0;
> +    long entrySize = 0;
> +    
> +    size = nhdrList.size();
> +    if (size <= 0)
> +      return 0;
> +    
> +    // Count the size of the whole PT_NOTE section.
> +    for (int index = 0; index < size; index++)
> +      {
> +        ElfNhdr entry = (ElfNhdr)nhdrList.get(index);
> +        
> +        entrySize = entry.getNhdrEntrySize();
> +        if (entrySize <= 0)
> +          {
> +            //One invalid entry, ignore it.
> +            nhdrList.remove(index);
> +            size--;
> +            index--;
> +            continue;
> +          }
> +        
> +        secSize += entrySize;
> +      }
> +    //XXX: in the operation "new byte[count]", count must be "int". 
> +    // If secSize is bigger than the max of "int' type, how can we do?
> +    byte[] noteSecBuffer = new byte[(int)secSize];
> +    long startAddress = 0;
> +    
> +    // Begin to fill the noteSection memory region.
> +    size = nhdrList.size();
> +    for (int index = 0; index < size; index++)
> +      {
> +        ElfNhdr entry = (ElfNhdr)nhdrList.get(index);
> +        
> +        entry.fillMemRegion(noteSecBuffer, startAddress);
> +        
> +        startAddress += entry.getNhdrEntrySize();
> +      }
> +    
> +    return size;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    int ret = -1;
> +    int entryCount = 0;
> +    
> +    ArrayList list = new ArrayList();
> +    
> +    ElfNhdr prpsinfoNhdr = new ElfNhdr();
> +    noteSection.getPointer()
> +    ret = this.fillENotePrpsinfo(prpsinfoNhdr, this.proc);
> +    if (ret >= 0)
> +      {
> +        // Fill PRPSINFO correctly.
> +        list.add(entryCount, prpsinfoNhdr);
> +        entryCount++;
> +      }
> +    
> +    //XXX: Continue to fill other ElfNhdr object, such as NT_PRSTATUS info.
> +    // ElfNhdr psstatusNhdr = new ...
> +    
> +    if (list.size() <= 0)
> +      return;
> +    
> +    ElfData sectionDate = noteSection.createNewElfData();
> +    constructSectionData(sectionDate, list);
> +  }
> +  
> +  /**
> +   * Fill the ELF header information for the ELF core file.
> +   * 
> +   * @param elfCore
> +   * @param proc
> +   * @return null if fail to construct ELF header.
> +   */
> +  public ElfEHeader fillElfHeader(Elf elfCore) throws TaskException
> +  {
> +    //XXX: construct ELF header for elf object. 
> +    elfCore.createNewEHeader();
> +    ElfEHeader elf_header = elfCore.getEHeader();
> +    
> +    fillEHArchInfo(elf_header);
> +    // Version
> +    elf_header.ident[6] = (byte) elfCore.getElfVersion();
> +    
> +    // EXEC for now, ET_CORE later
> +    elf_header.type = ElfEHeader.PHEADER_ET_EXEC;
> +    //elf_header.type = ElfEHeader.PHEADER_ET_CORE;
> +    
> +    // Version
> +    elf_header.version = elfCore.getElfVersion();
> +    
> +    // String Index
> +    elf_header.shstrndx = 1;
> +        
> +    elfCore.updateEHeader(elf_header);
> +    
> +    return elf_header;
> +  }
> +}
> +
> --- /dev/null	2006-10-16 17:26:51.467209250 +0800
> +++ frysk-core/frysk/proc/LinuxElfCorePPC64.java	2006-10-18 21:04:17.000000000 +0800
> @@ -0,0 +1,29 @@
> +package frysk.proc;
> +
> +import lib.elf.ElfEHeader;
> +import lib.elf.ElfEMachine;
> +import lib.elf.ElfSection;
> +import frysk.proc.Proc;
> +import frysk.proc.TaskException;
> +
> +public class LinuxElfCorePPC64 extends LinuxElfCore
> +{
> +  public LinuxElfCorePPC64(Proc proc)
> +  {
> +    super(proc);
> +  }
> +  
> +  public void fillEHArchInfo(ElfEHeader elfHeader)
> +  throws TaskException
> +  {
> +    super.fillEHArchInfo(elfHeader);
> +    
> +    elfHeader.machine = ElfEMachine.EM_PPC64;
> +    elfHeader.ident[4] = ElfEHeader.PHEADER_ELFCLASS64;
> +  }
> +  
> +  public void fillENoteSection(ElfSection noteSection)
> +  {
> +    //XXX: arch-dependent. 
> +  }
> +}
>   

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-18 15:55           ` Phil Muldoon
@ 2006-10-19 10:39             ` Yong Zheng
  2006-10-19 15:44               ` Phil Muldoon
  0 siblings, 1 reply; 14+ messages in thread
From: Yong Zheng @ 2006-10-19 10:39 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Frysk Hackers

Phil,

I have checked in some part of my code. Now, it can dump PT_NOTE (but
only with prpsinfo struct). After I dumped one core file, I read it by
readelf and get some warning info at the end of the output:

the section header info:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] note              PROGBITS         0000000000000000  00000318
       0000000000000098  0000000000000000   A       0     0     1
......

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  NOTE          0x0000000000000000 0x0000000000000000 0x0000000000000000
                0x0000000000000098 0x0000000000000000         0
  LOAD          0x00000000000003b0 0x0000000000400000 0x0000000000000000
                0x0000000000000000 0x0000000000001000  R E    1

But at the end of output from readelf, there are some warning infor:

Notes at offset 0x00000000 with length 0x00000098:
  Owner         Data size       Description
readelf: Warning: corrupt note found at offset 0 into core notes
readelf: Warning:  type: 0, namesize: 464c457f, descsize: 00010102

The above "type", namesize and descsize are not equal to that I record
in prpsinfo struct! Although there are some warning info, I checked them
in in order that we both can start working on it. right? :-)

I will trace down the bug. If I could get some comments from you about
this, it will be appreciated very much.

2006-10-19  Yong Zheng  <zhengyo@cn.ibm.com>

	* frysk-core/frysk/util/FCore.java (fillENoteSection): New
	function to construct PT_NOTE section).
	(constructSectionData): New function to construct PT_NOTE data.
	(fillENotePrpsinfo): New function to fill elf_prpsinfo info.
	* frysk-imports/lib/elf/ElfNhdr.java: New file.
	* frysk-imports/lib/elf/ELfNhdrType.h: Ditto.
	* frysk-imports/lib/elf/ELfPrpsinfo.java: Ditto.
	* frysk-imports/lib/elf/cni/ELfNhdr.cxx: Ditto.
	* frysk-imports/lib/elf/cni/ELfPrpsinfo.cxx: Ditto.


Best regards
Yong Zheng

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-19 10:39             ` Yong Zheng
@ 2006-10-19 15:44               ` Phil Muldoon
  2006-10-19 17:39                 ` Phil Muldoon
  0 siblings, 1 reply; 14+ messages in thread
From: Phil Muldoon @ 2006-10-19 15:44 UTC (permalink / raw)
  To: Yong Zheng; +Cc: Frysk Hackers


> But at the end of output from readelf, there are some warning infor:
>
> Notes at offset 0x00000000 with length 0x00000098:
>   Owner         Data size       Description
> readelf: Warning: corrupt note found at offset 0 into core notes
> readelf: Warning:  type: 0, namesize: 464c457f, descsize: 00010102
>
> The above "type", namesize and descsize are not equal to that I record
> in prpsinfo struct! Although there are some warning info, I checked them
> in in order that we both can start working on it. right? :-)
>   

Right, I'll pick up where you left off and l'll run with it today. 
Looking at it initially, for some reason there is a small offset of 
gcore/kernel where the notes lives (it does not begin at 0, like ours). 
I'm wondering if there is some confusion on ElfEHeader and NOTES header. 
We might have our offsets incorrectly calculated here.

For example in others:

Section Headers:
[Nr] Name                 Type         Addr     Off    Size   ES Flags 
Lk Inf Al
[ 0]                      NULL         00000000 000000 000000  0        
0   0  0
[ 1] note0                PROGBITS     00000000 000394 00046c  0 A      
0   0  1

> I will trace down the bug. If I could get some comments from you about
> this, it will be appreciated very much.
>
> 2006-10-19  Yong Zheng  <zhengyo@cn.ibm.com>
>
> 	* frysk-core/frysk/util/FCore.java (fillENoteSection): New
> 	function to construct PT_NOTE section).
> 	(constructSectionData): New function to construct PT_NOTE data.
> 	(fillENotePrpsinfo): New function to fill elf_prpsinfo info.
> 	* frysk-imports/lib/elf/ElfNhdr.java: New file.
> 	* frysk-imports/lib/elf/ELfNhdrType.h: Ditto.
> 	* frysk-imports/lib/elf/ELfPrpsinfo.java: Ditto.
> 	* frysk-imports/lib/elf/cni/ELfNhdr.cxx: Ditto.
> 	* frysk-imports/lib/elf/cni/ELfPrpsinfo.cxx: Ditto.
>
>   

All looks great to me. I suspect we'll need above check-in for each 
prspinfo, prstatus, fpregset, and auxv information. Lots of structures 
for one section ;) I'll let you know later on today what I come up with.

Regards

Phil

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-19 15:44               ` Phil Muldoon
@ 2006-10-19 17:39                 ` Phil Muldoon
  2006-10-20  8:09                   ` Yong Zheng
  0 siblings, 1 reply; 14+ messages in thread
From: Phil Muldoon @ 2006-10-19 17:39 UTC (permalink / raw)
  To: Yong Zheng; +Cc: Frysk Hackers

[-- Attachment #1: Type: text/plain, Size: 2696 bytes --]

I fixed the prspinfo, in the included patch. As usual, small bugs take 
the longest to find.  ;) The problem here was not asking libelf to 
calculate the note header offset in memory, then re-fetching the section 
header, and only then updating the program header offset for notes. Just 
updating the structure back to the native bits is not enough; we have to 
ask libelf to so some shuffling around, then tell use where everything is.

I'll check this in, with a number of other fixes/changes later today.

Regards

Phil

Phil Muldoon wrote:
>
>> But at the end of output from readelf, there are some warning infor:
>>
>> Notes at offset 0x00000000 with length 0x00000098:
>>   Owner         Data size       Description
>> readelf: Warning: corrupt note found at offset 0 into core notes
>> readelf: Warning:  type: 0, namesize: 464c457f, descsize: 00010102
>>
>> The above "type", namesize and descsize are not equal to that I record
>> in prpsinfo struct! Although there are some warning info, I checked them
>> in in order that we both can start working on it. right? :-)
>>   
>
> Right, I'll pick up where you left off and l'll run with it today. 
> Looking at it initially, for some reason there is a small offset of 
> gcore/kernel where the notes lives (it does not begin at 0, like 
> ours). I'm wondering if there is some confusion on ElfEHeader and 
> NOTES header. We might have our offsets incorrectly calculated here.
>
> For example in others:
>
> Section Headers:
> [Nr] Name                 Type         Addr     Off    Size   ES Flags 
> Lk Inf Al
> [ 0]                      NULL         00000000 000000 000000  
> 0        0   0  0
> [ 1] note0                PROGBITS     00000000 000394 00046c  0 
> A      0   0  1
>
>> I will trace down the bug. If I could get some comments from you about
>> this, it will be appreciated very much.
>>
>> 2006-10-19  Yong Zheng  <zhengyo@cn.ibm.com>
>>
>>     * frysk-core/frysk/util/FCore.java (fillENoteSection): New
>>     function to construct PT_NOTE section).
>>     (constructSectionData): New function to construct PT_NOTE data.
>>     (fillENotePrpsinfo): New function to fill elf_prpsinfo info.
>>     * frysk-imports/lib/elf/ElfNhdr.java: New file.
>>     * frysk-imports/lib/elf/ELfNhdrType.h: Ditto.
>>     * frysk-imports/lib/elf/ELfPrpsinfo.java: Ditto.
>>     * frysk-imports/lib/elf/cni/ELfNhdr.cxx: Ditto.
>>     * frysk-imports/lib/elf/cni/ELfPrpsinfo.cxx: Ditto.
>>
>>   
>
> All looks great to me. I suspect we'll need above check-in for each 
> prspinfo, prstatus, fpregset, and auxv information. Lots of structures 
> for one section ;) I'll let you know later on today what I come up with.
>
> Regards
>
> Phil


[-- Attachment #2: prspinfo_fix.patch --]
[-- Type: text/x-patch, Size: 1048 bytes --]

Index: frysk-core/frysk/util/FCore.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/util/FCore.java,v
retrieving revision 1.7
diff -u -r1.7 FCore.java
--- frysk-core/frysk/util/FCore.java	19 Oct 2006 10:45:54 -0000	1.7
+++ frysk-core/frysk/util/FCore.java	19 Oct 2006 17:30:48 -0000
@@ -458,6 +458,17 @@
 		noteSectHeader.size = noteSection.getData().getSize();
 		noteSection.update(noteSectHeader);
         
+		// Must first ask libelf to construct offset location before
+		// adding offset back to program header. Otherwise program offset
+		// will be 0.
+		if (local_elf.update(ElfCommand.ELF_C_NULL) < 0) {
+			throw new ElfException("Cannot calculate note section offset");
+		}
+		
+		// Then re-fetch the elf modified header from section. Now offset 
+		// is calculated and correct.
+		noteSectHeader = noteSection.getSectionHeader();
+		
 		// Modify PT_NOTE program header
 		noteProgramHeader = local_elf.getPHeader(0);
 		noteProgramHeader.type = ElfPHeader.PTYPE_NOTE;

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-19 17:39                 ` Phil Muldoon
@ 2006-10-20  8:09                   ` Yong Zheng
  2006-10-23 20:58                     ` Phil Muldoon
  0 siblings, 1 reply; 14+ messages in thread
From: Yong Zheng @ 2006-10-20  8:09 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Frysk Hackers

hi,

I have checked in one patch to fix the fillENotePrpsinfo(), and now all
information got from Stat() works well. Then I also do some
modifications on postProcessElfFile() because it doesnot work well as
expected on big endian platform.

On PPC/PPC64, the header of one core dumpped by fcore is the
following(hex): 

0000000: 7f45 4c46 0102 0100 0000 0000 0000 0000  .ELF............
0000010: 0402 0000 0000 0001 0000 0000 0000 0034  ...............4 

Notice the second line, "0402" will be parsed as e_type. So when reading
the core's header, readelf will give "<unknown>: 402" type and won't
show PT_NOTE's data info. The right value should be "0004" but not
"0402"! So I do some modifications on postProcessElfFile() function. 

Now, on PPC/PPC64, we could get the same output with on X86/X86_64.

2006-10-20  Yong Zheng <zhengyo@cn.ibm.com>

	* frysk-core/frysk/util/FCore.java (fillENotePrpsinfo): Pass pid
	as one parameter when refreshing Stat.
	(postProcessElfFile): Support modifications of the e_type in ELF
	header on big-endian platform. 

Best regards
Yong Zheng

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: fcore status
  2006-10-20  8:09                   ` Yong Zheng
@ 2006-10-23 20:58                     ` Phil Muldoon
  0 siblings, 0 replies; 14+ messages in thread
From: Phil Muldoon @ 2006-10-23 20:58 UTC (permalink / raw)
  To: Frysk Hackers

I did a clean-up and reworking of FCore, to use among other things:

proc.requestAbandon().

This brings FCore in line with FStack in leaving a process. I've also 
written a simple error handler that attempts to abandon the process 
cleanly, write errors to the console and exit as quickly as possible.

The utility function write_elf_file was getting very long and was 
refactored out to a lot of helper functions. I also re-indented where it 
was needed (ugh, my fault, it turns out between using emacs with gnu 
indention style (correct), eclipse in workspace without GNU formatting 
(wrong), and eclipse with GNU formatting (right), I made the indention a 
mess. I've fixed those errors with Eclipse's format using the GNU indent 
style. There are two more notes section left to do: floating point 
registers and auxv, and of course writing the tests.

Regards

Phil

2006-10-23  Phil Muldoon  <pmuldoon@redhat.com>

        * FCore.java (abandonCoreDump): New.
        (CoreDumpTasksObserver): GNU Indent. Add comments.
        (CoreDumpTasksObserver.existingTask): Call abandonCoreDump, on each
        Exception case.
        (CoreDumpTasksObserver.removeObservers): Use proc.requestAbandon().
        (fillENotePrstatus): GNU Indent. Use abandonCoreDump on failure.
        (fillENotePrpsinfo, constructSectionData): GNU Indent.
        (fillENoteSection): Added JavaDoc. GNU Indent.
        (write_elf_file): Rewritten and broken up into smaller utility
        functions.
        (buildElfHeader): New. Extrapolated from write_elf_file.
        (buildNotes): Ditto.
        (buildStringTable): Ditto.
        (CoreMapsBuilder.buildMap): GNU Indent.
        (MapsCounter.buildMap): Ditto.
        (main): GNU Indent and clean-up.
        (addOptions): GNU Indent and clean-up.



Yong Zheng wrote:
> hi,
>
> I have checked in one patch to fix the fillENotePrpsinfo(), and now all
> information got from Stat() works well. Then I also do some
> modifications on postProcessElfFile() because it doesnot work well as
> expected on big endian platform.
>
> On PPC/PPC64, the header of one core dumpped by fcore is the
> following(hex): 
>
> 0000000: 7f45 4c46 0102 0100 0000 0000 0000 0000  .ELF............
> 0000010: 0402 0000 0000 0001 0000 0000 0000 0034  ...............4 
>
> Notice the second line, "0402" will be parsed as e_type. So when reading
> the core's header, readelf will give "<unknown>: 402" type and won't
> show PT_NOTE's data info. The right value should be "0004" but not
> "0402"! So I do some modifications on postProcessElfFile() function. 
>
> Now, on PPC/PPC64, we could get the same output with on X86/X86_64.
>
> 2006-10-20  Yong Zheng <zhengyo@cn.ibm.com>
>
> 	* frysk-core/frysk/util/FCore.java (fillENotePrpsinfo): Pass pid
> 	as one parameter when refreshing Stat.
> 	(postProcessElfFile): Support modifications of the e_type in ELF
> 	header on big-endian platform. 
>
> Best regards
> Yong Zheng
>
>   

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2006-10-23 20:58 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-10-15 21:48 fcore status Phil Muldoon
2006-10-16 13:00 ` Yong Zheng
2006-10-16 13:18   ` Phil Muldoon
2006-10-17  2:39     ` Yong Zheng
2006-10-17 23:14       ` Phil Muldoon
2006-10-18 13:35         ` Yong Zheng
2006-10-18 14:37           ` Phil Muldoon
2006-10-18 15:55           ` Phil Muldoon
2006-10-19 10:39             ` Yong Zheng
2006-10-19 15:44               ` Phil Muldoon
2006-10-19 17:39                 ` Phil Muldoon
2006-10-20  8:09                   ` Yong Zheng
2006-10-23 20:58                     ` Phil Muldoon
2006-10-17 17:06     ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).