/* Return 1 if both offsets point to the same * filename (delimited by whitespace) * Else return 0 */ static int compareoffset(int selfmapfd1, off_t offset1, int selfmapfd2, off_t offset2) { off_t old_offset1 = mtcp_sys_lseek(selfmapfd1, 0, SEEK_CUR); off_t old_offset2 = mtcp_sys_lseek(selfmapfd2, 0, SEEK_CUR); char c1, c2; mtcp_sys_lseek(selfmapfd1, offset1, SEEK_SET); mtcp_sys_lseek(selfmapfd2, offset2, SEEK_SET); do { c1 = mtcp_readchar(selfmapfd1); c2 = mtcp_readchar(selfmapfd2); } while ((c1 == c2) && (c1 != '\n') && (c1 != '\t') && (c1 != '\0')); mtcp_sys_lseek(selfmapfd1, old_offset1, SEEK_SET); mtcp_sys_lseek(selfmapfd2, old_offset2, SEEK_SET); return (c1 == c2) && ((c1 == '\n') || (c1 == '\t') || (c1 == '\0')); }
char mtcp_readdec (int fd, VA *value) { char c; unsigned long int v; v = 0; while (1) { c = mtcp_readchar (fd); if ((c >= '0') && (c <= '9')) c -= '0'; else break; v = v * 10 + c; } *value = (VA)v; return (c); }
char mtcp_readhex (int fd, VA *value) { char c; unsigned long int v; v = 0; while (1) { c = mtcp_readchar (fd); if ((c >= '0') && (c <= '9')) c -= '0'; else if ((c >= 'a') && (c <= 'f')) c -= 'a' - 10; else if ((c >= 'A') && (c <= 'F')) c -= 'A' - 10; else break; v = v * 16 + c; } *value = (VA)v; return (c); }
int mtcp_selfmap_readline(int selfmapfd, VA *startaddr, VA *endaddr, off_t *file_offset) { int rc = 0; char c; if (file_offset != NULL) *file_offset = (off_t)-1; c = mtcp_readhex (selfmapfd, startaddr); if (c == '\0') return 0; /* c == '\0' implies that reached end-of-file */ if (c != '-') goto skipeol; c = mtcp_readhex (selfmapfd, endaddr); if (c != ' ') goto skipeol; skipeol: while ((c != '\0') && (c != '\n')) { if ( (file_offset != NULL) && (*file_offset == (off_t)-1) && ((c == '/') || (c == '[')) ) *file_offset = mtcp_sys_lseek(selfmapfd, 0, SEEK_CUR) - 1; c = mtcp_readchar (selfmapfd); } return 1; /* 1 means successfully read a line */ }
int mtcp_readmapsline (int mapsfd, Area *area, DeviceInfo *dev_info) { char c, rflag, sflag, wflag, xflag; int i; unsigned int long devmajor, devminor, inodenum; VA startaddr, endaddr; c = mtcp_readhex (mapsfd, &startaddr); if (c != '-') { if ((c == 0) && (startaddr == 0)) return (0); goto skipeol; } c = mtcp_readhex (mapsfd, &endaddr); if (c != ' ') goto skipeol; if (endaddr < startaddr) goto skipeol; rflag = c = mtcp_readchar (mapsfd); if ((c != 'r') && (c != '-')) goto skipeol; wflag = c = mtcp_readchar (mapsfd); if ((c != 'w') && (c != '-')) goto skipeol; xflag = c = mtcp_readchar (mapsfd); if ((c != 'x') && (c != '-')) goto skipeol; sflag = c = mtcp_readchar (mapsfd); if ((c != 's') && (c != 'p')) goto skipeol; c = mtcp_readchar (mapsfd); if (c != ' ') goto skipeol; c = mtcp_readhex (mapsfd, (VA *)&devmajor); if (c != ' ') goto skipeol; area -> offset = (off_t)devmajor; c = mtcp_readhex (mapsfd, (VA *)&devmajor); if (c != ':') goto skipeol; c = mtcp_readhex (mapsfd, (VA *)&devminor); if (c != ' ') goto skipeol; c = mtcp_readdec (mapsfd, (VA *)&inodenum); area -> name[0] = '\0'; while (c == ' ') c = mtcp_readchar (mapsfd); if (c == '/' || c == '[') { /* absolute pathname, or [stack], [vdso], etc. */ i = 0; do { area -> name[i++] = c; if (i == sizeof area -> name) goto skipeol; c = mtcp_readchar (mapsfd); } while (c != '\n'); area -> name[i] = '\0'; } if (c != '\n') goto skipeol; area -> addr = startaddr; area -> size = endaddr - startaddr; area -> prot = 0; if (rflag == 'r') area -> prot |= PROT_READ; if (wflag == 'w') area -> prot |= PROT_WRITE; if (xflag == 'x') area -> prot |= PROT_EXEC; area -> flags = MAP_FIXED; if (sflag == 's') area -> flags |= MAP_SHARED; if (sflag == 'p') area -> flags |= MAP_PRIVATE; if (area -> name[0] == '\0') area -> flags |= MAP_ANONYMOUS; if (dev_info != NULL) { dev_info->devmajor = devmajor; dev_info->devminor = devminor; dev_info->inodenum = inodenum; } return (1); skipeol: DPRINTF("ERROR: mtcp readmapsline*: bad maps line <%c", c); while ((c != '\n') && (c != '\0')) { c = mtcp_readchar (mapsfd); mtcp_printf ("%c", c); } mtcp_printf (">\n"); mtcp_abort (); return (0); /* NOTREACHED : stop compiler warning */ }