Thread: Mirror ram

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Mirror ram

    I just thought of something interesting, but perhaps impossible unless I make my own wrappers around ram.
    But the question is - is it possible to make an address in the virtual ram to mirror another space?
    For example, let's say I've allocated some memory at 0xB000000 and I want all reads and writes to 0xA000000 to be redirected to 0xB000000 in the virtual memory. Question - is it possible without writing your own memory wrappers to do such things?

    I find it an interesting prospect, one which I might experiment with, but I'm uncertain if it has any practical use, though I have one thing in mind.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well any answer is going to be heavily dependent on your OS.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, this targets Windows (XP/Vista).

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'm not sure if there is any way to make the OS do that for you, but certainly it's possible to "alias" the same physical memory range to multiple virtual addresses.

    Aside from mapping the same region of memory to share it between multiple processes [each which may have it's own address], I don't really see what the point is. If you have a block of memory, then you have a block of memory, and the fact that a particular address in that memory is unique [within a given process] is a very good thing, in my mind - you can for example compare two pointers and see if they point at the same object. Having multiple addresses that are actually the same physical address is just a pain.

    Actually, in the 16-bit x86 days, it was possible to have a pointer to the same object formed in different ways, because the segment address and the offset can be formed in 4096 different ways. So if you wanted to make sure that two pointers are equal, you'd have to "normalize" both of them before comparing, otherwise they could point to the same thing without having the same value.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I got the idea when thinking of arrays.
    For example, when you want to expand the array, you could allocate a new snippet of memory and assign it the virtual address just beyond the range of the first array. The new snippet of memory would of course get a new virtual address, in which I thought, how about mirroring the virtual address?
    Of course, I could just mirror a virtual address to the same physical memory too.

    Which makes me wonder... even if you allocate, say, 100 bytes of memory which is placed contigous in virtual memory, will it also gaurantee to be placed contigous in physical memory?

    Code:
    char* my_array = new char[100];
    // Code goes here
    // ...
    my_array[99] = 'H';
    // End of array, need to expand.
    char* my_array2 = new char[100];
    my_array[100] = 'e'; // my_array + 100 should be pointing to my_array2[0] here.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > will it also gaurantee to be placed contigous in physical memory?
    If it's all in the same page, yes.

    But if the virtual address range straddles a page boundary, then there's no telling where the two physical pages are located.

    Also, because they're virtual, there's no reason for the virtual address to be continually mapped to the same physical page. It could be swapped out and swapped back in later on.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    I got the idea when thinking of arrays.
    For example, when you want to expand the array, you could allocate a new snippet of memory and assign it the virtual address just beyond the range of the first array. The new snippet of memory would of course get a new virtual address, in which I thought, how about mirroring the virtual address?
    Of course, I could just mirror a virtual address to the same physical memory too.

    Which makes me wonder... even if you allocate, say, 100 bytes of memory which is placed contigous in virtual memory, will it also gaurantee to be placed contigous in physical memory?

    Code:
    char* my_array = new char[100];
    // Code goes here
    // ...
    my_array[99] = 'H';
    // End of array, need to expand.
    char* my_array2 = new char[100];
    my_array[100] = 'e'; // my_array + 100 should be pointing to my_array2[0] here.
    Not sure what you're trying to say, so I'll first explain how memory management works:
    1. Memory is small blocks of 4KB each, that is translated via a number of page-table entries [2-4 page tables, depending on processor architecture and settings].
    2. So the smallest granularity you could allocate memory at, with an equal address, is 4KB.

    A contiguous virtual address is not necessarily contiguous in a physical sense - only if you ask specifically [and this is usually only possible in kernel mode] can you get physically contiguous memory - something that is often used for DMA buffers by device drivers, particularly in older hardware that doesn't have "scatter/gather" mapping of it's physical buffers.

    But the 4KB itself is guarnteed to be contiguous. The next 4KB could be "anywhere" - in fact, in debug mode in Xen, it specifically uses a reverse-order allocation, so the first block you get is the last one of the current free-list, rather than the first. This guarantees that anyone doing "funny" coding based on the next block being physically is much more likely to be found.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, as in the example above, if I allocate a new array somewhere in memory, I want to be able to map that memory to the virtual address of local of array * size of array + 1, so even though the block was only 100 at first (my_array[99] is valid), then after the new allocation, I could continue to use the original array with the assumption that it's contiguous in virtual memory, so my_array[100] and my_array[198] are also valid since those would actually be element 0 and 99 of the second array, respectively.
    In other words:

    Code:
    char* my_array = new char[100];
    char* my2_array = new char[100];
    // Somehow map my2_array to my_array + sizeof(*my_array) * 100 + 1
    for (int i = 0; i < 99*2; i += 5)
    {
    	my_array[i] = 'H';
    	my_array[i + 1] = 'e';
    	my_array[i + 2] = 'l';
    	my_array[i + 3] = 'l';
    	my_array[i + 4] = 'o';
    }
    Normally, that would be a bad thing, but I'm wondering if it's possible to make it possible and not a bad thing (not write not owned memory).

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    No, there's no relationship at all between my_array and my2_array which you can exploit.
    They're just contiguous within themselves, not between each other.

    If you want it contiguous, then
    char *p = new char[200];
    char *p2 = p + 100;

    But then you only delete p at the end.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, of course... that's why I wanted to ask if it's possible to map or mirror virtual addresses so the address of my2_array is placed at localtion of my_array + sizeof my_array + 1.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Well, as in the example above, if I allocate a new array somewhere in memory, I want to be able to map that memory to the virtual address of local of array * size of array + 1, so even though the block was only 100 at first (my_array[99] is valid), then after the new allocation, I could continue to use the original array with the assumption that it's contiguous in virtual memory, so my_array[100] and my_array[198] are also valid since those would actually be element 0 and 99 of the second array, respectively.
    In other words:

    Code:
    char* my_array = new char[100];
    char* my2_array = new char[100];
    // Somehow map my2_array to my_array + sizeof(*my_array) * 100 + 1
    for (int i = 0; i < 99*2; i += 5)
    {
    	my_array[i] = 'H';
    	my_array[i + 1] = 'e';
    	my_array[i + 2] = 'l';
    	my_array[i + 3] = 'l';
    	my_array[i + 4] = 'o';
    }
    Normally, that would be a bad thing, but I'm wondering if it's possible to make it possible and not a bad thing (not write not owned memory).
    If you implement the above code and print the address of "my_array[100]" and "my2_array[0]" - yes, I know, [100] is not a valid element in your array, but taking the address of it shouldn't actually cause a problem.

    I think you'll find that they are not "next to each other". they are perhaps quite close. [since both are char *, you could even do "int diff = addr1 - addr2" to see the difference between the two pointers].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Yes, of course... that's why I wanted to ask if it's possible to map or mirror virtual addresses so the address of my2_array is placed at localtion of my_array + sizeof my_array + 1.
    The only way you could do that is if you write your own memory allocator. Aliasing of addresses won't help here, you need a different method of allocating memory so that you can say "make this a continuation of X (my_array for example)" - but you then have to be able to place that memory in the address just after my_array - which assumes that you reserved sufficient space in the first place.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I didn't think of that, of course... Makes sense. There's no gaurantee 100 bytes of contigous space after my_array is free, but still...
    There's basically no OS way to alias/redirect/or whatever the end of my_array to the address of my2_array?

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    I didn't think of that, of course... Makes sense. There's no gaurantee 100 bytes of contigous space after my_array is free, but still...
    There's basically no OS way to alias/redirect/or whatever the end of my_array to the address of my2_array?
    Certainly not if we are talking about arbitrary sizes of arrays - if you could guarantee that all sizes are multiples of 4KB at a time, there's a theoretical possibility of doing it, but as far as I'm aware, there's really no useful API to do this.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Sure, size doesn't matter, as long as I can force my2_array to be placed after my_array in virtual memory.

Popular pages Recent additions subscribe to a feed