コード例 #1
0
ファイル: shm.c プロジェクト: Kiddinglife/geco-game-engine
APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m,
                                         const char *filename,
                                         apr_pool_t *pool)
{
    area_info ai;
    thread_info ti;
    apr_shm_t *new_m;
    area_id deleteme = find_area(filename);

    if (deleteme == B_NAME_NOT_FOUND)
        return APR_EINVAL;

    new_m = (apr_shm_t*)apr_palloc(pool, sizeof(apr_shm_t*));
    if (new_m == NULL)
        return APR_ENOMEM;
    new_m->pool = pool;

    get_area_info(deleteme, &ai);
    get_thread_info(find_thread(NULL), &ti);

    if (ti.team != ai.team) {
        area_id narea;
        
        narea = clone_area(ai.name, &(ai.address), B_CLONE_ADDRESS,
                           B_READ_AREA|B_WRITE_AREA, ai.area);

        if (narea < B_OK)
            return narea;
            
        get_area_info(narea, &ai);
        new_m->aid = narea;
        new_m->memblock = ai.address;
        new_m->ptr = (void*)ai.address;
        new_m->avail = ai.size;
        new_m->reqsize = ai.size;
    }

    (*m) = new_m;
    
    return APR_SUCCESS;
}
コード例 #2
0
ファイル: LinkReceiver.cpp プロジェクト: DonCN/haiku
status_t
LinkReceiver::Read(void *data, ssize_t passedSize)
{
//	STRACE(("info: LinkReceiver Read()ing %ld bytes...\n", size));
	ssize_t size = passedSize;

	if (fReadError < B_OK)
		return fReadError;

	if (data == NULL || size < 1) {
		fReadError = B_BAD_VALUE;
		return B_BAD_VALUE;
	}

	if (fDataSize == 0 || fReplySize == 0)
		return B_NO_INIT;	// need to call GetNextReply() first

	bool useArea = false;
	if ((size_t)size >= kMaxBufferSize) {
		useArea = true;
		size = sizeof(area_id);
	}

	if (fRecvPosition + size > fRecvStart + fReplySize) {
		// reading past the end of current message
		fReadError = B_BAD_VALUE;
		return B_BAD_VALUE;
	}

	if (useArea) {
		area_id sourceArea;
		memcpy((void*)&sourceArea, fRecvBuffer + fRecvPosition, size);

		area_info areaInfo;
		if (get_area_info(sourceArea, &areaInfo) < B_OK)
			fReadError = B_BAD_VALUE;

		if (fReadError >= B_OK) {
			void* areaAddress = areaInfo.address;

			if (areaAddress && sourceArea >= B_OK) {
				memcpy(data, areaAddress, passedSize);
				delete_area(sourceArea);
			}
		}
	} else {
		memcpy(data, fRecvBuffer + fRecvPosition, size);
	}
	fRecvPosition += size;
	return fReadError;
}
コード例 #3
0
BBufferGroup *VideoRecorderNode::GetBitmapBufferGroup(void)
{
	BBufferGroup *my_group = new BBufferGroup; 
	area_info bm_info; 
	if (bitmap != NULL)
	{
		if (get_area_info(bitmap->Area(), &bm_info) != B_OK)
			return NULL;
		buffer_clone_info bc_info; 
		bc_info.area = bm_info.area; 
		bc_info.offset = ((char *) bitmap->Bits())-((char *) bm_info.address); 
		bc_info.size = bitmap->BitsLength(); 
		BBuffer *out_buffer = NULL; 
		if(my_group->AddBuffer(bc_info, &out_buffer) != B_OK)
			return NULL;
		else
		{
			out_buffer->Recycle();
			return my_group;
		}
	}
	else
		return NULL;
}
コード例 #4
0
static guarded_heap_page*
guarded_heap_area_allocation_for(void* address, area_id& allocationArea)
{
	allocationArea = area_for(address);
	if (allocationArea < 0)
		return NULL;

	area_info areaInfo;
	if (get_area_info(allocationArea, &areaInfo) != B_OK)
		return NULL;

	guarded_heap_page* page = (guarded_heap_page*)areaInfo.address;
	if (page->flags != (GUARDED_HEAP_PAGE_FLAG_USED
			| GUARDED_HEAP_PAGE_FLAG_FIRST | GUARDED_HEAP_PAGE_FLAG_AREA)) {
		return NULL;
	}

	if (page->allocation_base != address)
		return NULL;
	if (page->allocation_size >= areaInfo.size)
		return NULL;

	return page;
}
コード例 #5
0
ファイル: AreaLink.cpp プロジェクト: mmanley/Antares
void
AreaLink::SetTarget(area_id area, bool isAreaLinkArea)
{
	area_info targetInfo;

	if (get_area_info(area, &targetInfo) == B_OK) {
		fTarget = area;
		fAreaIsOk = true;
		fHeader = (AreaLinkHeader *)targetInfo.address;

		if (isAreaLinkArea)
			_ReadAttachments();
		else {
			fHeader->MakeEmpty();
			fHeader->SetInfo(targetInfo);
		}

		fBaseAddress = (int8*)targetInfo.address;
		fBaseAddress += sizeof(AreaLinkHeader);
	} else {
		fTarget = B_NAME_NOT_FOUND;
		fAreaIsOk = false;
	}
}
コード例 #6
0
ファイル: Requests.cpp プロジェクト: DonCN/haiku
	template<typename R> status_t operator()(R* request)
	{
		// check the request buffer size
		if (fRequestBufferSize < (int32)sizeof(R))
			RETURN_ERROR(B_BAD_DATA);
		// no need to relocate the addresses of a reply that indicates an error
		if (is_error_reply(request)) {
			fSuccess = true;
			return B_OK;
		}
		// get the address infos
		AddressInfo infos[MAX_REQUEST_ADDRESS_COUNT];
		int32 count = 0;
		status_t error = request->GetAddressInfos(infos, &count);
		if (error != B_OK)
			RETURN_ERROR(error);
		// check and relocate the addresses
		for (int32 i = 0; i < count; i++) {
			// check
			Address* address = infos[i].address;
			int32 size = address->GetSize();
			int32 offset = address->GetOffset();
//PRINT(("  relocating address: area: %ld, offset: %ld, size: %ld...\n",
//address->GetArea(), offset, size));
			if (offset < 0 || size < 0 || size > infos[i].max_size)
				RETURN_ERROR(B_BAD_DATA);
			if ((infos[i].flags & ADDRESS_NOT_NULL) && size == 0)
				RETURN_ERROR(B_BAD_DATA);
			// relocate
			area_id area = address->GetArea();
			if (area < 0) {
				// data in the buffer itself
				if (offset == 0 && size == 0) {
//PRINT(("    -> relocated address: NULL\n"));
					address->SetRelocatedAddress(NULL);
				} else {
					if (offset < (int32)sizeof(R)
						|| offset + size > fRequestBufferSize) {
						RETURN_ERROR(B_BAD_DATA);
					}
//PRINT(("    -> relocated address: %p\n", (uint8*)request + offset));
					address->SetRelocatedAddress((uint8*)request + offset);
				}
			} else {
				// clone the area
				void* data;
				area = clone_area("cloned request data", &data,
#ifdef _KERNEL_MODE
					B_ANY_KERNEL_ADDRESS,
#else
					B_ANY_ADDRESS,
#endif
					B_READ_AREA, area);
				if (area < 0)
					RETURN_ERROR(area);
				fAreas[(*fAreaCount)++] = area;
				// check offset and size
				area_info areaInfo;
				error = get_area_info(area, &areaInfo);
				if (error != B_OK)
					RETURN_ERROR(error);
				if (offset + size > (int32)areaInfo.size)
					RETURN_ERROR(B_BAD_DATA);
//PRINT(("    -> relocated address: %p\n", (uint8*)data + offset));
				address->SetRelocatedAddress((uint8*)data + offset);
			}
		}
		// finally let the request check its integrity
		error = request->Check();
		if (error != B_OK)
			RETURN_ERROR(error);
		fSuccess = true;
//PRINT(("RequestRelocator done: success\n"));
		return B_OK;
	}
