2

I am trying to do some tests on X86_64 Linux, and I want to know how to make malloc() allocate return addresses in the range higher than 4 GiB

Do I have to override malloc with a separate/custom library or is there any other simple way to do this?

Thanks.

----Edit----

What I am interested is in the address when taken as value (uintptr_t) and it does not matter whether its virtual or physical address, because, all that I want is the address must be a value greater than 4GiB

I am using gcc (4.2.1) with -m64, on Linux x86_64

(hope I made the question clear)

Ani
  • 1,448
  • 1
  • 16
  • 38
  • How do you know it's not returning a 64-bit pointer? Have you done `sizeof(void *)` to check? –  Mar 17 '11 at 18:46
  • 1
    The whole point of malloc() is that it gives you a block of memory, from the available heap you should not have to care where it is, and certainly cannot specify it. Apart from that the actual address will be a virtual address in any case. – Clifford Mar 17 '11 at 23:09

5 Answers5

5

malloc() is the wrong tool. You want to mmap() /dev/zero (which is what malloc() is doing behind the scenes in modern glibc), IIRC. (On Unix. I believe there is a similar API for Win32, but I couldn't tell you what it is.)

geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • 2
    Well, glibc `malloc()` does `mmap()` for you for allocation requests more that 128kB (tunable). There is no need to open `/dev/zero` for anonymous memory, just pass in `MAP_ANONYMOUS` to [`mmap()`](http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html). – Maxim Egorushkin Mar 17 '11 at 18:52
3

malloc() doesn't give you any way of asking for addresses in a certain range. As described in some of the other answers, if this is just a test you could just keep calling malloc() for more and more memory until you get an answer you like, but that's pretty wasteful.

Use mmap(). If you call like:

mmap(ADDRESS_ABOVE_4GB, size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS, -1, 0)

it'll give you what you want, with pretty much the same semantics as malloc().

If you're trying to cause this to happen for calls to malloc() in code you don't control/have source to, like library code, yeah, you'll have to provide your own implementation of malloc() that does the above.

metamatt
  • 13,809
  • 7
  • 46
  • 56
2

So long as you compile with e.g. gcc -m64 ... (may be the default anyway) and make sure you include the relevant headers (i.e. <stdlib.h> in the case of malloc) then everything should just work. Pointers will be 64 bits, size_t will be 64 bits, and you can malloc as much memory as you like (well up to 2^64-1 bytes anyway, which should be enough for anyone...).

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • I don't think that this answers the question on how to force adresses above 4GiB. – Jens Gustedt Mar 17 '11 at 19:34
  • @Jens: OK, yes, re-reading the question it's a little ambiguous - if the OP clarifies as to what he wants exactly then I'll delete my answer if it's not appropriate or relevant. – Paul R Mar 17 '11 at 20:51
  • @jens: I am using -m64, and what is interest to me is not the _size_ of the pointer, but where the memory it is pointing to lies, and I want that to be in range > 4GiB. Hope I made it clear. – Ani Mar 18 '11 at 08:07
  • @vyom: are you talking about **physical** address > 4 GB or **virtual** address > 4 GB ? Please edit your question to make this clearer. – Paul R Mar 18 '11 at 08:51
0

There isn't a standard way to force malloc() to allocate addresses in a particular range.

However, you can allocate 4 GiB of memory. If it is allocated so that enough of the space is in the high address range, use that space. Otherwise, allocate some more space; it should be allocated with a start address in the high range, but you should check (because a small allocation might still squeeze into space left in the low address range), and keep allocating until the allocated space is in high address range.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

malloc returns back an address that corresponds to an operating system kernel call which will find the "next" available block of memory that fits the size_t requirement.

If you want to ensure that the address is in a particular range, a custom version of malloc won't do the trick, as the actual memory assignment is a relay from the kernel's allocation of memory pages to the process.

That basically means the only other technique left is to keep malloc'ing until your exhaust the below 4GiB memory, or perhaps get lucky and get an address in the range you want. Note that to even get in that range, both your program and the operating system must be compiled to support more that 32 bit addresses, and that implies 64 bit architectures.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138