× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



I'm beginning to think that a port of the gc is not possible to the native environment. There just seems to be too many things preventing the ability to scan all possible types of memory for a "root set" as a starting point to be searched for possibly "live" pointers and objects. The current stumbling block is a test program packaged with the gc that tries to malloc a bunch of pointers in a function call and intersperses these with garbage collections:

    uniq(GC_malloc(12), GC_malloc(12), GC_malloc(12),
         (GC_gcollect(),GC_malloc(12)),
         GC_malloc(12), GC_malloc(12), GC_malloc(12),
         (GC_gcollect(),GC_malloc(12)),
         GC_malloc(12), GC_malloc(12), GC_malloc(12),
         (GC_gcollect(),GC_malloc(12)),
         GC_malloc(12), GC_malloc(12), GC_malloc(12),
         (GC_gcollect(),GC_malloc(12)),
         GC_malloc(12), GC_malloc(12), GC_malloc(12),
         (GC_gcollect(),GC_malloc(12)),
         (void *)0);

Now what happens is a routine called GC_push_regs (called within GC_malloc) attempts to "mark" pointers contained in registers (which are in all probability being used to pass parameters) in an attempt to protect those objects pointed to from being reclaimed. On most platforms a platform-specific inline assembler version of the routine examines registers and allows marking of objects pointed to by pointers contained in those registers. This can't be done in the native 400 environment (inline assembler, register access, that is), however a generic version written in C and using a setjmp() trick which at least compiles on the 400 also fails to do the necessary marking.

So what happens is that after a GC_gcollect occurs, the subsequent GC_malloc's start to re-use reclaimed pointers resulting in non-unique pointers for parameters within the uniq() routine, i.e., two parameters containing the same pointer rather than unique ones that have been protected by the register marking operation in GC_(generic_)push_regs.

Now it seems that under ILE that "call stacks" are the mechanism for calling functions and passing parameters. What I need to know at this point is whether it's possible for the GC_push_regs routine (within GC_malloc) to examine the current call stack (much like it examines registers) in an attempt to access the pointers passed as parameters and mark the object pointed to, so preventing the object being reclaimed?

(As regards your initial post of executing PPC code in a user space object, another e-mail directed to me suggested that this may be possible on earlier versions of OS/400, but on something like V5R3 (which I'm using for teraspace enablement) it becomes nigh on impossible because of user space object pages being marked "not executable" by the OS and causing an exception when an attempt is made to branch to code within such a page. Don't know for sure because it's not something I've tried myself...)


On 06/11/2004, at 12:34 AM, Steve Richter wrote:



-----Original Message-----
From: mi400-bounces@xxxxxxxxxxxx [mailto:mi400-bounces@xxxxxxxxxxxx]On
Behalf Of Peter Colson
Sent: Thursday, November 04, 2004 11:50 PM
To: 'MI Programming on the AS400 / iSeries'
Subject: RE: [MI400] running PowerPC instructions in a user space


Steve,

Very interesting....

That was my reaction also. I am glad you noticed Peter, it was looking like
this post had passed everyone by. :)


Now the questions in my mind are whether this technique can be used
flexibly
in an ILE/C program to:

1). Examine machine registers (if required) as part of the creation of a
"root-set" based on global (static) and automatic memory plus registers
that
may contain pointers to heap objects, so that the root set can be the
starting point of a scan by a 3rd-party garbage collector,

2). Execute native machine code as an efficient replacement of a
higher-level interpreted byte code.

What I have been able to gather so far is that the system on the PPC level
functions similar to the system at the user/programmer level. That is the
code accesses and calls out to interfaces to get its work done. To respond
with a guess, interfacing with the machine heap space ( MI instruction
CRTHS, ALCHSS, ... ) is a matter of filling registers and data structures
and then calling to either SEPT entry points or using the PowerPC SC (
system call ) instruction to call into the system via an interrupt.


The SC route is especially interesting because I suspect that is how PPC
code is indirectly able to execute privledged instructions that are needed
to start debugging PPC code. One goal I have is to be able to create a new
object type on the system. Not sure if that is possible, even using PPC
assembler, but I would like to find out.


I noted in your example you were using STRSST to alter machine code
instructions in an existing program, correct?

that is right. I had to replace two instruction words. The first one
copied the address in a register to the link register. The 2nd instruction
branched unconditionally to the link register.


(I've asked questions relating to the possibility of porting an open-source
gc to the 400 using ILE/C teraspace-enabled previously, on this and other
lists, and am still plugging away, so your post caught my eye...)

Based on the little I know, such a port is doable. Either to PASE or, much
more intersting to me, the native environment of the 400.


-Steve


-----Original Message-----
From: mi400-bounces@xxxxxxxxxxxx [mailto:mi400-bounces@xxxxxxxxxxxx] On
Behalf Of Steve Richter
Sent: Sunday, 31 October 2004 5:57 AM
To: chat. Mi400
Subject: [MI400] running PowerPC instructions in a user space


I have been curious to know if PowerPC encoded instructions could be place
in a user space and an RPG program be made to branch its execution to that
code. The answer, after a little bit of digging and experimenting ( and
reading the archives! ), is that yes, that can be done.


