1467 #ifdef DEBUG
1468 if (MR_GET_TYPE(mrp[i].mr_flags) == MR_PADDING) {
1469 MOBJ_STAT_ADD(exec_padding);
1470 }
1471 #endif
1472 ret = as_map(as, myaddr, mylen, segvn_create, &crargs);
1473 if (ret) {
1474 as_rangeunlock(as);
1475 mmapobj_unmap_exec(mrp, i, start_addr);
1476 return (ret);
1477 }
1478 } else {
1479 /*
1480 * There is a mapping that exists in the range
1481 * so check to see if it was a "reservation"
1482 * from /dev/null. The mapping is from
1483 * /dev/null if the mapping comes from
1484 * segdev and the type is neither MAP_SHARED
1485 * nor MAP_PRIVATE.
1486 */
1487 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
1488 seg = as_findseg(as, myaddr, 0);
1489 MOBJ_STAT_ADD(exec_addr_mapped);
1490 if (seg && seg->s_ops == &segdev_ops &&
1491 ((SEGOP_GETTYPE(seg, myaddr) &
1492 (MAP_SHARED | MAP_PRIVATE)) == 0) &&
1493 myaddr >= seg->s_base &&
1494 myaddr + mylen <=
1495 seg->s_base + seg->s_size) {
1496 MOBJ_STAT_ADD(exec_addr_devnull);
1497 AS_LOCK_EXIT(as, &as->a_lock);
1498 (void) as_unmap(as, myaddr, mylen);
1499 ret = as_map(as, myaddr, mylen, segvn_create,
1500 &crargs);
1501 mrp[i].mr_flags |= MR_RESV;
1502 if (ret) {
1503 as_rangeunlock(as);
1504 /* Need to remap what we unmapped */
1505 mmapobj_unmap_exec(mrp, i + 1,
1506 start_addr);
1507 return (ret);
1508 }
1509 } else {
1510 AS_LOCK_EXIT(as, &as->a_lock);
1511 as_rangeunlock(as);
1512 mmapobj_unmap_exec(mrp, i, start_addr);
1513 MOBJ_STAT_ADD(exec_addr_in_use);
1514 return (EADDRINUSE);
1515 }
1516 }
1517 }
1518 as_rangeunlock(as);
1519 return (0);
1520 }
1521
1522 /*
1523 * Walk through the ELF program headers and extract all useful information
1524 * for PT_LOAD and PT_SUNWBSS segments into mrp.
1525 * Return 0 on success or error on failure.
1526 */
1527 static int
1528 process_phdr(Ehdr *ehdrp, caddr_t phdrbase, int nphdrs, mmapobj_result_t *mrp,
1529 vnode_t *vp, uint_t *num_mapped, size_t padding, cred_t *fcred)
1530 {
|
1467 #ifdef DEBUG
1468 if (MR_GET_TYPE(mrp[i].mr_flags) == MR_PADDING) {
1469 MOBJ_STAT_ADD(exec_padding);
1470 }
1471 #endif
1472 ret = as_map(as, myaddr, mylen, segvn_create, &crargs);
1473 if (ret) {
1474 as_rangeunlock(as);
1475 mmapobj_unmap_exec(mrp, i, start_addr);
1476 return (ret);
1477 }
1478 } else {
1479 /*
1480 * There is a mapping that exists in the range
1481 * so check to see if it was a "reservation"
1482 * from /dev/null. The mapping is from
1483 * /dev/null if the mapping comes from
1484 * segdev and the type is neither MAP_SHARED
1485 * nor MAP_PRIVATE.
1486 */
1487 AS_LOCK_ENTER(as, RW_READER);
1488 seg = as_findseg(as, myaddr, 0);
1489 MOBJ_STAT_ADD(exec_addr_mapped);
1490 if (seg && seg->s_ops == &segdev_ops &&
1491 ((SEGOP_GETTYPE(seg, myaddr) &
1492 (MAP_SHARED | MAP_PRIVATE)) == 0) &&
1493 myaddr >= seg->s_base &&
1494 myaddr + mylen <=
1495 seg->s_base + seg->s_size) {
1496 MOBJ_STAT_ADD(exec_addr_devnull);
1497 AS_LOCK_EXIT(as);
1498 (void) as_unmap(as, myaddr, mylen);
1499 ret = as_map(as, myaddr, mylen, segvn_create,
1500 &crargs);
1501 mrp[i].mr_flags |= MR_RESV;
1502 if (ret) {
1503 as_rangeunlock(as);
1504 /* Need to remap what we unmapped */
1505 mmapobj_unmap_exec(mrp, i + 1,
1506 start_addr);
1507 return (ret);
1508 }
1509 } else {
1510 AS_LOCK_EXIT(as);
1511 as_rangeunlock(as);
1512 mmapobj_unmap_exec(mrp, i, start_addr);
1513 MOBJ_STAT_ADD(exec_addr_in_use);
1514 return (EADDRINUSE);
1515 }
1516 }
1517 }
1518 as_rangeunlock(as);
1519 return (0);
1520 }
1521
1522 /*
1523 * Walk through the ELF program headers and extract all useful information
1524 * for PT_LOAD and PT_SUNWBSS segments into mrp.
1525 * Return 0 on success or error on failure.
1526 */
1527 static int
1528 process_phdr(Ehdr *ehdrp, caddr_t phdrbase, int nphdrs, mmapobj_result_t *mrp,
1529 vnode_t *vp, uint_t *num_mapped, size_t padding, cred_t *fcred)
1530 {
|