diff options
author | tdeval <> | 2005-07-07 05:28:53 +0000 |
---|---|---|
committer | tdeval <> | 2005-07-07 05:28:53 +0000 |
commit | 50b5ffa76644cb9dbead0b4113a3f540cfce026a (patch) | |
tree | 5b5abe06a5605319b7f294459e43717a9484af81 /src | |
parent | 39bb14827920f2df6ef79ef2646a815ff17ff665 (diff) | |
download | openbsd-50b5ffa76644cb9dbead0b4113a3f540cfce026a.tar.gz openbsd-50b5ffa76644cb9dbead0b4113a3f540cfce026a.tar.bz2 openbsd-50b5ffa76644cb9dbead0b4113a3f540cfce026a.zip |
Fix the unmapping of freed pages, leaving just 64k worth of cache pages.
Prodded by art@ and fgsch@, ok deraadt@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 194 |
1 files changed, 136 insertions, 58 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index e3405df39a..5a328b0eb0 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
@@ -8,7 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #if defined(LIBC_SCCS) && !defined(lint) | 10 | #if defined(LIBC_SCCS) && !defined(lint) |
11 | static char rcsid[] = "$OpenBSD: malloc.c,v 1.74 2005/06/07 04:42:42 tedu Exp $"; | 11 | static char rcsid[] = "$OpenBSD: malloc.c,v 1.75 2005/07/07 05:28:53 tdeval Exp $"; |
12 | #endif /* LIBC_SCCS and not lint */ | 12 | #endif /* LIBC_SCCS and not lint */ |
13 | 13 | ||
14 | /* | 14 | /* |
@@ -142,8 +142,9 @@ struct pgfree { | |||
142 | /* A mask for the offset inside a page. */ | 142 | /* A mask for the offset inside a page. */ |
143 | #define malloc_pagemask ((malloc_pagesize)-1) | 143 | #define malloc_pagemask ((malloc_pagesize)-1) |
144 | 144 | ||
145 | #define pageround(foo) (((foo) + (malloc_pagemask)) & ~malloc_pagemask) | 145 | #define pageround(foo) (((foo) + (malloc_pagemask)) & ~malloc_pagemask) |
146 | #define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)+malloc_pageshift) | 146 | #define ptr2index(foo) (((u_long)(foo) >> malloc_pageshift)+malloc_pageshift) |
147 | #define index2ptr(idx) ((void*)(((idx)-malloc_pageshift)<<malloc_pageshift)) | ||
147 | 148 | ||
148 | /* fd of /dev/zero */ | 149 | /* fd of /dev/zero */ |
149 | #ifdef USE_DEV_ZERO | 150 | #ifdef USE_DEV_ZERO |
@@ -211,6 +212,7 @@ static int malloc_freeprot; | |||
211 | 212 | ||
212 | /* use guard pages after allocations? */ | 213 | /* use guard pages after allocations? */ |
213 | static int malloc_guard = 0; | 214 | static int malloc_guard = 0; |
215 | static int malloc_guarded; | ||
214 | /* align pointers to end of page? */ | 216 | /* align pointers to end of page? */ |
215 | static int malloc_ptrguard; | 217 | static int malloc_ptrguard; |
216 | 218 | ||
@@ -396,6 +398,7 @@ malloc_dump(FILE *fd) | |||
396 | fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize); | 398 | fprintf(fd, "Pagesize\t%lu\n", (u_long)malloc_pagesize); |
397 | fprintf(fd, "Pageshift\t%d\n", malloc_pageshift); | 399 | fprintf(fd, "Pageshift\t%d\n", malloc_pageshift); |
398 | fprintf(fd, "In use\t%lu\n", (u_long)malloc_used); | 400 | fprintf(fd, "In use\t%lu\n", (u_long)malloc_used); |
401 | fprintf(fd, "Guarded\t%lu\n", (u_long)malloc_guarded); | ||
399 | } | 402 | } |
400 | #endif /* MALLOC_STATS */ | 403 | #endif /* MALLOC_STATS */ |
401 | 404 | ||
@@ -472,9 +475,9 @@ map_pages(size_t pages) | |||
472 | { | 475 | { |
473 | struct pdinfo *pi, *spi; | 476 | struct pdinfo *pi, *spi; |
474 | struct pginfo **pd; | 477 | struct pginfo **pd; |
475 | u_long pidx,lidx; | 478 | u_long idx, pidx, lidx; |
476 | void *result, *tail; | 479 | void *result, *tail; |
477 | u_long index; | 480 | u_long index, lindex; |
478 | 481 | ||
479 | pages <<= malloc_pageshift; | 482 | pages <<= malloc_pageshift; |
480 | result = MMAP(pages + malloc_guard); | 483 | result = MMAP(pages + malloc_guard); |
@@ -485,23 +488,25 @@ map_pages(size_t pages) | |||
485 | #endif /* MALLOC_EXTRA_SANITY */ | 488 | #endif /* MALLOC_EXTRA_SANITY */ |
486 | return (NULL); | 489 | return (NULL); |
487 | } | 490 | } |
491 | index = ptr2index(result); | ||
488 | tail = result + pages + malloc_guard; | 492 | tail = result + pages + malloc_guard; |
493 | lindex = ptr2index(tail) - 1; | ||
489 | if (malloc_guard) | 494 | if (malloc_guard) |
490 | mprotect(result + pages, malloc_guard, PROT_NONE); | 495 | mprotect(result + pages, malloc_guard, PROT_NONE); |
491 | 496 | ||
492 | if (tail > malloc_brk) | 497 | pidx = PI_IDX(index); |
498 | lidx = PI_IDX(lindex); | ||
499 | |||
500 | if (tail > malloc_brk) { | ||
493 | malloc_brk = tail; | 501 | malloc_brk = tail; |
494 | if ((index = ptr2index(tail) - 1) > last_index) | 502 | last_index = lindex; |
495 | last_index = index; | 503 | } |
496 | 504 | ||
497 | /* Insert directory pages, if needed. */ | 505 | /* Insert directory pages, if needed. */ |
498 | pidx = PI_IDX(ptr2index(result)); | 506 | pdir_lookup(index, &pi); |
499 | lidx = PI_IDX(index); | ||
500 | |||
501 | pdir_lookup(ptr2index(result), &pi); | ||
502 | 507 | ||
503 | for (index=pidx,spi=pi;index<=lidx;index++) { | 508 | for (idx=pidx,spi=pi;idx<=lidx;idx++) { |
504 | if (pi == NULL || PD_IDX(pi->dirnum) != index) { | 509 | if (pi == NULL || PD_IDX(pi->dirnum) != idx) { |
505 | if ((pd = MMAP(malloc_pagesize)) == MAP_FAILED) { | 510 | if ((pd = MMAP(malloc_pagesize)) == MAP_FAILED) { |
506 | errno = ENOMEM; | 511 | errno = ENOMEM; |
507 | munmap(result, tail - result); | 512 | munmap(result, tail - result); |
@@ -515,31 +520,31 @@ map_pages(size_t pages) | |||
515 | pi->base = pd; | 520 | pi->base = pd; |
516 | pi->prev = spi; | 521 | pi->prev = spi; |
517 | pi->next = spi->next; | 522 | pi->next = spi->next; |
518 | pi->dirnum = index * (malloc_pagesize/sizeof(struct pginfo *)); | 523 | pi->dirnum = idx * (malloc_pagesize/sizeof(struct pginfo *)); |
519 | 524 | ||
520 | if (spi->next != NULL) | 525 | if (spi->next != NULL) |
521 | spi->next->prev = pi; | 526 | spi->next->prev = pi; |
522 | spi->next = pi; | 527 | spi->next = pi; |
523 | } | 528 | } |
524 | if (index > pidx && index < lidx) { | 529 | if (idx > pidx && idx < lidx) { |
525 | pi->dirnum += pdi_mod; | 530 | pi->dirnum += pdi_mod; |
526 | } else if (index == pidx) { | 531 | } else if (idx == pidx) { |
527 | if (pidx == lidx) { | 532 | if (pidx == lidx) { |
528 | pi->dirnum += (tail - result) >> malloc_pageshift; | 533 | pi->dirnum += (tail - result) >> malloc_pageshift; |
529 | } else { | 534 | } else { |
530 | pi->dirnum += pdi_mod - PI_OFF(ptr2index(result)); | 535 | pi->dirnum += pdi_mod - PI_OFF(index); |
531 | } | 536 | } |
532 | } else { | 537 | } else { |
533 | pi->dirnum += PI_OFF(ptr2index(tail - 1)) + 1; | 538 | pi->dirnum += PI_OFF(ptr2index(tail - 1)) + 1; |
534 | } | 539 | } |
535 | #ifdef MALLOC_EXTRA_SANITY | 540 | #ifdef MALLOC_EXTRA_SANITY |
536 | if (PD_OFF(pi->dirnum) > pdi_mod || PD_IDX(pi->dirnum) > index) { | 541 | if (PD_OFF(pi->dirnum) > pdi_mod || PD_IDX(pi->dirnum) > idx) { |
537 | wrterror("(ES): pages directory overflow\n"); | 542 | wrterror("(ES): pages directory overflow\n"); |
538 | errno = EFAULT; | 543 | errno = EFAULT; |
539 | return (NULL); | 544 | return (NULL); |
540 | } | 545 | } |
541 | #endif /* MALLOC_EXTRA_SANITY */ | 546 | #endif /* MALLOC_EXTRA_SANITY */ |
542 | if (index == pidx && pi != last_dir) { | 547 | if (idx == pidx && pi != last_dir) { |
543 | prev_dir = last_dir; | 548 | prev_dir = last_dir; |
544 | last_dir = pi; | 549 | last_dir = pi; |
545 | } | 550 | } |
@@ -852,6 +857,7 @@ malloc_pages(size_t size) | |||
852 | } | 857 | } |
853 | 858 | ||
854 | malloc_used += size << malloc_pageshift; | 859 | malloc_used += size << malloc_pageshift; |
860 | malloc_guarded += malloc_guard; | ||
855 | 861 | ||
856 | if (malloc_junk) | 862 | if (malloc_junk) |
857 | memset(p, SOME_JUNK, size << malloc_pageshift); | 863 | memset(p, SOME_JUNK, size << malloc_pageshift); |
@@ -1065,11 +1071,11 @@ malloc_bytes(size_t size) | |||
1065 | } | 1071 | } |
1066 | 1072 | ||
1067 | /* | 1073 | /* |
1068 | * magic so that malloc(sizeof(ptr)) is near the end of the page. | 1074 | * Magic so that malloc(sizeof(ptr)) is near the end of the page. |
1069 | */ | 1075 | */ |
1070 | #define PTR_GAP (malloc_pagesize - sizeof(void *)) | 1076 | #define PTR_GAP (malloc_pagesize - sizeof(void *)) |
1071 | #define PTR_SIZE (sizeof(void *)) | 1077 | #define PTR_SIZE (sizeof(void *)) |
1072 | #define PTR_ALIGNED(p) (((unsigned long)p & malloc_pagemask) == PTR_GAP) | 1078 | #define PTR_ALIGNED(p) (((unsigned long)p & malloc_pagemask) == PTR_GAP) |
1073 | 1079 | ||
1074 | /* | 1080 | /* |
1075 | * Allocate a piece of memory | 1081 | * Allocate a piece of memory |
@@ -1087,8 +1093,8 @@ imalloc(size_t size) | |||
1087 | abort(); | 1093 | abort(); |
1088 | 1094 | ||
1089 | if (malloc_ptrguard && size == PTR_SIZE) { | 1095 | if (malloc_ptrguard && size == PTR_SIZE) { |
1090 | ptralloc = 1; | 1096 | ptralloc = 1; |
1091 | size = malloc_pagesize; | 1097 | size = malloc_pagesize; |
1092 | } | 1098 | } |
1093 | 1099 | ||
1094 | if ((size + malloc_pagesize) < size) { /* Check for overflow */ | 1100 | if ((size + malloc_pagesize) < size) { /* Check for overflow */ |
@@ -1107,7 +1113,7 @@ imalloc(size_t size) | |||
1107 | memset(result, 0, size); | 1113 | memset(result, 0, size); |
1108 | 1114 | ||
1109 | if (result && ptralloc) | 1115 | if (result && ptralloc) |
1110 | return ((char *)result + PTR_GAP); | 1116 | return ((char *)result + PTR_GAP); |
1111 | return (result); | 1117 | return (result); |
1112 | } | 1118 | } |
1113 | 1119 | ||
@@ -1133,18 +1139,17 @@ irealloc(void *ptr, size_t size) | |||
1133 | } | 1139 | } |
1134 | 1140 | ||
1135 | if (malloc_ptrguard && PTR_ALIGNED(ptr)) { | 1141 | if (malloc_ptrguard && PTR_ALIGNED(ptr)) { |
1136 | if (size <= PTR_SIZE) | 1142 | if (size <= PTR_SIZE) { |
1137 | return (ptr); | 1143 | return (ptr); |
1138 | else { | 1144 | } else { |
1139 | p = imalloc(size); | 1145 | p = imalloc(size); |
1140 | if (p) | 1146 | if (p) |
1141 | memcpy(p, ptr, PTR_SIZE); | 1147 | memcpy(p, ptr, PTR_SIZE); |
1142 | ifree(ptr); | 1148 | ifree(ptr); |
1143 | return (p); | 1149 | return (p); |
1144 | } | 1150 | } |
1145 | } | 1151 | } |
1146 | 1152 | ||
1147 | |||
1148 | index = ptr2index(ptr); | 1153 | index = ptr2index(ptr); |
1149 | 1154 | ||
1150 | if (index < malloc_pageshift) { | 1155 | if (index < malloc_pageshift) { |
@@ -1240,7 +1245,7 @@ irealloc(void *ptr, size_t size) | |||
1240 | } | 1245 | } |
1241 | 1246 | ||
1242 | } else { | 1247 | } else { |
1243 | wrtwarning("pointer to wrong page\n"); | 1248 | wrtwarning("irealloc: pointer to wrong page\n"); |
1244 | return (NULL); | 1249 | return (NULL); |
1245 | } | 1250 | } |
1246 | 1251 | ||
@@ -1268,7 +1273,7 @@ irealloc(void *ptr, size_t size) | |||
1268 | static __inline__ void | 1273 | static __inline__ void |
1269 | free_pages(void *ptr, u_long index, struct pginfo *info) | 1274 | free_pages(void *ptr, u_long index, struct pginfo *info) |
1270 | { | 1275 | { |
1271 | u_long i, l; | 1276 | u_long i, l, cachesize = 0; |
1272 | struct pginfo **pd; | 1277 | struct pginfo **pd; |
1273 | struct pdinfo *pi, *spi; | 1278 | struct pdinfo *pi, *spi; |
1274 | u_long pidx, lidx; | 1279 | u_long pidx, lidx; |
@@ -1281,7 +1286,7 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
1281 | } | 1286 | } |
1282 | 1287 | ||
1283 | if (info != MALLOC_FIRST) { | 1288 | if (info != MALLOC_FIRST) { |
1284 | wrtwarning("pointer to wrong page\n"); | 1289 | wrtwarning("free_pages: pointer to wrong page\n"); |
1285 | return; | 1290 | return; |
1286 | } | 1291 | } |
1287 | 1292 | ||
@@ -1330,6 +1335,7 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
1330 | memset(ptr, SOME_JUNK, l); | 1335 | memset(ptr, SOME_JUNK, l); |
1331 | 1336 | ||
1332 | malloc_used -= l; | 1337 | malloc_used -= l; |
1338 | malloc_guarded -= malloc_guard; | ||
1333 | if (malloc_guard) { | 1339 | if (malloc_guard) { |
1334 | #ifdef MALLOC_EXTRA_SANITY | 1340 | #ifdef MALLOC_EXTRA_SANITY |
1335 | if (pi == NULL || PD_IDX(pi->dirnum) != PI_IDX(index+i)) { | 1341 | if (pi == NULL || PD_IDX(pi->dirnum) != PI_IDX(index+i)) { |
@@ -1371,9 +1377,18 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
1371 | 1377 | ||
1372 | /* Find the right spot, leave pf pointing to the modified entry. */ | 1378 | /* Find the right spot, leave pf pointing to the modified entry. */ |
1373 | 1379 | ||
1374 | for(pf = free_list.next; (pf->page+pf->size) < ptr && pf->next != NULL; | 1380 | /* Race ahead here, while calculating cache size. */ |
1375 | pf = pf->next) | 1381 | for (pf = free_list.next; |
1376 | ; /* Race ahead here. */ | 1382 | (pf->page + pf->size) < ptr && pf->next != NULL; |
1383 | pf = pf->next) | ||
1384 | cachesize += pf->size; | ||
1385 | |||
1386 | /* Finish cache size calculation. */ | ||
1387 | pt = pf; | ||
1388 | while (pt) { | ||
1389 | cachesize += pt->size; | ||
1390 | pt = pt->next; | ||
1391 | } | ||
1377 | 1392 | ||
1378 | if (pf->page > tail) { | 1393 | if (pf->page > tail) { |
1379 | /* Insert before entry */ | 1394 | /* Insert before entry */ |
@@ -1385,6 +1400,7 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
1385 | px = NULL; | 1400 | px = NULL; |
1386 | } else if ((pf->page + pf->size) == ptr ) { | 1401 | } else if ((pf->page + pf->size) == ptr ) { |
1387 | /* Append to the previous entry. */ | 1402 | /* Append to the previous entry. */ |
1403 | cachesize -= pf->size; | ||
1388 | pf->size += l; | 1404 | pf->size += l; |
1389 | if (pf->next != NULL && (pf->page + pf->size) == pf->next->page ) { | 1405 | if (pf->next != NULL && (pf->page + pf->size) == pf->next->page ) { |
1390 | /* And collapse the next too. */ | 1406 | /* And collapse the next too. */ |
@@ -1396,6 +1412,7 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
1396 | } | 1412 | } |
1397 | } else if (pf->page == tail) { | 1413 | } else if (pf->page == tail) { |
1398 | /* Prepend to entry. */ | 1414 | /* Prepend to entry. */ |
1415 | cachesize -= pf->size; | ||
1399 | pf->size += l; | 1416 | pf->size += l; |
1400 | pf->page = ptr; | 1417 | pf->page = ptr; |
1401 | pf->pdir = spi; | 1418 | pf->pdir = spi; |
@@ -1419,34 +1436,32 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
1419 | } | 1436 | } |
1420 | 1437 | ||
1421 | /* Return something to OS ? */ | 1438 | /* Return something to OS ? */ |
1422 | if (pf->next == NULL && /* If we're the last one, */ | 1439 | if (pf->size > (malloc_cache - cachesize)) { |
1423 | pf->size > malloc_cache && /* ..and the cache is full, */ | ||
1424 | (pf->page + pf->size) == malloc_brk) { /* ..and none behind us, */ | ||
1425 | 1440 | ||
1426 | /* | 1441 | /* |
1427 | * Keep the cache intact. Notice that the '>' above guarantees that | 1442 | * Keep the cache intact. Notice that the '>' above guarantees that |
1428 | * the pf will always have at least one page afterwards. | 1443 | * the pf will always have at least one page afterwards. |
1429 | */ | 1444 | */ |
1430 | if (munmap((char *)pf->page + malloc_cache, pf->size - malloc_cache)!=0) | 1445 | if (munmap((char *)pf->page + (malloc_cache - cachesize), |
1446 | pf->size - (malloc_cache - cachesize)) != 0) | ||
1431 | goto not_return; | 1447 | goto not_return; |
1432 | tail = pf->page + pf->size; | 1448 | tail = pf->page + pf->size; |
1433 | lidx = ptr2index(tail) - 1; | 1449 | lidx = ptr2index(tail) - 1; |
1434 | pf->size = malloc_cache; | 1450 | pf->size = malloc_cache - cachesize; |
1435 | 1451 | ||
1436 | malloc_brk = pf->page + malloc_cache; | 1452 | index = ptr2index(pf->page + pf->size); |
1437 | |||
1438 | index = ptr2index(malloc_brk); | ||
1439 | 1453 | ||
1440 | pidx = PI_IDX(index); | 1454 | pidx = PI_IDX(index); |
1441 | if (prev_dir != NULL && PD_IDX(prev_dir->dirnum) >= pidx) | 1455 | if (prev_dir != NULL && PD_IDX(prev_dir->dirnum) >= pidx) |
1442 | prev_dir = NULL; /* Will be wiped out below ! */ | 1456 | prev_dir = NULL; /* Will be wiped out below ! */ |
1443 | 1457 | ||
1444 | for (pi=pf->pdir; pi!=NULL && PD_IDX(pi->dirnum)<pidx; pi=pi->next); | 1458 | for (pi=pf->pdir; pi!=NULL && PD_IDX(pi->dirnum)<pidx; pi=pi->next); |
1445 | 1459 | ||
1460 | spi = pi; | ||
1446 | if (pi != NULL && PD_IDX(pi->dirnum) == pidx) { | 1461 | if (pi != NULL && PD_IDX(pi->dirnum) == pidx) { |
1447 | pd = pi->base; | 1462 | pd = pi->base; |
1448 | 1463 | ||
1449 | for(i=index;i <= last_index;) { | 1464 | for(i=index;i <= lidx;) { |
1450 | if (pd[PI_OFF(i)] != MALLOC_NOT_MINE) { | 1465 | if (pd[PI_OFF(i)] != MALLOC_NOT_MINE) { |
1451 | pd[PI_OFF(i)] = MALLOC_NOT_MINE; | 1466 | pd[PI_OFF(i)] = MALLOC_NOT_MINE; |
1452 | #ifdef MALLOC_EXTRA_SANITY | 1467 | #ifdef MALLOC_EXTRA_SANITY |
@@ -1458,12 +1473,19 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
1458 | #endif /* MALLOC_EXTRA_SANITY */ | 1473 | #endif /* MALLOC_EXTRA_SANITY */ |
1459 | pi->dirnum--; | 1474 | pi->dirnum--; |
1460 | } | 1475 | } |
1476 | #ifdef MALLOC_EXTRA_SANITY | ||
1477 | else | ||
1478 | wrtwarning("(ES): page already unmapped\n"); | ||
1479 | #endif /* MALLOC_EXTRA_SANITY */ | ||
1461 | i++; | 1480 | i++; |
1462 | if (!PI_OFF(i)) { | 1481 | if (!PI_OFF(i)) { |
1463 | /* If no page in that dir, free directory page. */ | 1482 | /* If no page in that dir, free directory page. */ |
1464 | if (!PD_OFF(pi->dirnum)) { | 1483 | if (!PD_OFF(pi->dirnum)) { |
1465 | /* Remove from list. */ | 1484 | /* Remove from list. */ |
1466 | pi->prev->next = pi->next; | 1485 | if (spi == pi) /* Update spi only if first. */ |
1486 | spi = pi->prev; | ||
1487 | if (pi->prev != NULL) | ||
1488 | pi->prev->next = pi->next; | ||
1467 | if (pi->next != NULL) | 1489 | if (pi->next != NULL) |
1468 | pi->next->prev = pi->prev; | 1490 | pi->next->prev = pi->prev; |
1469 | pi = pi->next; | 1491 | pi = pi->next; |
@@ -1475,11 +1497,65 @@ free_pages(void *ptr, u_long index, struct pginfo *info) | |||
1475 | pd = pi->base; | 1497 | pd = pi->base; |
1476 | } | 1498 | } |
1477 | } | 1499 | } |
1500 | if (pi && !PD_OFF(pi->dirnum)) { | ||
1501 | /* Resulting page dir is now empty. */ | ||
1502 | /* Remove from list. */ | ||
1503 | if (spi == pi) /* Update spi only if first. */ | ||
1504 | spi = pi->prev; | ||
1505 | if (pi->prev != NULL) | ||
1506 | pi->prev->next = pi->next; | ||
1507 | if (pi->next != NULL) | ||
1508 | pi->next->prev = pi->prev; | ||
1509 | pi = pi->next; | ||
1510 | munmap(pd, malloc_pagesize); | ||
1511 | } | ||
1478 | } | 1512 | } |
1479 | 1513 | ||
1480 | last_index = index - 1; | 1514 | if (pi == NULL && malloc_brk == tail) { |
1515 | /* Resize down the malloc upper boundary. */ | ||
1516 | last_index = index - 1; | ||
1517 | malloc_brk = index2ptr(index); | ||
1518 | } | ||
1481 | 1519 | ||
1482 | /* XXX: We could realloc/shrink the pagedir here I guess. */ | 1520 | /* XXX: We could realloc/shrink the pagedir here I guess. */ |
1521 | if (pf->size == 0) { /* Remove from free-list as well. */ | ||
1522 | if (px) | ||
1523 | ifree(px); | ||
1524 | if ((px = pf->prev) != &free_list) { | ||
1525 | if (pi == NULL && last_index == (index - 1)) { | ||
1526 | if (spi == NULL) { | ||
1527 | malloc_brk = NULL; | ||
1528 | i = 11; | ||
1529 | } else { | ||
1530 | pd = spi->base; | ||
1531 | if (PD_IDX(spi->dirnum) < pidx) | ||
1532 | index = ((PD_IDX(spi->dirnum) + 1) * pdi_mod) - 1; | ||
1533 | for (pi=spi,i=index;pd[PI_OFF(i)]==MALLOC_NOT_MINE;i--) | ||
1534 | #ifdef MALLOC_EXTRA_SANITY | ||
1535 | if (!PI_OFF(i)) { /* Should never enter here. */ | ||
1536 | pi = pi->prev; | ||
1537 | if (pi == NULL || i == 0) | ||
1538 | break; | ||
1539 | pd = pi->base; | ||
1540 | i = (PD_IDX(pi->dirnum) + 1) * pdi_mod; | ||
1541 | } | ||
1542 | #else /* !MALLOC_EXTRA_SANITY */ | ||
1543 | { } | ||
1544 | #endif /* MALLOC_EXTRA_SANITY */ | ||
1545 | malloc_brk = index2ptr(i + 1); | ||
1546 | } | ||
1547 | last_index = i; | ||
1548 | } | ||
1549 | if ((px->next = pf->next) != NULL) | ||
1550 | px->next->prev = px; | ||
1551 | } else { | ||
1552 | if ((free_list.next = pf->next) != NULL) | ||
1553 | free_list.next->prev = &free_list; | ||
1554 | } | ||
1555 | px = pf; | ||
1556 | last_dir = prev_dir; | ||
1557 | prev_dir = NULL; | ||
1558 | } | ||
1483 | } | 1559 | } |
1484 | not_return: | 1560 | not_return: |
1485 | if (pt != NULL) | 1561 | if (pt != NULL) |
@@ -1607,17 +1683,19 @@ ifree(void *ptr) | |||
1607 | return; | 1683 | return; |
1608 | 1684 | ||
1609 | if (malloc_ptrguard && PTR_ALIGNED(ptr)) | 1685 | if (malloc_ptrguard && PTR_ALIGNED(ptr)) |
1610 | ptr = (char *)ptr - PTR_GAP; | 1686 | ptr = (char *)ptr - PTR_GAP; |
1611 | 1687 | ||
1612 | index = ptr2index(ptr); | 1688 | index = ptr2index(ptr); |
1613 | 1689 | ||
1614 | if (index < malloc_pageshift) { | 1690 | if (index < malloc_pageshift) { |
1615 | wrtwarning("junk pointer, too low to make sense\n"); | 1691 | warnx("(%p)", ptr); |
1692 | wrtwarning("ifree: junk pointer, too low to make sense\n"); | ||
1616 | return; | 1693 | return; |
1617 | } | 1694 | } |
1618 | 1695 | ||
1619 | if (index > last_index) { | 1696 | if (index > last_index) { |
1620 | wrtwarning("junk pointer, too high to make sense\n"); | 1697 | warnx("(%p)", ptr); |
1698 | wrtwarning("ifree: junk pointer, too high to make sense\n"); | ||
1621 | return; | 1699 | return; |
1622 | } | 1700 | } |
1623 | 1701 | ||