diff --git a/headers/private/kernel/vm.h b/headers/private/kernel/vm.h index 7c0c403d81..399d0eb9ff 100644 --- a/headers/private/kernel/vm.h +++ b/headers/private/kernel/vm.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -67,7 +67,7 @@ area_id vm_map_physical_memory(team_id team, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 protection, addr_t phys_addr); area_id vm_map_file(team_id aid, const char *name, void **address, uint32 addressSpec, addr_t size, uint32 protection, uint32 mapping, - int fd, off_t offset); + bool unmapAddressRange, int fd, off_t offset); struct VMCache *vm_area_get_locked_cache(struct vm_area *area); void vm_area_put_locked_cache(struct VMCache *cache); area_id vm_create_null_area(team_id team, const char *name, void **address, @@ -87,7 +87,7 @@ bool vm_test_map_modification(struct vm_page *page); int32 vm_test_map_activation(struct vm_page *page, bool *_modified); void vm_clear_map_flags(struct vm_page *page, uint32 flags); void vm_remove_all_page_mappings(struct vm_page *page, uint32 *_flags); -bool vm_unmap_page(struct vm_area* area, addr_t virtualAddress, +bool vm_unmap_page(struct vm_area* area, addr_t virtualAddress, bool preserveModified); status_t vm_unmap_pages(struct vm_area *area, addr_t base, size_t length, bool preserveModified); @@ -121,7 +121,8 @@ area_id _user_create_area(const char *name, void **address, uint32 addressSpec, status_t _user_delete_area(area_id area); area_id _user_map_file(const char *uname, void **uaddress, int addressSpec, - size_t size, int protection, int mapping, int fd, off_t offset); + size_t size, int protection, int mapping, bool unmapAddressRange, + int fd, off_t offset); status_t _user_unmap_memory(void *address, size_t size); status_t _user_set_memory_protection(void* address, size_t size, int protection); diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index bf63f8bb8c..fb36a34907 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -140,21 +140,27 @@ extern thread_id _kern_find_thread(const char *name); extern status_t _kern_suspend_thread(thread_id thread); extern status_t _kern_resume_thread(thread_id thread); extern status_t _kern_rename_thread(thread_id thread, const char *newName); -extern status_t _kern_set_thread_priority(thread_id thread, int32 newPriority); +extern status_t _kern_set_thread_priority(thread_id thread, + int32 newPriority); extern status_t _kern_kill_thread(thread_id thread); extern void _kern_exit_thread(status_t returnValue); extern void _kern_thread_yield(void); -extern status_t _kern_wait_for_thread(thread_id thread, status_t *_returnCode); +extern status_t _kern_wait_for_thread(thread_id thread, + status_t *_returnCode); extern bool _kern_has_data(thread_id thread); -extern status_t _kern_send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize); -extern int32 _kern_receive_data(thread_id *_sender, void *buffer, size_t bufferSize); +extern status_t _kern_send_data(thread_id thread, int32 code, + const void *buffer, size_t bufferSize); +extern int32 _kern_receive_data(thread_id *_sender, void *buffer, + size_t bufferSize); extern int64 _kern_restore_signal_frame(); extern status_t _kern_get_thread_info(thread_id id, thread_info *info); -extern status_t _kern_get_next_thread_info(team_id team, int32 *cookie, thread_info *info); +extern status_t _kern_get_next_thread_info(team_id team, int32 *cookie, + thread_info *info); extern status_t _kern_get_team_info(team_id id, team_info *info); extern status_t _kern_get_next_team_info(int32 *cookie, team_info *info); -extern status_t _kern_get_team_usage_info(team_id team, int32 who, team_usage_info *info, size_t size); +extern status_t _kern_get_team_usage_info(team_id team, int32 who, + team_usage_info *info, size_t size); extern status_t _kern_block_thread(uint32 flags, bigtime_t timeout); extern status_t _kern_unblock_thread(thread_id thread, status_t status); @@ -189,8 +195,10 @@ extern image_id _kern_register_image(image_info *info, size_t size); extern status_t _kern_unregister_image(image_id id); extern void _kern_image_relocated(image_id id); extern void _kern_loading_app_failed(status_t error); -extern status_t _kern_get_image_info(image_id id, image_info *info, size_t size); -extern status_t _kern_get_next_image_info(team_id team, int32 *cookie, image_info *info, size_t size); +extern status_t _kern_get_image_info(image_id id, image_info *info, + size_t size); +extern status_t _kern_get_next_image_info(team_id team, int32 *cookie, + image_info *info, size_t size); extern status_t _kern_read_kernel_image_symbols(image_id id, struct Elf32_Sym* symbolTable, int32* _symbolCount, char* stringTable, size_t* _stringTableSize, @@ -198,19 +206,24 @@ extern status_t _kern_read_kernel_image_symbols(image_id id, // VFS functions extern dev_t _kern_mount(const char *path, const char *device, - const char *fs_name, uint32 flags, const char *args, size_t argsLength); + const char *fs_name, uint32 flags, const char *args, + size_t argsLength); extern status_t _kern_unmount(const char *path, uint32 flags); extern status_t _kern_read_fs_info(dev_t device, struct fs_info *info); -extern status_t _kern_write_fs_info(dev_t device, const struct fs_info *info, int mask); +extern status_t _kern_write_fs_info(dev_t device, const struct fs_info *info, + int mask); extern dev_t _kern_next_device(int32 *_cookie); extern status_t _kern_sync(void); extern status_t _kern_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf, char *userPath, size_t pathLength); extern status_t _kern_normalize_path(const char* userPath, bool traverseLink, char* buffer); -extern int _kern_open_entry_ref(dev_t device, ino_t inode, const char *name, int openMode, int perms); -extern int _kern_open(int fd, const char *path, int openMode, int perms); -extern int _kern_open_dir_entry_ref(dev_t device, ino_t inode, const char *name); +extern int _kern_open_entry_ref(dev_t device, ino_t inode, + const char *name, int openMode, int perms); +extern int _kern_open(int fd, const char *path, int openMode, + int perms); +extern int _kern_open_dir_entry_ref(dev_t device, ino_t inode, + const char *name); extern int _kern_open_dir(int fd, const char *path); extern int _kern_open_parent_dir(int fd, char *name, size_t nameLength); @@ -218,7 +231,8 @@ extern status_t _kern_fcntl(int fd, int op, uint32 argument); extern status_t _kern_fsync(int fd); extern status_t _kern_flock(int fd, int op); extern off_t _kern_seek(int fd, off_t pos, int seekType); -extern status_t _kern_create_dir_entry_ref(dev_t device, ino_t inode, const char *name, int perms); +extern status_t _kern_create_dir_entry_ref(dev_t device, ino_t inode, + const char *name, int perms); extern status_t _kern_create_dir(int fd, const char *path, int perms); extern status_t _kern_remove_dir(int fd, const char *path); extern status_t _kern_read_link(int fd, const char *path, char *buffer, @@ -235,30 +249,39 @@ extern status_t _kern_access(const char *path, int mode); extern ssize_t _kern_select(int numfds, struct fd_set *readSet, struct fd_set *writeSet, struct fd_set *errorSet, bigtime_t timeout, const sigset_t *sigMask); -extern ssize_t _kern_poll(struct pollfd *fds, int numfds, bigtime_t timeout); +extern ssize_t _kern_poll(struct pollfd *fds, int numFDs, + bigtime_t timeout); extern int _kern_open_attr_dir(int fd, const char *path); -extern int _kern_create_attr(int fd, const char *name, uint32 type, int openMode); +extern int _kern_create_attr(int fd, const char *name, uint32 type, + int openMode); extern int _kern_open_attr(int fd, const char *name, int openMode); extern status_t _kern_remove_attr(int fd, const char *name); -extern status_t _kern_rename_attr(int fromFile, const char *fromName, int toFile, const char *toName); +extern status_t _kern_rename_attr(int fromFile, const char *fromName, + int toFile, const char *toName); extern int _kern_open_index_dir(dev_t device); -extern status_t _kern_create_index(dev_t device, const char *name, uint32 type, uint32 flags); -extern status_t _kern_read_index_stat(dev_t device, const char *name, struct stat *stat); +extern status_t _kern_create_index(dev_t device, const char *name, + uint32 type, uint32 flags); +extern status_t _kern_read_index_stat(dev_t device, const char *name, + struct stat *stat); extern status_t _kern_remove_index(dev_t device, const char *name); extern status_t _kern_getcwd(char *buffer, size_t size); extern status_t _kern_setcwd(int fd, const char *path); -extern int _kern_open_query(dev_t device, const char *query, size_t queryLength, - uint32 flags, port_id port, int32 token); +extern int _kern_open_query(dev_t device, const char *query, + size_t queryLength, uint32 flags, port_id port, + int32 token); // file descriptor functions -extern ssize_t _kern_read(int fd, off_t pos, void *buffer, size_t bufferSize); -extern ssize_t _kern_readv(int fd, off_t pos, const struct iovec *vecs, size_t count); -extern ssize_t _kern_write(int fd, off_t pos, const void *buffer, size_t bufferSize); +extern ssize_t _kern_read(int fd, off_t pos, void *buffer, + size_t bufferSize); +extern ssize_t _kern_readv(int fd, off_t pos, const struct iovec *vecs, + size_t count); +extern ssize_t _kern_write(int fd, off_t pos, const void *buffer, + size_t bufferSize); extern ssize_t _kern_writev(int fd, off_t pos, const struct iovec *vecs, size_t count); extern status_t _kern_ioctl(int fd, ulong cmd, void *data, size_t length); -extern ssize_t _kern_read_dir(int fd, struct dirent *buffer, size_t bufferSize, - uint32 maxCount); +extern ssize_t _kern_read_dir(int fd, struct dirent *buffer, + size_t bufferSize, uint32 maxCount); extern status_t _kern_rewind_dir(int fd); extern status_t _kern_read_stat(int fd, const char *path, bool traverseLink, struct stat *stat, size_t statSize); @@ -320,34 +343,43 @@ extern status_t _kern_stop_watching(dev_t device, ino_t node, port_id port, // time functions extern status_t _kern_set_real_time_clock(uint32 time); -extern status_t _kern_set_timezone(int32 timezoneOffset, bool daylightSavingTime); -extern status_t _kern_get_timezone(int32 *_timezoneOffset, bool *_daylightSavingTime); -extern status_t _kern_set_tzfilename(const char *filename, size_t length, bool isGMT); -extern status_t _kern_get_tzfilename(char *filename, size_t length, bool *_isGMT); +extern status_t _kern_set_timezone(int32 timezoneOffset, + bool daylightSavingTime); +extern status_t _kern_get_timezone(int32 *_timezoneOffset, + bool *_daylightSavingTime); +extern status_t _kern_set_tzfilename(const char *filename, size_t length, + bool isGMT); +extern status_t _kern_get_tzfilename(char *filename, size_t length, + bool *_isGMT); extern bigtime_t _kern_system_time(); extern status_t _kern_snooze_etc(bigtime_t time, int timebase, int32 flags); // area functions -extern area_id _kern_create_area(const char *name, void **address, uint32 addressSpec, - size_t size, uint32 lock, uint32 protection); +extern area_id _kern_create_area(const char *name, void **address, + uint32 addressSpec, size_t size, uint32 lock, + uint32 protection); extern status_t _kern_delete_area(area_id area); extern area_id _kern_area_for(void *address); extern area_id _kern_find_area(const char *name); extern status_t _kern_get_area_info(area_id area, area_info *info); -extern status_t _kern_get_next_area_info(team_id team, int32 *cookie, area_info *info); +extern status_t _kern_get_next_area_info(team_id team, int32 *cookie, + area_info *info); extern status_t _kern_resize_area(area_id area, size_t newSize); -extern area_id _kern_transfer_area(area_id area, void **_address, uint32 addressSpec, - team_id target); -extern status_t _kern_set_area_protection(area_id area, uint32 newProtection); -extern area_id _kern_clone_area(const char *name, void **_address, uint32 addressSpec, - uint32 protection, area_id sourceArea); -extern status_t _kern_reserve_heap_address_range(addr_t* _address, uint32 addressSpec, - addr_t size); +extern area_id _kern_transfer_area(area_id area, void **_address, + uint32 addressSpec, team_id target); +extern status_t _kern_set_area_protection(area_id area, + uint32 newProtection); +extern area_id _kern_clone_area(const char *name, void **_address, + uint32 addressSpec, uint32 protection, + area_id sourceArea); +extern status_t _kern_reserve_heap_address_range(addr_t* _address, + uint32 addressSpec, addr_t size); extern area_id _kern_map_file(const char *name, void **address, int addressSpec, size_t size, int protection, - int mapping, int fd, off_t offset); + int mapping, bool unmapAddressRange, int fd, + off_t offset); extern status_t _kern_unmap_memory(void *address, size_t size); extern status_t _kern_set_memory_protection(void *address, size_t size, int protection); @@ -361,14 +393,18 @@ extern status_t _kern_close_port(port_id id); extern status_t _kern_delete_port(port_id id); extern port_id _kern_find_port(const char *port_name); extern status_t _kern_get_port_info(port_id id, struct port_info *info); -extern status_t _kern_get_next_port_info(team_id team, int32 *cookie, struct port_info *info); -extern ssize_t _kern_port_buffer_size_etc(port_id port, uint32 flags, bigtime_t timeout); +extern status_t _kern_get_next_port_info(team_id team, int32 *cookie, + struct port_info *info); +extern ssize_t _kern_port_buffer_size_etc(port_id port, uint32 flags, + bigtime_t timeout); extern int32 _kern_port_count(port_id port); -extern ssize_t _kern_read_port_etc(port_id port, int32 *msgCode, void *msgBuffer, - size_t bufferSize, uint32 flags, bigtime_t timeout); +extern ssize_t _kern_read_port_etc(port_id port, int32 *msgCode, + void *msgBuffer, size_t bufferSize, uint32 flags, + bigtime_t timeout); extern status_t _kern_set_port_owner(port_id port, team_id team); -extern status_t _kern_write_port_etc(port_id port, int32 msgCode, const void *msgBuffer, - size_t bufferSize, uint32 flags, bigtime_t timeout); +extern status_t _kern_write_port_etc(port_id port, int32 msgCode, + const void *msgBuffer, size_t bufferSize, uint32 flags, + bigtime_t timeout); extern status_t _kern_writev_port_etc(port_id id, int32 msgCode, const struct iovec *msgVecs, size_t vecCount, size_t bufferSize, uint32 flags, bigtime_t timeout); @@ -403,7 +439,8 @@ extern status_t _kern_system_profiler_stop(); /* atomic_* ops (needed for CPUs that don't support them directly) */ #ifdef ATOMIC_FUNCS_ARE_SYSCALLS extern int32 _kern_atomic_set(vint32 *value, int32 newValue); -extern int32 _kern_atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst); +extern int32 _kern_atomic_test_and_set(vint32 *value, int32 newValue, + int32 testAgainst); extern int32 _kern_atomic_add(vint32 *value, int32 addValue); extern int32 _kern_atomic_and(vint32 *value, int32 andValue); extern int32 _kern_atomic_or(vint32 *value, int32 orValue); @@ -412,7 +449,8 @@ extern int32 _kern_atomic_get(vint32 *value); #ifdef ATOMIC64_FUNCS_ARE_SYSCALLS extern int64 _kern_atomic_set64(vint64 *value, int64 newValue); -extern int64 _kern_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst); +extern int64 _kern_atomic_test_and_set64(vint64 *value, int64 newValue, + int64 testAgainst); extern int64 _kern_atomic_add64(vint64 *value, int64 addValue); extern int64 _kern_atomic_and64(vint64 *value, int64 andValue); extern int64 _kern_atomic_or64(vint64 *value, int64 orValue); @@ -438,7 +476,8 @@ extern area_id _kern_register_messaging_service(sem_id lockingSem, sem_id counterSem); extern status_t _kern_unregister_messaging_service(); -extern void _kern_clear_caches(void *address, size_t length, uint32 flags); +extern void _kern_clear_caches(void *address, size_t length, + uint32 flags); extern bool _kern_cpu_enabled(int32 cpu); extern status_t _kern_set_cpu_enabled(int32 cpu, bool enabled); diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp index 986b429aa6..8faf8591e2 100644 --- a/src/system/kernel/elf.cpp +++ b/src/system/kernel/elf.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001, Travis Geiselbrecht. All rights reserved. @@ -1802,7 +1802,7 @@ elf_load_user_image(const char *path, struct team *team, int flags, id = vm_map_file(team->id, regionName, (void **)®ionAddress, B_EXACT_ADDRESS, fileUpperBound, - B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, + B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false, fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); if (id < B_OK) { dprintf("error mapping file data: %s!\n", strerror(id)); @@ -1850,7 +1850,7 @@ elf_load_user_image(const char *path, struct team *team, int flags, id = vm_map_file(team->id, regionName, (void **)®ionAddress, B_EXACT_ADDRESS, segmentSize, - B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, + B_READ_AREA | B_EXECUTE_AREA, REGION_PRIVATE_MAP, false, fd, ROUNDOWN(programHeaders[i].p_offset, B_PAGE_SIZE)); if (id < B_OK) { dprintf("error mapping file text: %s!\n", strerror(id)); diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 63cdc9184d..e1cf29ee1e 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -2252,8 +2252,8 @@ pre_map_area_pages(vm_area* area, VMCache* cache) */ static area_id _vm_map_file(team_id team, const char* name, void** _address, - uint32 addressSpec, size_t size, uint32 protection, uint32 mapping, int fd, - off_t offset, bool kernel) + uint32 addressSpec, size_t size, uint32 protection, uint32 mapping, + bool unmapAddressRange, int fd, off_t offset, bool kernel) { // TODO: for binary files, we want to make sure that they get the // copy of a file at a given time, ie. later changes should not @@ -2267,10 +2267,11 @@ _vm_map_file(team_id team, const char* name, void** _address, if (mapping == REGION_NO_PRIVATE_MAP) protection |= B_SHARED_AREA; + if (addressSpec != B_EXACT_ADDRESS) + unmapAddressRange = false; if (fd < 0) { - uint32 flags = addressSpec == B_EXACT_ADDRESS - ? CREATE_AREA_UNMAP_ADDRESS_RANGE : 0; + uint32 flags = unmapAddressRange ? CREATE_AREA_UNMAP_ADDRESS_RANGE : 0; return vm_create_anonymous_area(team, name, _address, addressSpec, size, B_NO_LOCK, protection, flags, kernel); } @@ -2345,7 +2346,7 @@ _vm_map_file(team_id team, const char* name, void** _address, vm_area* area; status = map_backing_store(locker.AddressSpace(), cache, _address, offset, size, addressSpec, 0, protection, mapping, &area, name, - addressSpec == B_EXACT_ADDRESS, kernel); + unmapAddressRange, kernel); if (status != B_OK || mapping == REGION_PRIVATE_MAP) { // map_backing_store() cannot know we no longer need the ref @@ -2374,13 +2375,14 @@ _vm_map_file(team_id team, const char* name, void** _address, area_id vm_map_file(team_id aid, const char* name, void** address, uint32 addressSpec, - addr_t size, uint32 protection, uint32 mapping, int fd, off_t offset) + addr_t size, uint32 protection, uint32 mapping, bool unmapAddressRange, + int fd, off_t offset) { if (!arch_vm_supports_protection(protection)) return B_NOT_SUPPORTED; return _vm_map_file(aid, name, address, addressSpec, size, protection, - mapping, fd, offset, true); + mapping, unmapAddressRange, fd, offset, true); } @@ -6148,7 +6150,8 @@ _user_delete_area(area_id area) area_id _user_map_file(const char* userName, void** userAddress, int addressSpec, - size_t size, int protection, int mapping, int fd, off_t offset) + size_t size, int protection, int mapping, bool unmapAddressRange, int fd, + off_t offset) { char name[B_OS_NAME_LENGTH]; void* address; @@ -6173,7 +6176,8 @@ _user_map_file(const char* userName, void** userAddress, int addressSpec, | (protection & B_WRITE_AREA ? B_KERNEL_WRITE_AREA : 0); area = _vm_map_file(vm_current_user_address_space_id(), name, &address, - addressSpec, size, protection, mapping, fd, offset, false); + addressSpec, size, protection, mapping, unmapAddressRange, fd, offset, + false); if (area < B_OK) return area; diff --git a/src/system/libroot/posix/sys/mman.cpp b/src/system/libroot/posix/sys/mman.cpp index eebbfdd98f..82480a0b1c 100644 --- a/src/system/libroot/posix/sys/mman.cpp +++ b/src/system/libroot/posix/sys/mman.cpp @@ -125,7 +125,7 @@ mmap(void* address, size_t length, int protection, int flags, int fd, // ask the kernel to map area_id area = _kern_map_file("mmap area", &address, addressSpec, - length, areaProtection, mapping, fd, offset); + length, areaProtection, mapping, true, fd, offset); if (area < 0) { errno = area; return MAP_FAILED; diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp index 73a5cedff9..11f896dddf 100644 --- a/src/system/runtime_loader/images.cpp +++ b/src/system/runtime_loader/images.cpp @@ -1,6 +1,6 @@ /* * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2003-2008, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2002, Manuel J. Petit. All rights reserved. @@ -306,7 +306,8 @@ map_image(int fd, char const* path, image_t* image, bool fixed) image->regions[i].id = _kern_map_file(regionName, (void**)&loadAddress, addressSpecifier, image->regions[i].vmsize, B_READ_AREA | B_WRITE_AREA, - REGION_PRIVATE_MAP, fd, PAGE_BASE(image->regions[i].fdstart)); + REGION_PRIVATE_MAP, false, fd, + PAGE_BASE(image->regions[i].fdstart)); if (image->regions[i].id < 0) return image->regions[i].id;