runtime loader: Register extended image info with kernel
Add structure extended_image_info which extends image_info by the fields symbol_table, symbol_hash, string_table.
This commit is contained in:
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
|
||||||
|
#include <image_defs.h>
|
||||||
|
|
||||||
|
|
||||||
struct image;
|
struct image;
|
||||||
|
|
||||||
@@ -25,7 +27,7 @@ struct image {
|
|||||||
struct image* next;
|
struct image* next;
|
||||||
struct image* prev;
|
struct image* prev;
|
||||||
struct image* hash_link;
|
struct image* hash_link;
|
||||||
image_info info;
|
extended_image_info info;
|
||||||
team_id team;
|
team_id team;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,8 +43,10 @@ struct image {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern image_id register_image(Team *team, image_info *info, size_t size);
|
extern image_id register_image(Team *team, extended_image_info *info,
|
||||||
|
size_t size);
|
||||||
extern status_t unregister_image(Team *team, image_id id);
|
extern status_t unregister_image(Team *team, image_id id);
|
||||||
|
extern status_t copy_images(team_id fromTeamId, Team *toTeam);
|
||||||
extern int32 count_images(Team *team);
|
extern int32 count_images(Team *team);
|
||||||
extern status_t remove_images(Team *team);
|
extern status_t remove_images(Team *team);
|
||||||
|
|
||||||
@@ -59,7 +63,8 @@ extern status_t image_init(void);
|
|||||||
|
|
||||||
// user-space exported calls
|
// user-space exported calls
|
||||||
extern status_t _user_unregister_image(image_id id);
|
extern status_t _user_unregister_image(image_id id);
|
||||||
extern image_id _user_register_image(image_info *userInfo, size_t size);
|
extern image_id _user_register_image(extended_image_info *userInfo,
|
||||||
|
size_t size);
|
||||||
extern void _user_image_relocated(image_id id);
|
extern void _user_image_relocated(image_id id);
|
||||||
extern void _user_loading_app_failed(status_t error);
|
extern void _user_loading_app_failed(status_t error);
|
||||||
extern status_t _user_get_next_image_info(team_id team, int32 *_cookie,
|
extern status_t _user_get_next_image_info(team_id team, int32 *_cookie,
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
* Copyright 2009-2016, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _SYSTEM_IMAGE_DEFS_H
|
#ifndef _SYSTEM_IMAGE_DEFS_H
|
||||||
#define _SYSTEM_IMAGE_DEFS_H
|
#define _SYSTEM_IMAGE_DEFS_H
|
||||||
|
|
||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
#include <image.h>
|
||||||
|
|
||||||
|
|
||||||
#define B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE _gSharedObjectHaikuVersion
|
#define B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE _gSharedObjectHaikuVersion
|
||||||
@@ -15,4 +17,12 @@
|
|||||||
#define B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME "_gSharedObjectHaikuABI"
|
#define B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME "_gSharedObjectHaikuABI"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct extended_image_info {
|
||||||
|
image_info basic_info;
|
||||||
|
void* symbol_table;
|
||||||
|
void* symbol_hash;
|
||||||
|
void* string_table;
|
||||||
|
} extended_image_info;
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SYSTEM_IMAGE_DEFS_H */
|
#endif /* _SYSTEM_IMAGE_DEFS_H */
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <DiskDeviceDefs.h>
|
#include <DiskDeviceDefs.h>
|
||||||
#include <elf_private.h>
|
#include <elf_private.h>
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
|
#include <image_defs.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -223,7 +224,8 @@ extern status_t _kern_set_signal_stack(const stack_t *newStack,
|
|||||||
stack_t *oldStack);
|
stack_t *oldStack);
|
||||||
|
|
||||||
// image functions
|
// image functions
|
||||||
extern image_id _kern_register_image(image_info *info, size_t size);
|
extern image_id _kern_register_image(extended_image_info *info,
|
||||||
|
size_t size);
|
||||||
extern status_t _kern_unregister_image(image_id id);
|
extern status_t _kern_unregister_image(image_id id);
|
||||||
extern void _kern_image_relocated(image_id id);
|
extern void _kern_image_relocated(image_id id);
|
||||||
extern void _kern_loading_app_failed(status_t error);
|
extern void _kern_loading_app_failed(status_t error);
|
||||||
|
|||||||
@@ -246,17 +246,17 @@ typedef DoublyLinkedList<ThreadState> ThreadStateList;
|
|||||||
struct ImageInfo : DoublyLinkedListLinkImpl<ImageInfo> {
|
struct ImageInfo : DoublyLinkedListLinkImpl<ImageInfo> {
|
||||||
ImageInfo(struct image* image)
|
ImageInfo(struct image* image)
|
||||||
:
|
:
|
||||||
fId(image->info.id),
|
fId(image->info.basic_info.id),
|
||||||
fType(image->info.type),
|
fType(image->info.basic_info.type),
|
||||||
fDeviceId(image->info.device),
|
fDeviceId(image->info.basic_info.device),
|
||||||
fNodeId(image->info.node),
|
fNodeId(image->info.basic_info.node),
|
||||||
fName(strdup(image->info.name)),
|
fName(strdup(image->info.basic_info.name)),
|
||||||
fInitRoutine((addr_t)image->info.init_routine),
|
fInitRoutine((addr_t)image->info.basic_info.init_routine),
|
||||||
fTermRoutine((addr_t)image->info.term_routine),
|
fTermRoutine((addr_t)image->info.basic_info.term_routine),
|
||||||
fText((addr_t)image->info.text),
|
fText((addr_t)image->info.basic_info.text),
|
||||||
fData((addr_t)image->info.data),
|
fData((addr_t)image->info.basic_info.data),
|
||||||
fTextSize(image->info.text_size),
|
fTextSize(image->info.basic_info.text_size),
|
||||||
fDataSize(image->info.data_size)
|
fDataSize(image->info.basic_info.data_size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1019,7 +1019,7 @@ SystemProfiler::_ImageAdded(struct image* image)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
event->team = image->team;
|
event->team = image->team;
|
||||||
event->info = image->info;
|
event->info = image->info.basic_info;
|
||||||
|
|
||||||
fHeader->size = fBufferSize;
|
fHeader->size = fBufferSize;
|
||||||
|
|
||||||
@@ -1039,7 +1039,7 @@ SystemProfiler::_ImageRemoved(struct image* image)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
event->team = image->team;
|
event->team = image->team;
|
||||||
event->image = image->info.id;
|
event->image = image->info.basic_info.id;
|
||||||
|
|
||||||
fHeader->size = fBufferSize;
|
fHeader->size = fBufferSize;
|
||||||
|
|
||||||
|
|||||||
+37
-31
@@ -108,23 +108,24 @@ unregister_elf_image(struct elf_image_info *image)
|
|||||||
static void
|
static void
|
||||||
register_elf_image(struct elf_image_info *image)
|
register_elf_image(struct elf_image_info *image)
|
||||||
{
|
{
|
||||||
image_info imageInfo;
|
extended_image_info imageInfo;
|
||||||
|
|
||||||
memset(&imageInfo, 0, sizeof(image_info));
|
memset(&imageInfo, 0, sizeof(imageInfo));
|
||||||
imageInfo.id = image->id;
|
imageInfo.basic_info.id = image->id;
|
||||||
imageInfo.type = B_SYSTEM_IMAGE;
|
imageInfo.basic_info.type = B_SYSTEM_IMAGE;
|
||||||
strlcpy(imageInfo.name, image->name, sizeof(imageInfo.name));
|
strlcpy(imageInfo.basic_info.name, image->name,
|
||||||
|
sizeof(imageInfo.basic_info.name));
|
||||||
|
|
||||||
imageInfo.text = (void *)image->text_region.start;
|
imageInfo.basic_info.text = (void *)image->text_region.start;
|
||||||
imageInfo.text_size = image->text_region.size;
|
imageInfo.basic_info.text_size = image->text_region.size;
|
||||||
imageInfo.data = (void *)image->data_region.start;
|
imageInfo.basic_info.data = (void *)image->data_region.start;
|
||||||
imageInfo.data_size = image->data_region.size;
|
imageInfo.basic_info.data_size = image->data_region.size;
|
||||||
|
|
||||||
if (image->text_region.id >= 0) {
|
if (image->text_region.id >= 0) {
|
||||||
// evaluate the API/ABI version symbols
|
// evaluate the API/ABI version symbols
|
||||||
|
|
||||||
// Haiku API version
|
// Haiku API version
|
||||||
imageInfo.api_version = 0;
|
imageInfo.basic_info.api_version = 0;
|
||||||
elf_sym* symbol = elf_find_symbol(image,
|
elf_sym* symbol = elf_find_symbol(image,
|
||||||
B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME, NULL, true);
|
B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME, NULL, true);
|
||||||
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
|
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
|
||||||
@@ -135,12 +136,12 @@ register_elf_image(struct elf_image_info *image)
|
|||||||
if (symbolAddress >= image->text_region.start
|
if (symbolAddress >= image->text_region.start
|
||||||
&& symbolAddress - image->text_region.start + sizeof(uint32)
|
&& symbolAddress - image->text_region.start + sizeof(uint32)
|
||||||
<= image->text_region.size) {
|
<= image->text_region.size) {
|
||||||
imageInfo.api_version = *(uint32*)symbolAddress;
|
imageInfo.basic_info.api_version = *(uint32*)symbolAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Haiku ABI
|
// Haiku ABI
|
||||||
imageInfo.abi = 0;
|
imageInfo.basic_info.abi = 0;
|
||||||
symbol = elf_find_symbol(image,
|
symbol = elf_find_symbol(image,
|
||||||
B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME, NULL, true);
|
B_SHARED_OBJECT_HAIKU_ABI_VARIABLE_NAME, NULL, true);
|
||||||
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
|
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
|
||||||
@@ -151,17 +152,17 @@ register_elf_image(struct elf_image_info *image)
|
|||||||
if (symbolAddress >= image->text_region.start
|
if (symbolAddress >= image->text_region.start
|
||||||
&& symbolAddress - image->text_region.start + sizeof(uint32)
|
&& symbolAddress - image->text_region.start + sizeof(uint32)
|
||||||
<= image->text_region.size) {
|
<= image->text_region.size) {
|
||||||
imageInfo.api_version = *(uint32*)symbolAddress;
|
imageInfo.basic_info.api_version = *(uint32*)symbolAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// in-memory image -- use the current values
|
// in-memory image -- use the current values
|
||||||
imageInfo.api_version = B_HAIKU_VERSION;
|
imageInfo.basic_info.api_version = B_HAIKU_VERSION;
|
||||||
imageInfo.abi = B_HAIKU_ABI;
|
imageInfo.basic_info.abi = B_HAIKU_ABI;
|
||||||
}
|
}
|
||||||
|
|
||||||
image->id = register_image(team_get_kernel_team(), &imageInfo,
|
image->id = register_image(team_get_kernel_team(), &imageInfo,
|
||||||
sizeof(image_info));
|
sizeof(imageInfo));
|
||||||
sImagesHash->Insert(image);
|
sImagesHash->Insert(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1902,8 +1903,8 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
goto error2;
|
goto error2;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_info imageInfo;
|
extended_image_info imageInfo;
|
||||||
memset(&imageInfo, 0, sizeof(image_info));
|
memset(&imageInfo, 0, sizeof(imageInfo));
|
||||||
|
|
||||||
for (i = 0; i < elfHeader.e_phnum; i++) {
|
for (i = 0; i < elfHeader.e_phnum; i++) {
|
||||||
char regionName[B_OS_NAME_LENGTH];
|
char regionName[B_OS_NAME_LENGTH];
|
||||||
@@ -1948,8 +1949,8 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
}
|
}
|
||||||
mappedAreas[i] = id;
|
mappedAreas[i] = id;
|
||||||
|
|
||||||
imageInfo.data = regionAddress;
|
imageInfo.basic_info.data = regionAddress;
|
||||||
imageInfo.data_size = memUpperBound;
|
imageInfo.basic_info.data_size = memUpperBound;
|
||||||
|
|
||||||
image->data_region.start = (addr_t)regionAddress;
|
image->data_region.start = (addr_t)regionAddress;
|
||||||
image->data_region.size = memUpperBound;
|
image->data_region.size = memUpperBound;
|
||||||
@@ -2005,8 +2006,8 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
|
|
||||||
mappedAreas[i] = id;
|
mappedAreas[i] = id;
|
||||||
|
|
||||||
imageInfo.text = regionAddress;
|
imageInfo.basic_info.text = regionAddress;
|
||||||
imageInfo.text_size = segmentSize;
|
imageInfo.basic_info.text_size = segmentSize;
|
||||||
|
|
||||||
image->text_region.start = (addr_t)regionAddress;
|
image->text_region.start = (addr_t)regionAddress;
|
||||||
image->text_region.size = segmentSize;
|
image->text_region.size = segmentSize;
|
||||||
@@ -2053,20 +2054,25 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// register the loaded image
|
// register the loaded image
|
||||||
imageInfo.type = B_LIBRARY_IMAGE;
|
imageInfo.basic_info.type = B_LIBRARY_IMAGE;
|
||||||
imageInfo.device = st.st_dev;
|
imageInfo.basic_info.device = st.st_dev;
|
||||||
imageInfo.node = st.st_ino;
|
imageInfo.basic_info.node = st.st_ino;
|
||||||
strlcpy(imageInfo.name, path, sizeof(imageInfo.name));
|
strlcpy(imageInfo.basic_info.name, path, sizeof(imageInfo.basic_info.name));
|
||||||
|
|
||||||
imageInfo.api_version = B_HAIKU_VERSION;
|
imageInfo.basic_info.api_version = B_HAIKU_VERSION;
|
||||||
imageInfo.abi = B_HAIKU_ABI;
|
imageInfo.basic_info.abi = B_HAIKU_ABI;
|
||||||
// TODO: Get the actual values for the shared object. Currently only
|
// TODO: Get the actual values for the shared object. Currently only
|
||||||
// the runtime loader is loaded, so this is good enough for the time
|
// the runtime loader is loaded, so this is good enough for the time
|
||||||
// being.
|
// being.
|
||||||
|
|
||||||
imageInfo.id = register_image(team, &imageInfo, sizeof(image_info));
|
imageInfo.symbol_table = image->syms;
|
||||||
if (imageInfo.id >= 0 && team_get_current_team_id() == team->id)
|
imageInfo.symbol_hash = image->symhash;
|
||||||
user_debug_image_created(&imageInfo);
|
imageInfo.string_table = image->strtab;
|
||||||
|
|
||||||
|
imageInfo.basic_info.id = register_image(team, &imageInfo,
|
||||||
|
sizeof(imageInfo));
|
||||||
|
if (imageInfo.basic_info.id >= 0 && team_get_current_team_id() == team->id)
|
||||||
|
user_debug_image_created(&imageInfo.basic_info);
|
||||||
// Don't care, if registering fails. It's not crucial.
|
// Don't care, if registering fails. It's not crucial.
|
||||||
|
|
||||||
TRACE(("elf_load: done!\n"));
|
TRACE(("elf_load: done!\n"));
|
||||||
|
|||||||
+55
-19
@@ -40,9 +40,9 @@ struct ImageTableDefinition {
|
|||||||
typedef struct image ValueType;
|
typedef struct image ValueType;
|
||||||
|
|
||||||
size_t HashKey(image_id key) const { return key; }
|
size_t HashKey(image_id key) const { return key; }
|
||||||
size_t Hash(struct image* value) const { return value->info.id; }
|
size_t Hash(struct image* value) const { return value->info.basic_info.id; }
|
||||||
bool Compare(image_id key, struct image* value) const
|
bool Compare(image_id key, struct image* value) const
|
||||||
{ return value->info.id == key; }
|
{ return value->info.basic_info.id == key; }
|
||||||
struct image*& GetLink(struct image* value) const
|
struct image*& GetLink(struct image* value) const
|
||||||
{ return value->hash_link; }
|
{ return value->hash_link; }
|
||||||
};
|
};
|
||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
KMessage event;
|
KMessage event;
|
||||||
event.SetTo(eventBuffer, sizeof(eventBuffer), IMAGE_MONITOR);
|
event.SetTo(eventBuffer, sizeof(eventBuffer), IMAGE_MONITOR);
|
||||||
event.AddInt32("event", eventCode);
|
event.AddInt32("event", eventCode);
|
||||||
event.AddInt32("image", image->info.id);
|
event.AddInt32("image", image->info.basic_info.id);
|
||||||
event.AddPointer("imageStruct", image);
|
event.AddPointer("imageStruct", image);
|
||||||
|
|
||||||
DefaultNotificationService::Notify(event, eventCode);
|
DefaultNotificationService::Notify(event, eventCode);
|
||||||
@@ -81,8 +81,8 @@ static ImageNotificationService sNotificationService;
|
|||||||
|
|
||||||
/*! Registers an image with the specified team.
|
/*! Registers an image with the specified team.
|
||||||
*/
|
*/
|
||||||
image_id
|
static image_id
|
||||||
register_image(Team *team, image_info *_info, size_t size)
|
register_image(Team *team, extended_image_info *info, size_t size, bool locked)
|
||||||
{
|
{
|
||||||
image_id id = atomic_add(&sNextImageID, 1);
|
image_id id = atomic_add(&sNextImageID, 1);
|
||||||
struct image *image;
|
struct image *image;
|
||||||
@@ -91,16 +91,17 @@ register_image(Team *team, image_info *_info, size_t size)
|
|||||||
if (image == NULL)
|
if (image == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
memcpy(&image->info, _info, sizeof(image_info));
|
memcpy(&image->info, info, sizeof(extended_image_info));
|
||||||
image->team = team->id;
|
image->team = team->id;
|
||||||
|
|
||||||
mutex_lock(&sImageMutex);
|
if (!locked)
|
||||||
|
mutex_lock(&sImageMutex);
|
||||||
|
|
||||||
image->info.id = id;
|
image->info.basic_info.id = id;
|
||||||
|
|
||||||
// Add the app image to the head of the list. Some code relies on it being
|
// Add the app image to the head of the list. Some code relies on it being
|
||||||
// the first image to be returned by get_next_image_info().
|
// the first image to be returned by get_next_image_info().
|
||||||
if (image->info.type == B_APP_IMAGE)
|
if (image->info.basic_info.type == B_APP_IMAGE)
|
||||||
list_add_link_to_head(&team->image_list, image);
|
list_add_link_to_head(&team->image_list, image);
|
||||||
else
|
else
|
||||||
list_add_item(&team->image_list, image);
|
list_add_item(&team->image_list, image);
|
||||||
@@ -109,13 +110,23 @@ register_image(Team *team, image_info *_info, size_t size)
|
|||||||
// notify listeners
|
// notify listeners
|
||||||
sNotificationService.Notify(IMAGE_ADDED, image);
|
sNotificationService.Notify(IMAGE_ADDED, image);
|
||||||
|
|
||||||
mutex_unlock(&sImageMutex);
|
if (!locked)
|
||||||
|
mutex_unlock(&sImageMutex);
|
||||||
|
|
||||||
TRACE(("register_image(team = %p, image id = %ld, image = %p\n", team, id, image));
|
TRACE(("register_image(team = %p, image id = %ld, image = %p\n", team, id, image));
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Registers an image with the specified team.
|
||||||
|
*/
|
||||||
|
image_id
|
||||||
|
register_image(Team *team, extended_image_info *info, size_t size)
|
||||||
|
{
|
||||||
|
return register_image(team, info, size, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Unregisters an image from the specified team.
|
/*! Unregisters an image from the specified team.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
@@ -136,7 +147,7 @@ unregister_image(Team *team, image_id id)
|
|||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// notify the debugger
|
// notify the debugger
|
||||||
user_debug_image_deleted(&image->info);
|
user_debug_image_deleted(&image->info.basic_info);
|
||||||
|
|
||||||
// notify listeners
|
// notify listeners
|
||||||
sNotificationService.Notify(IMAGE_REMOVED, image);
|
sNotificationService.Notify(IMAGE_REMOVED, image);
|
||||||
@@ -148,6 +159,30 @@ unregister_image(Team *team, image_id id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
copy_images(team_id fromTeamId, Team *toTeam)
|
||||||
|
{
|
||||||
|
// get the team
|
||||||
|
Team* fromTeam = Team::Get(fromTeamId);
|
||||||
|
if (fromTeam == NULL)
|
||||||
|
return B_BAD_TEAM_ID;
|
||||||
|
BReference<Team> teamReference(fromTeam, true);
|
||||||
|
|
||||||
|
MutexLocker locker(sImageMutex);
|
||||||
|
|
||||||
|
struct image *image = NULL;
|
||||||
|
while ((image = (struct image*)list_get_next_item(&fromTeam->image_list,
|
||||||
|
image)) != NULL) {
|
||||||
|
image_id id = register_image(toTeam, &image->info, sizeof(image->info),
|
||||||
|
true);
|
||||||
|
if (id < 0)
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Counts the registered images from the specified team.
|
/*! Counts the registered images from the specified team.
|
||||||
Interrupts must be enabled.
|
Interrupts must be enabled.
|
||||||
*/
|
*/
|
||||||
@@ -204,7 +239,7 @@ _get_image_info(image_id id, image_info *info, size_t size)
|
|||||||
|
|
||||||
struct image *image = sImageTable->Lookup(id);
|
struct image *image = sImageTable->Lookup(id);
|
||||||
if (image != NULL) {
|
if (image != NULL) {
|
||||||
memcpy(info, &image->info, size);
|
memcpy(info, &image->info.basic_info, size);
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +271,7 @@ _get_next_image_info(team_id teamID, int32 *cookie, image_info *info,
|
|||||||
while ((image = (struct image*)list_get_next_item(&team->image_list,
|
while ((image = (struct image*)list_get_next_item(&team->image_list,
|
||||||
image)) != NULL) {
|
image)) != NULL) {
|
||||||
if (count == *cookie) {
|
if (count == *cookie) {
|
||||||
memcpy(info, &image->info, size);
|
memcpy(info, &image->info.basic_info, size);
|
||||||
(*cookie)++;
|
(*cookie)++;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -270,7 +305,7 @@ dump_images_list(int argc, char **argv)
|
|||||||
|
|
||||||
while ((image = (struct image*)list_get_next_item(&team->image_list, image))
|
while ((image = (struct image*)list_get_next_item(&team->image_list, image))
|
||||||
!= NULL) {
|
!= NULL) {
|
||||||
image_info *info = &image->info;
|
image_info *info = &image->info.basic_info;
|
||||||
|
|
||||||
kprintf("%6" B_PRId32 " %p %-7" B_PRId32 " %p %-7" B_PRId32 " %s\n",
|
kprintf("%6" B_PRId32 " %p %-7" B_PRId32 " %p %-7" B_PRId32 " %s\n",
|
||||||
info->id, info->text, info->text_size, info->data, info->data_size,
|
info->id, info->text, info->text_size, info->data, info->data_size,
|
||||||
@@ -328,13 +363,14 @@ image_debug_lookup_user_symbol_address(Team *team, addr_t address,
|
|||||||
addr_t *_baseAddress, const char **_symbolName, const char **_imageName,
|
addr_t *_baseAddress, const char **_symbolName, const char **_imageName,
|
||||||
bool *_exactMatch)
|
bool *_exactMatch)
|
||||||
{
|
{
|
||||||
// TODO: work together with ELF reader and runtime_loader
|
// TODO: Work together with ELF reader and runtime_loader. For regular user
|
||||||
|
// images we have the symbol and string table addresses.
|
||||||
|
|
||||||
struct image *image = NULL;
|
struct image *image = NULL;
|
||||||
|
|
||||||
while ((image = (struct image*)list_get_next_item(&team->image_list, image))
|
while ((image = (struct image*)list_get_next_item(&team->image_list, image))
|
||||||
!= NULL) {
|
!= NULL) {
|
||||||
image_info *info = &image->info;
|
image_info *info = &image->info.basic_info;
|
||||||
|
|
||||||
if ((address < (addr_t)info->text
|
if ((address < (addr_t)info->text
|
||||||
|| address >= (addr_t)info->text + info->text_size)
|
|| address >= (addr_t)info->text + info->text_size)
|
||||||
@@ -424,11 +460,11 @@ _user_unregister_image(image_id id)
|
|||||||
|
|
||||||
|
|
||||||
image_id
|
image_id
|
||||||
_user_register_image(image_info *userInfo, size_t size)
|
_user_register_image(extended_image_info *userInfo, size_t size)
|
||||||
{
|
{
|
||||||
image_info info;
|
extended_image_info info;
|
||||||
|
|
||||||
if (size != sizeof(image_info))
|
if (size != sizeof(info))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userInfo)
|
if (!IS_USER_ADDRESS(userInfo)
|
||||||
|
|||||||
@@ -1604,15 +1604,18 @@ team_create_thread_start_internal(void* args)
|
|||||||
|
|
||||||
// Register commpage image
|
// Register commpage image
|
||||||
image_id commPageImage = get_commpage_image();
|
image_id commPageImage = get_commpage_image();
|
||||||
image_info imageInfo;
|
extended_image_info imageInfo;
|
||||||
err = get_image_info(commPageImage, &imageInfo);
|
err = get_image_info(commPageImage, &imageInfo.basic_info);
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
TRACE(("team_create_thread_start: get_image_info() failed: %s\n",
|
TRACE(("team_create_thread_start: get_image_info() failed: %s\n",
|
||||||
strerror(err)));
|
strerror(err)));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
imageInfo.text = team->commpage_address;
|
imageInfo.basic_info.text = team->commpage_address;
|
||||||
image_id image = register_image(team, &imageInfo, sizeof(image_info));
|
imageInfo.symbol_table = NULL;
|
||||||
|
imageInfo.symbol_hash = NULL;
|
||||||
|
imageInfo.string_table = NULL;
|
||||||
|
image_id image = register_image(team, &imageInfo, sizeof(imageInfo));
|
||||||
if (image < 0) {
|
if (image < 0) {
|
||||||
TRACE(("team_create_thread_start: register_image() failed: %s\n",
|
TRACE(("team_create_thread_start: register_image() failed: %s\n",
|
||||||
strerror(image)));
|
strerror(image)));
|
||||||
@@ -2031,7 +2034,6 @@ fork_team(void)
|
|||||||
thread_id threadID;
|
thread_id threadID;
|
||||||
status_t status;
|
status_t status;
|
||||||
ssize_t areaCookie;
|
ssize_t areaCookie;
|
||||||
int32 imageCookie;
|
|
||||||
|
|
||||||
TRACE(("fork_team(): team %" B_PRId32 "\n", parentTeam->id));
|
TRACE(("fork_team(): team %" B_PRId32 "\n", parentTeam->id));
|
||||||
|
|
||||||
@@ -2174,14 +2176,8 @@ fork_team(void)
|
|||||||
arch_store_fork_frame(forkArgs);
|
arch_store_fork_frame(forkArgs);
|
||||||
|
|
||||||
// copy image list
|
// copy image list
|
||||||
image_info imageInfo;
|
if (copy_images(parentTeam->id, team) != B_OK)
|
||||||
imageCookie = 0;
|
goto err5;
|
||||||
while (get_next_image_info(parentTeam->id, &imageCookie, &imageInfo)
|
|
||||||
== B_OK) {
|
|
||||||
image_id image = register_image(team, &imageInfo, sizeof(imageInfo));
|
|
||||||
if (image < 0)
|
|
||||||
goto err5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the main thread
|
// create the main thread
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
|
#include <image_defs.h>
|
||||||
#include <vm_defs.h>
|
#include <vm_defs.h>
|
||||||
|
|
||||||
#include "add_ons.h"
|
#include "add_ons.h"
|
||||||
@@ -466,22 +467,22 @@ void
|
|||||||
register_image(image_t* image, int fd, const char* path)
|
register_image(image_t* image, int fd, const char* path)
|
||||||
{
|
{
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
image_info info;
|
extended_image_info info;
|
||||||
|
|
||||||
// TODO: set these correctly
|
// TODO: set these correctly
|
||||||
info.id = 0;
|
info.basic_info.id = 0;
|
||||||
info.type = image->type;
|
info.basic_info.type = image->type;
|
||||||
info.sequence = 0;
|
info.basic_info.sequence = 0;
|
||||||
info.init_order = 0;
|
info.basic_info.init_order = 0;
|
||||||
info.init_routine = (void (*)())image->init_routine;
|
info.basic_info.init_routine = (void (*)())image->init_routine;
|
||||||
info.term_routine = (void (*)())image->term_routine;
|
info.basic_info.term_routine = (void (*)())image->term_routine;
|
||||||
|
|
||||||
if (_kern_read_stat(fd, NULL, false, &stat, sizeof(struct stat)) == B_OK) {
|
if (_kern_read_stat(fd, NULL, false, &stat, sizeof(struct stat)) == B_OK) {
|
||||||
info.device = stat.st_dev;
|
info.basic_info.device = stat.st_dev;
|
||||||
info.node = stat.st_ino;
|
info.basic_info.node = stat.st_ino;
|
||||||
} else {
|
} else {
|
||||||
info.device = -1;
|
info.basic_info.device = -1;
|
||||||
info.node = -1;
|
info.basic_info.node = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We may have split segments into separate regions. Compute the correct
|
// We may have split segments into separate regions. Compute the correct
|
||||||
@@ -514,14 +515,17 @@ register_image(image_t* image, int fd, const char* path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(info.name, path, sizeof(info.name));
|
strlcpy(info.basic_info.name, path, sizeof(info.basic_info.name));
|
||||||
info.text = (void*)textBase;
|
info.basic_info.text = (void*)textBase;
|
||||||
info.text_size = textEnd - textBase;
|
info.basic_info.text_size = textEnd - textBase;
|
||||||
info.data = (void*)dataBase;
|
info.basic_info.data = (void*)dataBase;
|
||||||
info.data_size = dataEnd - dataBase;
|
info.basic_info.data_size = dataEnd - dataBase;
|
||||||
info.api_version = image->api_version;
|
info.basic_info.api_version = image->api_version;
|
||||||
info.abi = image->abi;
|
info.basic_info.abi = image->abi;
|
||||||
image->id = _kern_register_image(&info, sizeof(image_info));
|
info.symbol_table = image->syms;
|
||||||
|
info.symbol_hash = image->symhash;
|
||||||
|
info.string_table = image->strtab;
|
||||||
|
image->id = _kern_register_image(&info, sizeof(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user