/*
 * Copyright (C) 2000-2003 ASANO Masahiro
 */

#include <unistd.h>
#include "crash.h"

PRIVATE addr_t module();
const commandtable_t command_module =
	{"module", module, "[address]", "print module table"};

extern addr_t print_module();
extern addr_t getmsyms();

PRIVATE addr_t
module()
{
	int i, c;
	int full = 0;
	addr_t addr;
	extern void prhead_module();

	while ((c = getopt(argcnt, args, "f")) != EOF) {
		switch (c) {
		case 'f':
			full = 1;
			break;
		default:
			THROW(usage);
		}
	}

	if (argcnt > optind) {
		if (!full) prhead_module();
		for (i = optind; i < argcnt; i++) {
			addr = getvalue(args[i]);
			if (full) prhead_module();
			addr = print_module(addr, full);
		}
	} else {
#if LINUXVER>=25
		static addr_t modules_addr;
		struct list_head modules;	
		extern int module_offset_list;

		GETADDR(modules);
		memread(modules_addr, sizeof(modules), &modules, "modules");
		addr = (addr_t)modules.next;
		if (!full) prhead_module();
		while (addr && addr != modules_addr) {
			if (full) prhead_module();
			addr = print_module(addr - module_offset_list, full);
		}
#else
		static addr_t module_list_addr;
		GETADDR(module_list);
		memread(module_list_addr, sizeof(addr), &addr, "module_list");
		if (!full) prhead_module();
		while (addr) {
			if (full) prhead_module();
			addr = print_module(addr, full);
		}
#endif
	}
	return addr;
}

/*
 *	call at initializing
 */
void
get_module_symbol(addr)
	addr_t addr;
{
	TRY {
#if LINUXVER>=25
		struct list_head modules;	
		addr_t tmp;
		extern int module_offset_list;

		memread(addr, sizeof(modules), &modules, "modules");
		tmp = (addr_t)modules.next;
		while (tmp && addr != tmp) {
			tmp = getmsyms(tmp - module_offset_list);
		}
#else
		memread(addr, sizeof(addr), &addr, "module_list");
		while (addr) {
			addr = getmsyms(addr);
		}
#endif /*LINUXVER*/
	} CATCH {
		fprintf(stderr, "%s\n", except_message);
	}
	ENDTRY
}
