
/*
 *  $Header: /private/src/postgres/src/backend/port/dld/RCS/dynloader.c,v 1.1 1993/03/04 03:05:29 andrew Exp $
 */


/*
 * DLD ver 3.2.3
 *
 * How does this work?  
 *
 * pretty simple (read the DLD docs). But still need to make sure
 * loaded objects are compiled with "-G 0" on DECs.
 *
 */ 

#include <stdio.h>
#include "tmp/c.h"
#include "fmgr.h"

extern char pg_pathname[];
DynamicFunctionList *load_symbols();

DynamicFunctionList *
dynamic_file_load(err, filename, start_addr, size)

char **err, *filename, **start_addr;
long *size;

{
	static int dld_initialized= 0;

	if (!dld_initialized) {	  /* only need to do this once */
	    dld_init(pg_pathname);
	    dld_initialized= 1;
	}

	if (dld_link(filename))
	    dld_perror("dynamic_file_load: Can't link");

	/* note that start_addr and size will not (and should
	   not) be used by other routines, so we don't bother
	   to return anything real */
	*start_addr = 0;
	*size = 0;
	return load_symbols(filename,0);
}

/*
 * Cheat massively because I can't figure out how to read the symbol table
 * properly, so use system("nm ...") to do it instead.
 *
 * I choose to keep "nm" around because it takes only an insignificant 
 * amount of time to do. Also, DLD hashes the function names and addresses
 * which makes it hard to just pull out those for the desired object.
 *  -- AKY
 */

DynamicFunctionList *
load_symbols(filename, entry_addr)

char *filename; int entry_addr;

{
	char command[256];
	char line[128];
	char *tmp_file;
	FILE *fp;
	DynamicFunctionList *head, *scanner;
	int entering = 1, func_addr;
	char funcname[16];

	/* create a temporary file name */
	tmp_file = (char *) palloc(64);
	sprintf(tmp_file, "/tmp/_pg_dyn%ld", getpid());

	sprintf(command, "/usr/bin/nm %s | grep \' T \' > %s", filename, tmp_file);

	if (system(command))
		fprintf(stderr, "system() died\n");

	fp = fopen(tmp_file, "r");

	while (fgets(line, 127, fp) != NULL)
	{
		sscanf(line, "%lx T %s", &func_addr, funcname);
		if (entering)
		{
			head = (DynamicFunctionList *)
				   malloc(sizeof(DynamicFunctionList));
			scanner = head;
			entering = 0;
		}
		else
		{
			scanner->next = (DynamicFunctionList *)
							malloc(sizeof(DynamicFunctionList));
			scanner = scanner->next;
		}

		strncpy(scanner->funcname, funcname, 16);
		scanner->func = (func_ptr) (dld_get_func(funcname));
		scanner->next = NULL;
	}

	fclose(fp);
	unlink(tmp_file);
	pfree(tmp_file);
	return(head);
}