The as400/ppc uses 8 byte pointers when it branches to code in a program.
It also uses 8 byte pointers when it loads and stores data to 8 byte
addresses of data in user spaces. The theory is that the 8 byte address
of
a data that is stored to in a user space can also be branched to using
that
same 8 byte address.


Here is rpg code that copys 4 bytes ( a word ) pointed to by a pointer
into
an rpg program variable:
 d pData        s            *
 d Data         s           4a   based(pData)
 d ch4          s           4a
  /free
       ch4      = Data ;

here is the corresponding PowerPC code:
 LQ     20, 0x1e40(30), 6
 SELRI  23, 21, 0, 41
 LWZ    22, 0x0(23)
 STW    22, 0x128( 30 )

LQ loads "pData", the pointer ( quad word ) stored at EA ( effective
address ) reg30 + 0x1e40, into reg20 and reg21. reg30 is the pointer to
either the automatic storage of the RPG program or to its procedure call
stack. Not sure which. 0x1e40 is the displacement from reg30 to the
"pData"
variable.


SELRI does something to reg21 with the result ending up in reg23. reg21 is
important because it holds the actual pointer after LQ loaded both reg20
and
reg21.


LWZ ( load word, zero fill ) loads the word ( 4 bytes ) located at EA
reg23
+ 0 into reg22. These are the 4 characters pointed to by "pData" in the
rpg
program.


STW stores the word stored in reg22 into the word at EA reg30 + 0x128.
That
is the rpg variable "ch4".

That is how the PowerPC loads and stores data to an EA. The following is
PPC code that would branch execution to code at that same address:
mtspr 9, 23
bcctrl 20, 0


MTSPR ( move to special register ) moves reg23 to special register #9.
That
is the "count" register.
http://www.nersc.gov/vendor_docs/ibm/asm/mtspr.htm#a29891041

BCCTRL ( branch conditional to count register ) branches to the address
stored in the count register. ( the 20 means do it unconditionally ).
Because there is an "L" at the end of the opcode name ( BCCTRL instead of
BCCTR ) it also stores the return address, the address of the next
instruction, in the link register.


Here is the PowerPC code that branches to the instruction words pointed to
by the above RPG variable "pData"
E29E1E46 LQ 20, 0x1e40(30), 6
7AB7049C SELRI 23, 21, 0, 41
7EE903A6 mtspr 9, 23
4E800421 bcctrl 20, 0


The hex values in the left column is the hex external form of the 4 byte
power pc instructions. This site is pretty good at explaining what the
encoding is all about:
http://www.nersc.gov/vendor_docs/ibm/asm/mastertoc.htm


Here is code that when executed will store an immediate value to an EA and
then branch unconditionally to the link register:
3A600320 addi 19, 0, 800
927E012C stw 19, 30, 300
4E800020 bclr 20, 0


The first stmt effectively places the immediate value 800 into reg19. The
"stw" stmt stores reg19 to the word at EA reg30 + 300. The last stmt,
"bclr" branches unconditionally to the address in the link register.


If this code is stored in a user space, it can be executed from an RPG
program by doing the following:
- make sure "pData" points to the data/code in the user space
- use the display/alter/dump facility of STRSST to punch the mtspr and
bcctrl stmts shown above in place of the LWZ and STW in the rpg program:


original RPG emitted code:
 LQ     20, 0x1e40(30), 6
 SELRI  23, 21, 0, 41
 LWZ    22, 0x0(23)
 STW    22, 0x128( 30 )

becomes:
 E29E1E46   LQ      20, 0x1e40(30), 6
 7AB7049C   SELRI   23, 21, 0, 41
 7EE903A6   mtspr   9, 23
 4E800421   bcctrl  20, 0

The user space code to be executed:
 3A600320     addi  19, 0, 800
 927E012C     stw   19, 30, 300
 4E800020     bclr  20, 0

is going to store the immed word value "800" to displacement 300 from the
au
tomatic storage of the RPG program. That was the displacement to a 10i 0
int variable in the rpg program I was working with. It is there to prove
the concept that the patched rpg code actually did branch to the user
space
and execute the above statements. If you are going to do the same you
should change that displacement to a value you see from using SST to dump
your own RPG code.


What I did was add a breakpoint to the rpg program at the statement after
the one that was patched, ran the code, hoped for the best and presto, the
breakpoint broke and an EVAL of the RPG INT variable showed that it
contained the value "800" !


-Steve Richter


_______________________________________________ This is the MI Programming on the AS400 / iSeries (MI400) mailing list To post a message email: MI400@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options, visit: http://lists.midrange.com/mailman/listinfo/mi400 or email: MI400-request@xxxxxxxxxxxx Before posting, please take a moment to review the archives at http://archive.midrange.com/mi400.




_______________________________________________
This is the MI Programming on the AS400 / iSeries (MI400) mailing list
To post a message email: MI400@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/mi400
or email: MI400-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/mi400.


_______________________________________________ This is the MI Programming on the AS400 / iSeries (MI400) mailing list To post a message email: MI400@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options, visit: http://lists.midrange.com/mailman/listinfo/mi400 or email: MI400-request@xxxxxxxxxxxx Before posting, please take a moment to review the archives at http://archive.midrange.com/mi400.





Regards, Peter Colson.


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.