c - mmap different behavior on intel (i7) and arm? -


I use a program compiled on Open Xisues 13.1 with the Intel Eye processor. I have compiled a similar program in the QMU (virtual environment) so that OpenSite 13.1 can be simulated with an ARM processor. This line of code:

  rvp = mmap (rvp, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fails, 0);  

gives me an indicator for memory in Ram, yet the size of this memory is different between Intel and Arm:

Size "length" on Intel Is independent of the file size indicated by the files.

Size on the ARM (approximate) indicates the size of the file by the field, and ignores the fact that the size is bigger than the field.

I just have to allocate more memory than file ...

EDIT: I successfully tried to solve this problem with two consecutive calls:

  rvp = mmap (tap, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); Unsigned int i; For (i = 0; i & lt; length; i + = 5000) printf ("% i ->% u \ n", i, rvp [i] access buffer;); Rvp = mmap (rvp, height, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fails, 0); For (i = 0; i & lt; length; i + = 5000) printf ("% i ->% u \ n", i, rvp [i] access buffer;);  

As an output to me:

 Access buffer 0 - & gt; 0 ... Access buffer 90000 - & gt; 0 access buffer 0 - & gt; 0 ... 85000 access buffer - & gt; 0 split mistake ...  

This point is not very clear, but please Note:

[memory] within the address range starting from [,] pa and lane byte [,] For the continuation of the whole page after the end of an object will result in the delivery of the SIGBUS signal.

I got stuck in some commas and stressed to clarify the point: If you have mmap larger area than that area which makes it back , Then the OS is considered if you try to proceed at the end of the file, provided you go before a page limit (this license is only because the hardware is accessible from the OS and the inaccessible memory Do not allow to set a boundary between Security that does not have page limits) ( SIGBUS and SIGSEGV are considered interchangeable by now many OS).

You were on the right track with your "two consecutive call" approach, but that did not work because you used the same length for both calls. If you have specified the file size in the second call, it will work. You can retrieve the actual size of the file with the system call. If the file is large from the length of your desired allocation, then you need to care a little bit here, how I will write:

  char * map_file (int Fd, size_t len) {struct stat st; Four * RV .; If (fstat (FD, and ST)) return report_error ("fstat"); If (st.st_size> = (off_t) lane) / / If the file is at least as large as expected, then simply we want to map the part * / RV = MMAP (0, lane, PROT_READ | PROT_WRITE, MAP_PRIVATE , FD, 0); If (RV == MAP_FAILED) return report_up ("mmip"); } Else {/ * Otherwise, we have to allocate anonymous memory to fill the gap. * / Four * Anan; Anon = MMAP (0, lane, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); If (Ann == MAP_FAILED) return report_directory ("mmp (anon)"); RV = MMAP (ANO, (size_TY) st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, FD, 0); If (RV == MAP_FAILED) {int save_errno = errno; (Empty) monum (ion, lane); Errno = save_errno; Return report_r ("mmip"); }} Return RV .; }  

Depending on your large goal, instead you can make sense to expand the file if it is not necessarily large, then use it:

  char * map_file (int fd, size_t len) {struct stat st; Four * RV .; If (fstat (FD, and ST)) return report_error ("fstat"); / * If the file is not as large as expected, then increase it * / if (st.st_size & lt; (off_t) lane) (ftruncate (fd, (off_t) lane)) report refund ("ftruncate"); RV = MMAP (0, lane, PROT_READ | PROT_WRITE, MAP_PRIVATE, FD, 0); If (RV == MAP_FAILED) return report_up ("mmip"); Return RV .; }  

But perhaps, if you wanted the reference, you would use MAP_PRIVATE instead of MAP_SHARED .

>

(NB function report_error is not shown, an error message logs, and then receives zero.)


Comments