コード例 #7
0
status_t
_user_system_profiler_start(struct system_profiler_parameters* userParameters)
{
	// copy params to the kernel
	struct system_profiler_parameters parameters;
	if (userParameters == NULL || !IS_USER_ADDRESS(userParameters)
		|| user_memcpy(&parameters, userParameters, sizeof(parameters))
			!= B_OK) {
		return B_BAD_ADDRESS;
	}

	// check the parameters
	team_id team = thread_get_current_thread()->team->id;

	area_info areaInfo;
	status_t error = get_area_info(parameters.buffer_area, &areaInfo);
	if (error != B_OK)
		return error;

	if (areaInfo.team != team)
		return B_BAD_VALUE;

	if ((parameters.flags & B_SYSTEM_PROFILER_SAMPLING_EVENTS) != 0) {
		if (parameters.stack_depth < 1)
			return B_BAD_VALUE;

		if (parameters.interval < B_DEBUG_MIN_PROFILE_INTERVAL)
			parameters.interval = B_DEBUG_MIN_PROFILE_INTERVAL;

		if (parameters.stack_depth > B_DEBUG_STACK_TRACE_DEPTH)
			parameters.stack_depth = B_DEBUG_STACK_TRACE_DEPTH;
	}

	// quick check to see whether we do already have a profiler installed
	InterruptsSpinLocker locker(sProfilerLock);
	if (sProfiler != NULL)
		return B_BUSY;
	locker.Unlock();

	// initialize the profiler
	SystemProfiler* profiler = new(std::nothrow) SystemProfiler(team, areaInfo,
		parameters);
	if (profiler == NULL)
		return B_NO_MEMORY;
	ObjectDeleter<SystemProfiler> profilerDeleter(profiler);

	error = profiler->Init();
	if (error != B_OK)
		return error;

	// set the new profiler
	locker.Lock();
	if (sProfiler != NULL)
		return B_BUSY;

	profilerDeleter.Detach();
	sProfiler = profiler;
	locker.Unlock();

	return B_OK;
}
コード例 #8
0
status_t
start_system_profiler(size_t areaSize, uint32 stackDepth, bigtime_t interval)
{
	struct ParameterDeleter {
		ParameterDeleter(area_id area)
			:
			fArea(area),
			fDetached(false)
		{
		}

		~ParameterDeleter()
		{
			if (!fDetached) {
				delete_area(fArea);
				delete sRecordedParameters;
				sRecordedParameters = NULL;
			}
		}

		void Detach()
		{
			fDetached = true;
		}

	private:
		area_id	fArea;
		bool	fDetached;
	};

	void* address;
	area_id area = create_area("kernel profile data", &address,
		B_ANY_KERNEL_ADDRESS, areaSize, B_FULL_LOCK,
		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
	if (area < 0)
		return area;

	ParameterDeleter parameterDeleter(area);

	sRecordedParameters = new(std::nothrow) system_profiler_parameters;
	if (sRecordedParameters == NULL)
		return B_NO_MEMORY;

	sRecordedParameters->buffer_area = area;
	sRecordedParameters->flags = B_SYSTEM_PROFILER_TEAM_EVENTS
		| B_SYSTEM_PROFILER_THREAD_EVENTS | B_SYSTEM_PROFILER_IMAGE_EVENTS
		| B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS
		| B_SYSTEM_PROFILER_SAMPLING_EVENTS;
	sRecordedParameters->locking_lookup_size = 4096;
	sRecordedParameters->interval = interval;
	sRecordedParameters->stack_depth = stackDepth;

	area_info areaInfo;
	get_area_info(area, &areaInfo);

	// initialize the profiler
	SystemProfiler* profiler = new(std::nothrow) SystemProfiler(B_SYSTEM_TEAM,
		areaInfo, *sRecordedParameters);
	if (profiler == NULL)
		return B_NO_MEMORY;

	ObjectDeleter<SystemProfiler> profilerDeleter(profiler);

	status_t error = profiler->Init();
	if (error != B_OK)
		return error;

	// set the new profiler
	InterruptsSpinLocker locker(sProfilerLock);
	if (sProfiler != NULL)
		return B_BUSY;

	parameterDeleter.Detach();
	profilerDeleter.Detach();
	sProfiler = profiler;
	locker.Unlock();

	return B_OK;
}
コード例 #9
0
status_t
VideoConsumer::CreateBuffers(const media_format& format)
{
	FUNCTION("VideoConsumer::CreateBuffers\n");
	
	// delete any old buffers
	DeleteBuffers();	

	status_t status = B_OK;

	// create a buffer group
	uint32 width = format.u.raw_video.display.line_width;
	uint32 height = format.u.raw_video.display.line_count;	
	color_space colorSpace = format.u.raw_video.display.format;
	PROGRESS("VideoConsumer::CreateBuffers - Width = %ld - Height = %ld - "
		"Colorspace = %d\n", width, height, colorSpace);

	fBuffers = new BBufferGroup();
	status = fBuffers->InitCheck();
	if (B_OK != status) {
		ERROR("VideoConsumer::CreateBuffers - ERROR CREATING BUFFER GROUP\n");
		return status;
	}

	// and attach the bitmaps to the buffer group
	BRect bounds(0, 0, width - 1, height - 1);
	for (uint32 i = 0; i < kBufferCount; i++) {
		// figure out the bitmap creation flags
		uint32 bitmapFlags = 0;
		if (fTryOverlay) {
			// try to use hardware overlay
			bitmapFlags |= B_BITMAP_WILL_OVERLAY;
			if (i == 0)
				bitmapFlags |= B_BITMAP_RESERVE_OVERLAY_CHANNEL;
		} else
			bitmapFlags = B_BITMAP_IS_LOCKED;
			
		fBitmap[i] = new BBitmap(bounds, bitmapFlags, colorSpace);
		status = fBitmap[i]->InitCheck();
		if (status >= B_OK) {
			buffer_clone_info info;

			uint8* bits = (uint8*)fBitmap[i]->Bits();
			info.area = area_for(bits);
			area_info bitmapAreaInfo;
			status = get_area_info(info.area, &bitmapAreaInfo);
			if (status != B_OK) {
				fprintf(stderr, "VideoConsumer::CreateBuffers() - "
					"get_area_info(): %s\n", strerror(status));
				return status;
			}

//printf("area info for bitmap %ld (%p):\n", i, fBitmap[i]->Bits());
//printf("        area: %ld\n", bitmapAreaInfo.area);
//printf("        size: %ld\n", bitmapAreaInfo.size);
//printf("        lock: %ld\n", bitmapAreaInfo.lock);
//printf("  protection: %ld\n", bitmapAreaInfo.protection);
//printf("    ram size: %ld\n", bitmapAreaInfo.ram_size);
//printf("  copy_count: %ld\n", bitmapAreaInfo.copy_count);
//printf("   out_count: %ld\n", bitmapAreaInfo.out_count);
//printf("     address: %p\n", bitmapAreaInfo.address);

			info.offset = bits - (uint8*)bitmapAreaInfo.address;
			info.size = (size_t)fBitmap[i]->BitsLength();
			info.flags = 0;
			info.buffer = 0;
				// the media buffer id

			BBuffer* buffer = NULL;
			if ((status = fBuffers->AddBuffer(info, &buffer)) != B_OK) {
				ERROR("VideoConsumer::CreateBuffers - ERROR ADDING BUFFER "
					"TO GROUP (%ld): %s\n", i, strerror(status));
				return status;
			} else {
				PROGRESS("VideoConsumer::CreateBuffers - SUCCESSFUL ADD "
					"BUFFER TO GROUP\n");
			}
			fBufferMap[i] = buffer;
		} else {
			ERROR("VideoConsumer::CreateBuffers - ERROR CREATING VIDEO RING "
				"BUFFER (Index %ld Width %ld Height %ld Colorspace %d: %s\n",
				i, width, height, colorSpace, strerror(status));
			return status;
		}	
	}
	
	FUNCTION("VideoConsumer::CreateBuffers - EXIT\n");
	return status;
}
コード例 #10
0
ファイル: driver.c プロジェクト: mmanley/Antares
static status_t init_ring_buffers(dp83815_properties_t *data)
{
	uint32			i;
	area_info		info;
	physical_entry	map[2];
	uint32 pages;

	descriptor_t	*RxDescRing = NULL;
	descriptor_t	*TxDescRing = NULL;

	descriptor_t	*desc_base_virt_addr;
	uint32			desc_base_phys_addr;

	void			*buff_base_virt_addr;
	uint32			buff_base_phys_addr;


	data->mem_area = 0;

#define NUM_BUFFS	2*MAX_DESC

	pages = pages_needed(2*MAX_DESC*sizeof(descriptor_t) + NUM_BUFFS*BUFFER_SIZE);

	data->mem_area = create_area(kDevName " desc buffer", (void**)&RxDescRing,
		B_ANY_KERNEL_ADDRESS, pages * B_PAGE_SIZE, B_CONTIGUOUS,
		B_READ_AREA | B_WRITE_AREA);
	if( data->mem_area < 0 )
		return -1;

	get_area_info(data->mem_area, &info);
	get_memory_map(info.address, info.size, map, 4);

	desc_base_phys_addr = (int)map[0].address + NUM_BUFFS*BUFFER_SIZE;
	desc_base_virt_addr = (info.address + NUM_BUFFS*BUFFER_SIZE);

	buff_base_phys_addr = (int)map[0].address;
	buff_base_virt_addr = info.address;

	RxDescRing = desc_base_virt_addr;
	for( i = 0; i < MAX_DESC; i++ ) {
		RxDescRing[i].link = desc_base_phys_addr + ((i+1)%MAX_DESC)*sizeof(descriptor_t);
		RxDescRing[i].cmd = MAX_PACKET_SIZE;
		RxDescRing[i].ptr = buff_base_phys_addr +i*BUFFER_SIZE;
		RxDescRing[i].virt_next = &RxDescRing[(i+1)%MAX_DESC];
		RxDescRing[i].virt_buff = buff_base_virt_addr + i*BUFFER_SIZE;
	}

	TxDescRing = desc_base_virt_addr + MAX_DESC;
	for( i = 0; i < MAX_DESC; i++ ) {
		TxDescRing[i].link = desc_base_phys_addr + MAX_DESC*sizeof(descriptor_t)+ ((i+1)%MAX_DESC)*sizeof(descriptor_t);
		TxDescRing[i].cmd = MAX_PACKET_SIZE;
		TxDescRing[i].ptr = buff_base_phys_addr + ((i+MAX_DESC)*BUFFER_SIZE);
		TxDescRing[i].virt_next = &TxDescRing[(i+1)%MAX_DESC];
		TxDescRing[i].virt_buff = buff_base_virt_addr + ((i+MAX_DESC)*BUFFER_SIZE);
	}

	data->Rx.Curr = RxDescRing;
	data->Tx.Curr = TxDescRing;

	data->Rx.CurrInt = RxDescRing;
	data->Tx.CurrInt = TxDescRing;


	write32(REG_RXDP, desc_base_phys_addr);		/* set the initial rx descriptor	*/

	i = desc_base_phys_addr+MAX_DESC*sizeof(descriptor_t);
	write32(REG_TXDP, i);							/* set the initial tx descriptor	*/

	return B_OK;
}
コード例 #11
0
ファイル: iwdma.c プロジェクト: HaikuArchives/InterWave
status_t iw_find_low_memory(interwave_dev * iw)
{
	size_t low_size = (MIN_MEMORY_SIZE+(B_PAGE_SIZE-1))&~(B_PAGE_SIZE-1);
	size_t allocate_size;
	physical_entry where;
	uint32 boundary;
	size_t trysize;
	area_id curarea;
	void * addr;
	char name[DEVNAME];

	if (low_size < MIN_MEMORY_SIZE) {
		low_size = MIN_MEMORY_SIZE;
	}
	if (low_size > 65536) {
		iwprintf("too much low memory requested !");
		low_size = 65536;
	}
	
	allocate_size = 2*low_size;

	sprintf(name, "%s_low", iw->name);
	
	curarea = find_area(name);
	if (curarea >= 0) {	/* area there from previous run */
		area_info ainfo;
		iwprintf("testing likely candidate...");
		if (get_area_info(curarea, &ainfo)) {
			iwprintf("no info");
			goto allocate;
		}
		/* test area we found */
		trysize = ainfo.size;
		addr = ainfo.address;
		if (trysize < allocate_size) {
			iwprintf("too small (%x)", trysize);
			goto allocate;
		}
		if (get_memory_map(addr, trysize, &where, 1) < B_OK) {
			iwprintf("no memory map");
			goto allocate;
		}
		if ((uint32)where.address & 0xff000000) {
			iwprintf("bad physical address");
			goto allocate;
		}
		if (ainfo.lock < B_FULL_LOCK || where.size < allocate_size) {
			iwprintf("lock not contiguous");
			goto allocate;
		}
		goto a_o_k;
	}

allocate:
	if (curarea >= 0) {
		delete_area(curarea); /* area didn't work */
		curarea = -1;
	}

	iwprintf("allocating new low area");

	trysize = allocate_size;
	curarea = create_area(name, &addr, B_ANY_KERNEL_ADDRESS, 
		trysize, B_LOMEM, B_READ_AREA | B_WRITE_AREA);
	iwprintf("create_area(%d) returned area %x at logical 0x%08x", trysize, curarea, addr);
	if (curarea < 0) {
		goto oops;
	}
	if (get_memory_map(addr, allocate_size, &where, 1) < 0) {
		delete_area(curarea);
		curarea = B_ERROR;
		goto oops;
	}
	if ((uint32)where.address & 0xff000000) {                 // does not start in low memory
		delete_area(curarea);
		curarea = B_ERROR;
		goto oops;
	}
	if (((uint32)where.address+allocate_size) & 0xff000000) { // does not end in low memory
		delete_area(curarea);
		curarea = B_ERROR;
		goto oops;
	}

oops:
	if (curarea < 0) {
		dprintf("interwave: failed to create low_mem area\n");
		return curarea;
	}
	
a_o_k:
	iwprintf("successfully found or created low area!");
	iwprintf("physical 0x%08x-0x%08x logical 0x%08x size %d", where.address, 
		where.address+trysize-1, addr, trysize);
	
	iw->low_size = low_size;
	iw->low_area = curarea;

	// The resulting double-sized area probably crosses a 64K boundary.
	// Let's change the start address so that the final, normal-sized one does not.

	// The first boundary possibly crossed
	boundary = ((uint32)where.address & 0xffff0000) + 0x00010000;
	
	// The good chunk (low_size bytes not crossing a 64K boundary) may be
	// either below or above the first boundary.
	if((boundary-(uint32)where.address) >= low_size) { // it's below, nothing to change
		iw->low_mem = (uchar *)addr;
		iw->low_phys = (vuchar *)where.address;
		
		iwprintf("current size is %d bytes",trysize);
		iwprintf("keeping %d bytes",low_size);
		if(trysize>low_size)
			resize_area(curarea,low_size);
	} else {                                           // it's above - bump up start address
		uint32 delta = boundary - (uint32)where.address;
	
		iw->low_mem = (uchar *)addr + delta;
		iw->low_phys = (vuchar *)boundary;
		
		// Unfortunately, what's below the boundary (delta bytes) is wasted.
		// We can't truncate an area's bottom.
		iwprintf("current size is %d bytes",trysize);
		iwprintf("keeping %d bytes, waste=%d",low_size+delta,delta);
		if(trysize>low_size+delta)
			resize_area(curarea,low_size+delta);
	}
	
	iwprintf("using physical 0x%08x-0x%08x logical 0x%08x size %d", iw->low_phys,
		iw->low_phys+iw->low_size-1, iw->low_mem, iw->low_size);

	return B_OK;
}
コード例 #12
0
ファイル: support.c プロジェクト: BALDELab/incubator-hawq
void
beos_startup(int argc, char **argv)
{
	if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster"))
	{
		/*
		 * We are in the postmaster, create the protection semaphore for
		 * shared mem remapping
		 */
		beos_shm_sem = create_sem(1, "beos_shm_sem");
	}

	if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0)
	{
		/* We are in the support server, run it ... */

		port_id		port_in;
		port_id		port_out;

		/* Get back port ids from arglist */
		sscanf(argv[2], "%d", (int *) (&port_in));
		sscanf(argv[3], "%d", (int *) (&port_out));

		/* Main server loop */
		for (;;)
		{
			int32 opcode = 0;
			char		datas[4000];

			/*
			 * Wait for a message from the backend : 1 : load a shared object
			 * 2 : unload a shared object any other : exit support server
			 */
			read_port(port_in, &opcode, datas, 4000);

			switch (opcode)
			{
					image_id	addon;
					image_info	info_im;
					area_info	info_ar;
					void	   *fpt;

					/* Load Add-On */
				case 1:

					/* Load shared object */
					addon = load_add_on(datas);

					/* send back the shared object Id */
					write_port(port_out, addon, NULL, 0);

					/* Get Shared Object infos */
					get_image_info(addon, &info_im);

					/* get text segment info */
					get_area_info(area_for(info_im.text), &info_ar);
					/* Send back area_id of text segment */
					write_port(port_out, info_ar.area, info_ar.name, strlen(info_ar.name) + 1);
					/* Send back real address of text segment */
					write_port(port_out, (int) info_ar.address, info_ar.name, strlen(info_ar.name) + 1);


					/* get data segment info */
					get_area_info(area_for(info_im.data), &info_ar);
					/* Send back area_id of data segment */
					write_port(port_out, info_ar.area, info_ar.name, strlen(info_ar.name) + 1);
					/* Send back real address of data segment */
					write_port(port_out, (int) info_ar.address, info_ar.name, strlen(info_ar.name) + 1);
					break;
					/* UnLoad Add-On */
				case 2:

					/*
					 * Unload shared object and send back the result of the
					 * operation
					 */
					write_port(port_out, unload_add_on(*((int *) (datas))), NULL, 0);
					break;
					/* Cleanup and exit */
				case 3:

					/* read image Id on the input port */
					read_port(port_in, &addon, NULL, 0);

					/* Loading symbol */
					fpt = NULL;


					if (get_image_symbol(addon, datas, B_SYMBOL_TYPE_TEXT, &fpt) == B_OK);
					{
						/*
						 * Sometime the loader return B_OK for an inexistant
						 * function with an invalid address !!! Check that the
						 * return address is in the image range
						 */

						get_image_info(addon, &info_im);
						if ((fpt < info_im.text) ||(fpt >= (info_im.text +info_im.text_size)))
							fpt = NULL;
					}

					/* Send back fptr of data segment */
					write_port(port_out, (int32) (fpt), NULL, 0);
					break;

				default:
					/* Free system resources */
					delete_port(port_in);
					delete_port(port_out);
					/* Exit */
					exit(0);
					break;
			}
		}
		/* Never be there */
		exit(1);
	}
}