V8/usr/src/cmd/cyntax/cem/read.c

Compare this file to the similar file:
Show the results in this format:

#include	<errno.h>
#include	"cem.h"
#define	STD_OBJ	1
#include	"stdobj.h"

/*
 *	Read and load an object file.
 */
static void
read_obj(s, fd)
register char	*s;
register int	fd;
{
	register int	i;
	register long	sz;
	header		obj_header;
	static char	cmd[]	= CMD;
	static char	mac[]	= MAC;
	extern void	enter_types();
	extern void	enter_vars();
	extern void	install_strings();

	switch (read(fd, (char *)&obj_header, sizeof (header)))
	{
	case SYSERROR:
		fprintf(stderr, "%s: could not read ", my_name);
		fflush(stderr);
		perror(s);
		exit(1);

	case sizeof (header):
		break;

	default:
		fprintf(stderr, "%s: %s is not an object module\n", my_name, s);
		exit(1);
	}

	if (strncmp(obj_header.hd_cmd, cmd, CMD_SZ) != 0)
	{
		fprintf(stderr, "%s: %s is not an object module\n", my_name, s);
		exit(1);
	}

	if (strncmp(obj_header.hd_mac, mac, MAC_SZ) != 0)
	{
		fprintf(stderr, "%s: version mismatch for %s (recompile)\n", my_name, s);
		exit(1);
	}

	if (obj_header.hd_type_size == 0)
	{
		fprintf(stderr, "%s: %s has compilation errors\n", my_name, s);
		exit(1);
	}

	sz = obj_header.hd_str_off + obj_header.hd_str_size - sizeof (header);
	data_base = salloc(sz);
	str_base = data_base + obj_header.hd_str_off - sizeof (header) - 1;

	if ((i = read(fd, data_base, (int)sz)) != sz)
	{
		if (i == SYSERROR)
		{
			fprintf(stderr, "%s: could not read ", my_name);
			fflush(stderr);
			perror(s);
		}
		else
			fprintf(stderr, "%s: %s is too small\n", my_name, s);

		exit(1);
	}

#if	DEBUG
	if (debug)
	{
		register char	*id;
		register long	l0;
		register long	l1;
		register long	l2;

		data_ptr = data_base;
		data_end = data_base + obj_header.hd_str_off - sizeof (header);
		type_index = 1;
		var_index = 1;
		str_num = 0;

		while (data_ptr < data_end)
		{
			i = getd();

			switch (obj_item(i))
			{
			case i_data:
				l0 = getv();
				l1 = getv();
				printf("data: var %ld (%s:%ld)\n", l0, &str_base[l1], getv());

				loop
				{
					i = getd();

					switch (obj_item(i))
					{
					case d_addr:
						printf("\taddr var %ld for %ld\n", get4(), obj_id(i));
						continue;

					case d_bytes:
						if (obj_id(i) == 0)
							l0 = getv();
						else
							l0 = obj_id(i);

						printf("\tbytes %ld\n", l0);
						data_ptr += l0;
						continue;

					case d_end:
						printf("\tend\n");
						break;

					case d_istring:
						if (obj_id(i) == 0)
							l0 = getv();
						else
							l0 = obj_id(i);

						data_ptr += l0;
						printf("\tstring %ld, length %ld\n", str_num++, l0);
						continue;

					case d_irstring:
						if (obj_id(i) == 0)
							l0 = getv();
						else
							l0 = obj_id(i);

						data_ptr += l0;
						printf("\tstring %ld + %ld, length %ld\n", str_num++, get4(), l0);
						continue;

					case d_space:
						printf("\tspace %ld\n", obj_id(i) == 0 ? getv() : obj_id(i));
						continue;

					case d_string:
						printf("\tstring %ld\n", getv());
						continue;

					case d_reloc:
						l0 = getv();
						printf("\treloc var %ld + %ld for %ld\n", l0, get4(), obj_id(i));
						continue;

					case d_rstring:
						l0 = getv();
						printf("\tstring %ld + %ld\n", l0, get4());
						continue;

					default:
						fprintf(stderr, "%s: unknown data id %d\n", my_name, i);
						exit(1);
					}

					break;
				}

				break;

			case i_lib:
				printf("lib: %s\n", &str_base[getv()]);
				break;

			case i_src:
				printf("src: %s\n", &str_base[getv()]);
				break;

			case i_string:
				if (obj_id(i) == 0)
					l0 = getv();
				else
					l0 = obj_id(i);

				printf("string %ld, length %ld\n", str_num++, l0);
				data_ptr += l0;
				break;

			case i_type:
				printf("type ");

				switch (obj_id(i))
				{
				case t_arrayof:
					l0 = getv();
					l1 = getv();
					printf("%ld: array %ld of %ld\n", type_index++, l0, l1);
					break;

				case t_basetype:
					printf("%ld: ", type_index++);
					print_basetype(getd() & 0xFF);
					printf("\n");
					break;

				case t_bitfield:
					l0 = getv();
					l1 = getv();
					printf("%ld: bitfield %ld of %ld\n", type_index++, l0, l1);
					break;

				case t_dimless:
					printf("%ld: array [] of %ld\n", type_index++, getv());
					break;

				case t_elaboration:
					l0 = getv();
					l1 = getv();
					printf("elab %ld: (%s:%ld) ", l0, &str_base[l1], getv());
					
					switch (i = obj_id(getd()))
					{
					case t_enum:
						printf("enum\n");
						l0 = getv();
						goto elab_enum;

					case t_structof:
						printf("struct\n");
						l0 = getv();

						do
						{
							l1 = getv();
							printf("\t%s = %ld @ %ld\n", &str_base[l0], l1, getv());
							l0 = getv();
						}
						while (l0 != 0);

						printf("\t(%ld)\n", getv());
						break;

					case t_unionof:
						printf("union\n");
						l0 = getv();

						do
						{
							l1 = getv();
							printf("\t%s = %ld\n", &str_base[l0], l1);
							l0 = getv();
						}
						while (l0 != 0);

						printf("\t(%ld)\n", getv());
						break;

					default:
						fprintf(stderr, "%s: unknown elaboration id %d\n", my_name, i);
						exit(1);
					}

					break;

				case t_enum:
					printf("%ld: ", type_index++);

					if ((l0 = getv()) == 0)
						id = "<anon>";
					else
						id = &str_base[l0];

					l0 = getv();
					l1 = getv();

					printf("enum %s (%s:%ld)\n", id, &str_base[l0], l1);

					if ((l0 = getv()) == 0)
					{
						printf("\tforward\n");
						break;
					}

				elab_enum:
					do
					{
						l1 = getu();
						printf("\t%s = %ld\n", &str_base[l0], l1);
						l0 = getv();
					}
					while (l0 != 0);

					l0 = getu();
					l1 = getu();

					printf("\t(%ld, %ld)\n", l0, l1);
					break;

				case t_ftnreturning:
					printf("%ld: function returning %ld\n", type_index++, getv());
					break;

				case t_ptrto:
					printf("%ld: pointer to %ld\n", type_index++, getv());
					break;

				case t_structof:
					printf("%ld: ", type_index++);

					if ((l0 = getv()) == 0)
						id = "<anon>";
					else
						id = &str_base[l0];

					l0 = getv();
					l1 = getv();

					printf("struct %s (%s:%ld)\n", id, &str_base[l0], l1);
					break;

				case t_unionof:
					printf("%ld: ", type_index++);

					if ((l0 = getv()) == 0)
						id = "<anon>";
					else
						id = &str_base[l0];

					l0 = getv();
					l1 = getv();

					printf("union %s (%s:%ld)\n", id, &str_base[l0], l1);
					break;

				default:
					fprintf(stderr, "%s: unknown type id %d\n", my_name, obj_id(i));
					exit(1);
				}

				break;

			case i_var:
				printf("var ");

				switch (obj_id(i))
				{
				case v_arglist:
					l0 = getv();
					l1 = getv();
					printf("arglist: %ld (%s:%ld)\n", l0, &str_base[l1], getv());

					while ((l0 = getv()) != 0)
					{
						l1 = getv();
						l2 = getv();
						printf("\t%ld: %s type %ld (%s:%ld)\n", var_index++, &str_base[l0], l1, &str_base[l2], getv());
					}

					break;

				case v_array_size:
					l0 = getv();
					printf("array %ld new type %ld\n", l0, getv());
					break;

				case v_auto:
					id = "auto";
					goto get_var;

				case v_block_static:
					id = "block static";
					goto get_var;

				case v_call:
					l0 = getv();
					l1 = getv();
					printf("call: var %ld (%s:%ld)\n", l0, &str_base[l1], getv());

					while ((l0 = getv()) != 0)
						printf("\ttype %ld\n", l0);

					break;

				case v_global:
					id = "global";
					goto get_var;

				case v_implicit_function:
					id = "implicit()";
					goto get_var;

				case v_static:
					id = "static";
					goto get_var;

				get_var:
					l0 = getv();
					l1 = getv();
					l2 = getv();
					printf("%ld: %s %s type %ld (%s:%ld)\n", var_index++, id, &str_base[l0], l1, &str_base[l2], getv());
					break;

				case v_varargs:
					l0 = getv();
					printf("%ld: varargs %ld\n", l0, getv());
					break;

				default:
					fprintf(stderr, "%s: unknown var id %d\n", my_name, obj_id(i));
					exit(1);
				}

				break;

			default:
				fprintf(stderr, "%s: unknown obj_item %d\n", my_name, obj_item(i));
				exit(1);
			}
		}

		fflush(stdout);
	}
#endif	DEBUG

	file_errors = 0;
	install_strings(str_base + 1, obj_header.hd_str_size);

	type_index = 1;
	data_ptr = data_base;
	data_end = data_base + obj_header.hd_str_off - sizeof (header);
	enter_types(obj_header.hd_type_size);

	str_num = 0;
	var_index = 1;
	data_ptr = data_base;
	data_end = data_base + obj_header.hd_str_off - sizeof (header);
	enter_vars(obj_header.hd_var_size);

	free((char *)str_trans);
	free((char *)type_trans);
	free((char *)var_trans);
	free(data_base);
	src_file = NULL;

	if (file_errors)
		fflush(stdout);
}

/*
 *	Open a library and load it.
 */
void
load_lib(l)
char	*l;
{
	register int	fd;
	register char	*s;
	extern int	errno;
	extern char	*strcat();
	extern char	*strcpy();

	s = salloc(strlen(LIB_PATH) + strlen(l) + 1L);
	(void)strcat(strcpy(s, LIB_PATH), l);

	if ((fd = open(s, 0)) == SYSERROR)
	{
		if (errno == ENOENT)
			fprintf(stderr, "%s: no library '-l%s'\n", my_name, l);
		else
		{
			fprintf(stderr, "%s: could not open ", my_name);
			fflush(stderr);
			perror(s);
		}

		exit(1);
	}

	read_obj(s, fd);
	free(s);
	(void)close(fd);
}

/*
 *	Open an object file and load it.
 */
void
load_obj(s)
register char	*s;
{
	register int	fd;

	if ((fd = open(s, 0)) == SYSERROR)
	{
		fprintf(stderr, "%s: could not open ", my_name);
		fflush(stderr);
		perror(s);
		exit(1);
	}

	read_obj(s, fd);
	(void)close(fd);
}