* Added an "unmapAddressRange" argument to the file mapping syscall. This is

the first part of making the runtime loader behave itself; it should already
  make Clockwerk run okay with any number of translators (even if not all of
  them will work yet).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31113 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-06-19 08:23:11 +00:00
parent c9a4907c03
commit 82db8a9e15
6 changed files with 115 additions and 70 deletions
+5 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008, Axel Dörfler, [email protected].
* Copyright 2002-2009, Axel Dörfler, [email protected].
* 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);
+89 -50
View File
@@ -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);
+3 -3
View File
@@ -1,6 +1,6 @@
/*
* Copyright 2009, Ingo Weinhold, [email protected].
* Copyright 2002-2008, Axel Dörfler, [email protected].
* Copyright 2002-2009, Axel Dörfler, [email protected].
* 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 **)&regionAddress,
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 **)&regionAddress,
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));
+14 -10
View File
@@ -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;
+1 -1
View File
@@ -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;
+3 -2
View File
@@ -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;