Re: C-like Pointers
by ikegami (Patriarch) on Nov 16, 2009 at 01:23 UTC
|
The question is flawed on two levels.
-
Even in C that doesn't access RAM. It access virtual memory, the process's memory space.
-
Scalars are fundamentally different than raw bytes of memory. Perl is free to allocated and deallocated scalars, convert strings between two internal formats, and convert between types at will, even when you only look at the scalar.
You are really asking for a means of accessing "arbitrary" addresses within the process's memory space. That's definitely possible via an XS module. Start your search on CPAN.
Mind you, it's possible to use a scalar (and other types of variables) as an interface to functions such that fetches call one function and sets call another. The feature is call "magic", and tie is one form of this. The downside is this slower than calling the underlying functions directly.
That said, I can't help but think we should review your decision to go down this path. What is the real problem you are trying to solve?
| [reply] |
|
Thank you for your answer (and either thank to the others) :D
I know the fact, that C can only access virtual memory, I choosed the easier term "RAM" for people which don't know about Paging and stuff.
My real problem is to solve the following problem:
A buddy wrote a program in C which loads a ELF-kernel and execute it. I (I'm either a C progammer and OS-developer) wanted to write the same program in Perl, just for fun. The biggest problem is to access a virtual address within the process' memoryspace and using pointers to these addresses. I have to write this line:
krnl = mmap((void *)0x78000000, lof, PROT_READ, MAP_PRIVATE | MAP_FIXE
+D, fileno(kernel), 0);
In Perl. My (not working) solution is:
$mapped_kernel = syscall(\&SYS_mmap, $address, $kernel_size, $page_rea
+d, $map_private | $map_fixed, fileno(KERNEL), 0);
where syscall() and \&SYS_mmap are functions/references to functions from syscall.h (converted to .ph via h2ph), $kernel_size, $page_read, $map_private and $map_fixed simple integer-values, KERNEL the filehandle to the loaded kernel and $address the pointer to the address.
In short words, I want to do (void*)0x78000000 in Perl, a pointer to a address defiend by myself (without the help of C :-P). I've searched CPAN for XS and pointers but did not found anything related to my problem (or I was too stupid to find it ^^).
| [reply] [d/l] [select] |
|
hardwire(VARIABLE, ADDRESS, LENGTH)
Specifies the address in memory of a variable, possibly within a
region you've "mmap()"ed another variable to. You must use the same
precautions to keep the variable from being reallocated, and use
"substr()" with an exact length. If you "munmap()" a region that a
"hardwire()"ed variable lives in, the "hardwire()"ed variable will
not automatically be "undef"ed. You must do this manually.
..and thought it just might be of use. Maybe try:
use Sys::Mmap;
# ...
Sys::Mmap::hardwire($address, 0x78000000, $kernel_size);
| [reply] [d/l] [select] |
|
Re: C-like Pointers
by Anonymous Monk on Nov 16, 2009 at 01:18 UTC
|
| [reply] |
Re: C-like Pointers (unpack)
by tye (Sage) on Nov 16, 2009 at 03:49 UTC
|
my $bytes= 4*1024; # Set to number of bytes to copy
my $copy= unpack "P$bytes", 0x78000000;
| [reply] [d/l] |
|
Hi,
with your solution I'm gettig a segfault while executing. This either can mean it works and the adress 0x78000000 is just wrong for it (I need to find out where Perl does run in the virtual memspace...) or your solution is wrong.
Anyway, thanks for your advice :D
| [reply] |
|
| [reply] |
|
Oops, I forgot that this requires an extra layer of indirection. I suspect that the number of environments where "I" is the wrong choice is very small. Strangely, I used "L" in Acme::ESP which seems a more fragile choice.
my $fmt= "I";
my $iBytes= length( pack $fmt, $fmt );
my $pBytes= length( pack "P", $fmt );
if( $iBytes != $pBytes ) {
die "Your pointers are $pBytes bytes, ints are $iBytes";
}
my $pointer= pack $fmt, 0x78000000;
my $bytes= 4*1024; # Set to number of bytes to copy
my $copy= unpack "P$bytes", $pointer;
| [reply] [d/l] |
Re: C-like Pointers
by 7stud (Deacon) on Nov 16, 2009 at 01:25 UTC
|
Hi,
The integer represented by the hex notation 0x78000000 is the same integer as 2,013,265,920, which is in decimal notation. I think your program does the equivalent of:
my $x = \1;
print $x, "\n";
which outputs something like this:
SCALAR(0x1810e50)
I believe that hex address is where the integer 1 is located in memory. In other words, you didn't succeed in getting a pointer to the address 0x1. | [reply] [d/l] [select] |