view leo-obj/tool/chararray.c @ 392:35009c936a4a

compal/melody-extr: first attempt at actual melody extraction
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 01 Apr 2022 06:03:47 +0000
parents 069b79b36228
children
line wrap: on
line source

/*
 * Some COFF objects in TI's firmware semi-src are the result of compiling
 * a *.c file that contains nothing more than a const char array.  Here
 * we support the extraction of these char arrays, to enable recompilation
 * with our choice of compiler toolchain.
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "intstruct.h"
#include "coffconst.h"
#include "globals.h"

extern unsigned get_u16(), get_u32();

cmd_chararray(argc, argv)
	char **argv;
{
	int c, sflag = 0;
	unsigned n, array_len;
	char *array_name;
	struct internal_syment *sym;
	u_char *dp;
	extern int optind;
	extern char *optarg;

	while ((c = getopt(argc, argv, "s:")) != EOF)
		switch (c) {
		case 's':
			array_len = strtoul(optarg, 0, 16);
			sflag = 1;
			continue;
		default:
			/* error msg already printed */
			exit(1);
		}
	if (argc != optind + 1) {
		fprintf(stderr, "tiobjd chararray: name argument required\n");
		exit(1);
	}
	array_name = argv[optind];

	get_int_section_table();
	get_int_symbol_table();
	for (n = 0; n < nsymtab; n++) {
		sym = symtab[n];
		if (!sym)
			continue;
		if (sym->class != C_EXT)
			continue;
		if (sym->name[0] != '_')
			continue;
		if (!strcmp(sym->name + 1, array_name))
			goto found;
	}
	fprintf(stderr, "error: found no global symbol named %s\n", array_name);
	exit(1);

found:	if (!sym->section) {
		fprintf(stderr, "error: %s is not defined in a section\n",
			array_name);
		exit(1);
	}
	if (!sflag) {
		if (sym->type != 0x003C) {
			fprintf(stderr,
				"error: %s has type != array of u_char\n",
				array_name);
			exit(1);
		}
		if (!sym->aux) {
			fprintf(stderr, "error: %s has no Aux record\n",
				array_name);
			exit(1);
		}
		array_len = get_u16(sym->aux + 8);
	}
	dp = filemap + sym->section->data_offset + sym->value;
	printf("const unsigned char %s[%u] = {", array_name, array_len);
	for (n = 0; n < array_len; n++) {
		if (!(n & 15))
			putchar('\n');
		printf("0x%02X,", *dp++);
	}
	puts("\n};");
	exit(0);
}