Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

C-like Pointers

by DerHartmut (Novice)
on Nov 16, 2009 at 00:55 UTC ( [id://807342]=perlquestion: print w/replies, xml ) Need Help??

DerHartmut has asked for the wisdom of the Perl Monks concerning the following question:

Hi @ all, I have a Problem: I want to do this expression in Perl:
(void*)0x78000000
it's a pointer to a address in the RAM. After reading this (it's written in german) I've tried the following in my Perl-Code:
my $address = \0x78000000;
Now my question: How to use $address so I'm getting a real pointer to this piece of RAM? $address, $$address or \$address? I've all of them and the first and third expression gave a address about 0x9esomethinsomethin out while $$address gives 0x78000000 out.

If this problem cannot be solved in Perl, please let me know that ^^

Best regards,

DerHartmut

P.S.: Sorry for my bad bad english, I'm still learning it (and either Perl :D)

Replies are listed 'Best First'.
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?

      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 ^^).
        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

        Did you come across Sys::Mmap's hardwire() method in your travels?

        Just reading the synopsis for this function:

               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);
Re: C-like Pointers
by Anonymous Monk on Nov 16, 2009 at 01:18 UTC
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;

    - tye        

      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

        Although less probable, seen in pack documentation:

        If your system has a strange pointer size (i.e. a pointer is neither as big as an int nor as big as a long), it may not be possible to pack or unpack pointers in big- or little-endian byte order. Attempting to do so will result in a fatal error.

      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;

      - tye        

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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://807342]
Approved by biohisham
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-16 12:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found