From: oliverm@nevada.edu (Moises Oliveira )
Subject: Re: PLEASE help me with rld!
Organization: Organization? Ha, don't make me laugh
Date: Sat, 22 Aug 1992 15:47:17 GMT

In article <HRA6NUH@mailgzrz.tu-berlin.de> mauriti@cs.tu-berlin.de (Frank Hartlep) writes:
>I've asked this already and nobody replied. But I can't believe there's
>nobody on this big, big net who knows how to use rld.
>

Probably because no one ever saw it.  I certainly didn't.

> ... and PLEASE!  PLEASE!  PLEASE!  PLEASE! tell me what's wrong with it.
> Loader should load to_be_loaded.o and execute LoadedFunction.
> Sounds easy, but why does it fail in rld_load_basefile (with a
> floating point exception in NXCreateZone, as the debugger tells me)???
> 

	This isn't the way rld(3) works.  There are two problems in
this example.  The solution to your immediate problem
first: 

>  ld -o loader.gdb loader.o /lib/crt0.o /lib/libsys_s.a -U _LoadedFunction

is wrong.   Use

	ld -o loader.gdb -lcrt0.o loader.o -lsys_s -U _LoadedFunction

That will stop the problem you are having NOW, the code
will no longer crash at the first function call in the
program.  But bigger problems lurk in the code you have
here.  the rld(3) set of calls is not used in the way you are
trying to use it.  Here's a quick primer to convert your
code to working code: 

First off, your call to  rld_load_basefile is completely
unnecessary.  Remove it. 

Second, if possible compose the full pathname to the file
to be loaded.  The current working directory is seldom the
same directory that an application resides in.  In the
code below, I have hard-coded the path.  (To keep it short) 


This is not the way rld(3) works:

>        LoadedFunction ("It works!");

It doesn't automagically change all references to
LoadedFunction to point to the newly loaded code.  What
you are doing ( with -U) is allowing the linker to set
LoadedFunction to point to (0x0),  so that as soon as the
above line is executed your program will crash anyways.

What rld(3) does is load the code and text from the
MH_OBJECT file, and then provide a way for you to find the
entry points of functions, and the addresses of
variables, by using rld_lookup().

What you need to do is ask rld_lookup for the address of
"_LoadedFunction", and then call that address using a
pointer to a function.  The name that "loader" uses does
not bear any relation to the name of the function in
"to_be_loaded". 


Here are the programs done correctly:


>--- loader.c

#include <mach-o/rld.h>
#include <stdio.h>

int main ()
{
	char		*ObjectFiles [] = {"/tmp/rld/to_be_loaded.o", NULL};
	int		Status;
// This is a pointer to a function called "theFunction",
// which takes a ( char *) for an arguement 
	long		(*theFunction) (const char *);

// we load the object files, and "check" for any errors
	Status = rld_load (NULL, NULL, ObjectFiles, NULL);
	fprintf (stderr, "rld_load returned %d\n", Status);

// we ask rld where the function has been loaded, and "check" for errors
	rld_lookup(NULL,"_LoadedFunction",&theFunction);
	fprintf (stderr, "rld_lookup returned %d\n", aStatus);

// now theFunction points to the newly loaded code. We call theFunction
	(* theFunction) ("It works!");
	return 0;
}

>---- to_be_loaded.c

#include <stdio.h>

void LoadedFunction (char *Text)
{
	printf ("%s\n", Text);
	return;
}

Finally, we compile, link and test the program.  Notice
that now that we are no longer trying to call a
non-existent function, we can get rid of the -U
siliness.  We can also quit calling ld directly, and use cc
to save us some heartache. 

cc -g -Wall -o loader.gdb loader.c
cc -g -Wall -c to_be_loaded.c

rld_load returned 1
rld_lookup returned 1
It works!


Newsgroups: comp.sys.next.programmer