I am studying the layout of Linux memory space on x86_64 systems and wanted to print some addresses from some sections. I used this Rust code:
fn main() { let x = 3; // should be stored on stack let s = "hello"; // should be in the .data section println!("stack β {:p}", &x); println!(".text β {:p}", main as *const ()); println!(".data β {:p}", s); use std::io; let mut f = std::fs::File::open("/proc/self/maps").unwrap(); let out = io::stdout(); io::copy(&mut f, &mut out.lock()).unwrap(); }
This code also outputs the file /proc/self/maps to stdout. I compiled this mem.rs file simply with rustc mem.rs He typed:
stack β 0x7ffffbf82f2c .text β 0x7f45b7c0a2b0 .data β 0x7f45b7c4d35b 7f45b6800000-7f45b6c00000 rw
At least the addresses that I typed myself seem to match what maps says. But when I execute cat /proc/self/maps in the terminal, I get this output:
00400000-0040b000 rx- 00000000 00:00 107117 /bin/cat 0060a000-0060b000 r
The last result corresponds to everything I read about this section: sections from the executable are displayed at the lower end of the virtual address space (starting from 0x400000).
I executed and compiled everything in the Linux subsystem for Windows (mostly Ubuntu 14.04). I know this is new and more, but I am sure that this is not a problem with the subsystem (please tell me if this is so!). Rust 1.14 is what matters (I doubt)
I also tried the same with C program (sorry, probably bad C):
#include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> int main(int argc, char **argv) { FILE *test_file; char buf[4096]; if ((test_file = fopen ("/proc/self/maps", "r")) != NULL) { while (!feof (test_file)) { fgets (buf, sizeof (buf), test_file); puts (buf); } } return 0; }
It outputs something similar to cat :
00400000-00401000 rx- 00000000 00:00 1325490 /home/lukas/tmp/a.out 00600000-00601000 r--- 00000000 00:00 1325490 /home/lukas/tmp/a.out 00601000-00602000 rw-- 00001000 00:00 1325490 /home/lukas/tmp/a.out
Why is the Rust executable mapped to large addresses near the stack?