This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: other/9830: [pch] not working on Solaris 9
- From: "Michael Teske" <mteske at csksoftware dot com>
- To: Geoff Keating <geoffk at geoffk dot org>
- Cc: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 26 Feb 2003 11:22:03 +0100
- Subject: Re: other/9830: [pch] not working on Solaris 9
- Organization: CSK Software AG
- References: <20030224132612.26862.qmail__21143.0731149905$1046093758@sources.redhat.com> <200302251630.21951.mteske@csksoftware.com> <200302251811.h1PIB0M19100@desire.geoffk.org>
On Tuesday 25 February 2003 19:11, Geoff Keating wrote:
> > From: "Michael Teske" <mteske at csksoftware dot com>
> > Organization: CSK Software AG
> > Date: Tue, 25 Feb 2003 16:30:21 +0100
> >
> > > MAP_FIXED would work if you can find a way to work out whether there's
> > > already something else mapped at that location. I don't have a
> > > Solaris box right now, but I seem to remember that you could read
> > > memory map information out of /proc?
> >
> > Have to look at that, but that might be too os specific, or not?
>
> It would be host-specific, but that's OK; we have ways of dealing with
> such things.
Ok, here's a demo program attached.
solaris_can_safely_be_mmapped() is the function one can use for Solaris
versions newer that Solaris 2.6 (AKA Solaris 6,7,8,9). Older versions do not
have this proc interface.
Hope that helps,
Michael
P.S.: Of course I tested what happens if one overrides an already mapped
region, it's really replacing it and segfaults, so you were right.
Another thing to make it work without this would be to determine the offset
before doing the mmap test and writing the mmi structure to the file. But
from the code as it works now this is not easily archievable, I fear...
--
Michael Teske
<This space is left blank intentionally>
#include <procfs.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
void print_map (void)
{
prmap_t mymap;
char procmapname[64];
FILE *f;
int x;
sprintf(procmapname, "/proc/%ld/map", getpid());
f = fopen(procmapname,"rb");
if (!f) {
perror(procmapname);
return;
}
while (1 == fread (&mymap, sizeof (mymap), 1, f)) {
printf("addr: 0x%lx, size: 0x%lx, offset 0x%lx, %s\n", (long) mymap.pr_vaddr, (long) mymap.pr_size, (long) mymap.pr_offset, mymap.pr_mapname);
}
fclose(f);
}
/* checks the address range if it can safely be mapped with MAP_FIXED
* without unmapping existing stuff
* returns 1 on success, 0 on failure
*/
int solaris_can_safely_be_mmapped (long addr, long size)
{
prmap_t mymap;
char procmapname[64];
FILE *f;
int end;
end = addr+size-1;
sprintf(procmapname, "/proc/%ld/map", getpid());
f = fopen(procmapname,"rb");
if (!f) {
perror(procmapname);
return 0;
}
while (1 == fread (&mymap, sizeof (mymap), 1, f)) {
/* printf("addr: 0x%lx, size: 0x%lx, offset 0x%lx, %s\n", (long) mymap.pr_vaddr, (long) mymap.pr_size, (long) mymap.pr_offset, mymap.pr_mapname);*/
if (mymap.pr_vaddr <= addr && (mymap.pr_vaddr+mymap.pr_size-1) >= addr) {
/* start in existing addr range?!? */
fclose(f);
return 0;
} else if (mymap.pr_vaddr <= end && (mymap.pr_vaddr+mymap.pr_size-1) >= end) {
/* end in existing addr range?!? */
fclose(f);
return 0;
}
}
fclose(f);
return 1;
}
void mmaptest (long mybase, long size)
{
void* base = (void *)mybase;
long offset = 0; /*0x16000;*/
void* addr;
FILE *f = fopen ("mmaptest.bigfile", "r+");
if (f==NULL) return ;
addr = mmap (base, size,
PROT_READ | PROT_WRITE, MAP_PRIVATE| MAP_FIXED,
fileno (f), offset);
printf("base: %p, addr: %p\n", base, addr);
munmap(addr, size);
fclose(f);
return;
}
int main (void)
{
#define NUMADDR 2
unsigned long addrtotest [NUMADDR] = {0xff33a000, 0xfdc00000};
unsigned long sizes [NUMADDR] = {0xa000, 0xc00000};
int i;
print_map();
for (i=0; i< NUMADDR; i++) {
if (solaris_can_safely_be_mmapped( addrtotest[i], sizes[i])) {
mmaptest(addrtotest[i], sizes[i]);
} else {
printf("0x%lx can not be mapped!\n", addrtotest[i]);
}
}
}