* tools/build/.cvsignore, tools/build/ChangeLog,

tools/build/Makefile.am, tools/build/README, tools/build/binpatch.c,
	tools/build/cklength.c, tools/build/config.h.in,
	tools/build/configure.ac, tools/build/cvsignore-add.sh,
	tools/build/doxy-filter, tools/build/eolstrip.c,
	tools/build/install-if-change.in, tools/build/multigen,
	tools/build/packhex.c, tools/build/rtems-bin2c.c,
	tools/build/search-id.sh, tools/build/unhex.c, tools/cpu/.cvsignore,
	tools/cpu/ChangeLog, tools/cpu/Makefile.am, tools/cpu/configure.ac,
	tools/cpu/generic/.cvsignore, tools/cpu/generic/ChangeLog,
	tools/cpu/generic/Makefile.am, tools/cpu/generic/configure.ac,
	tools/cpu/generic/size_rtems.in, tools/cpu/nios2/.cvsignore,
	tools/cpu/nios2/ChangeLog, tools/cpu/nios2/Makefile.am,
	tools/cpu/nios2/README, tools/cpu/nios2/bridges.c,
	tools/cpu/nios2/bridges.h, tools/cpu/nios2/clocks.c,
	tools/cpu/nios2/clocks.h, tools/cpu/nios2/configure.ac,
	tools/cpu/nios2/devices.c, tools/cpu/nios2/devices.h,
	tools/cpu/nios2/linkcmds.c, tools/cpu/nios2/linkcmds.h,
	tools/cpu/nios2/memory.c, tools/cpu/nios2/memory.h,
	tools/cpu/nios2/nios2gen.c, tools/cpu/nios2/output.c,
	tools/cpu/nios2/output.h, tools/cpu/nios2/ptf.c,
	tools/cpu/nios2/ptf.h, tools/cpu/nios2/sample.ptf,
	tools/cpu/sh/.cvsignore, tools/cpu/sh/AUTHORS, tools/cpu/sh/COPYING,
	tools/cpu/sh/ChangeLog, tools/cpu/sh/Makefile.am, tools/cpu/sh/TODO,
	tools/cpu/sh/configure.ac, tools/cpu/sh/sci.c, tools/cpu/sh/sci.h,
	tools/cpu/sh/shgen.c: New files.
This commit is contained in:
Joel Sherrill
2011-05-17 20:39:40 +00:00
parent d305d75c7e
commit d751cecbb1
58 changed files with 7659 additions and 0 deletions

18
tools/build/.cvsignore Normal file
View File

@@ -0,0 +1,18 @@
aclocal.m4
autom4te*.cache
config.cache
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
depcomp
install-if-change
install-sh
Makefile
Makefile.in
missing
mkinstalldirs
stamp-h.in

209
tools/build/ChangeLog Normal file
View File

@@ -0,0 +1,209 @@
2011-02-02 Ralf Corsépius <ralf.corsepius@rtems.org>
* configure.ac: Require autoconf-2.68, automake-1.11.1.
2010-07-30 Ralf Corsépius <ralf.corsepius@rtems.org>
* rtems-bin2c.c: Fix memory leak in '.c' suffix strip.
Also strip '.h' suffix.
2010-07-30 Ralf Corsépius <ralf.corsepius@rtems.org>
* rtems-bin2c.c: Make -v (verbose) working.
2010-07-30 Ralf Corsépius <ralf.corsepius@rtems.org>
* configure.ac: Check for libgen.h, basename.
* rtems-bin2c.c: Use basename(3) instead of strrchr cascade.
Introduce ifbasename. Use ifbasename in generated files.
2010-07-29 Ralf Corsépius <ralf.corsepius@rtems.org>
* rtems-bin2c.c: Add -C and -H options.
2010-03-12 Joel Sherrill <joel.sherrill@oarcorp.com>
* eolstrip.c: Readdress use of ctype methods per recommendation from
D.J. Delorie on the newlib mailing list. We should pass an unsigned
char into these methods.
2007-09-18 Joel Sherrill <joel.sherrill@OARcorp.com>
* Makefile.am: Rename bin2c to rtems-bin2c.
2007-09-10 Joel Sherrill <joel.sherrill@OARcorp.com>
* bin2c.c: Updated license after author changed it.
2007-09-07 Joel Sherrill <joel.sherrill@OARcorp.com>
* bin2c.c: Update comments.
2007-09-04 Joel Sherrill <joel.sherrill@oarcorp.com>
* bin2c.c: Significant improvements -- add multiple options, generate
both C and H files, do not always generate static. fix indentation,
add comments.
2007-09-04 Joel Sherrill <joel.sherrill@oarcorp.com>
* bin2c.c: New file.
http://www.wxwidgets.org/wiki/index.php/Embedding_PNG_Images-Bin2c_In_C
2007-09-04 Joel Sherrill <joel.sherrill@oarcorp.com>
* Makefile.am: Add bin2c so we can have a more reliable way to convert
binary files to objects. If they are in C, we can use the correct CPU
CFLAGS and they will link easier.
2006-12-02 Ralf Corsépius <ralf.corsepius@rtems.org>
* configure.ac: New BUG-REPORT address.
2006-10-17 Ralf Corsépius <ralf.corsepius@rtems.org>
* configure.ac: Require autoconf-2.60. Require automake-1.10.
2006-07-13 Ralf Corsepius <ralf.corsepius@rtems.org>
* doxy-filter: New.
* Makefile.am: Add doxy-filter.
2006-07-11 Ralf Corsepius <ralf.corsepius@rtems.org>
* ampolish3.in: Remove.
* Makefile.am: Remove ampolish3.
* configure.ac: Remove ampolish3, perl.
2006-01-14 Ralf Corsepius <ralf.corsepius@rtems.org>
* ampolish3.in: Check Makefile.am for SUBDIRS.
Add all-am: for PREINSTALL_FILES.
2006-01-12 Ralf Corsepius <ralf.corsepius@rtems.org>
* ampolish3.in: Add all: for PREINSTALL_FILES.
Add all-local for TMPINSTALL_FILES.
Misc bug fixes.
2006-01-12 Ralf Corsepius <ralf.corsepius@rtems.org>
* ampolish3.in: Check if Makefile.am already contains CLEANFILES or
DISTCLEANFILES.
2006-01-10 Ralf Corsepius <ralf.corsepius@rtems.org>
* ampolish3.in: Update.
2005-10-25 Ralf Corsepius <ralf.corsepius@rtems.org>
* ampolish3.in: Sync with private bleeding-edge .
2005-10-24 Ralf Corsepius <ralf.corsepius@rtems.org>
* ampolish3.in: Use @PERL@, partial update from local sources.
2005-10-24 Ralf Corsepius <ralf.corsepius@rtems.org>
* configure.ac: Add ampolish3.
* Makefile.am: Add ampolish3.
* ampolish3.in: New.
2004-09-24 Ralf Corsepius <ralf.corsepius@rtems.org>
* configure.ac: Require automake > 1.9.
2004-02-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Add EXTRA_DIST = search-id.sh multigen
cvsignore-add.sh.
2003-12-12 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Require automake >= 1.8, autoconf >= 2.59.
2003-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Use rtems-bugs@rtems.com as bug report email address.
2003-03-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Add AC_CHECK_HEADERS(getopt.h) to work around a bug
in autoconf-2.57.
2003-03-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Remove AC_CONFIG_AUX_DIR.
2003-03-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Add AC_CHECK_HEADERS.
2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: AC_PREREQ(2.57).
2002-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Reformat.
Add autom4te*cache.
Remove autom4te.cache.
2002-10-02 Chris Johns <cjohns@cybertec.com.au>
* cvsignore-add.sh: Script to append a specific file to all
.cvsignore files if the files exists is a specific directory.
2002-05-01 Joel Sherrill <joel@OARcorp.com>
* lock-directory.in, unlock-directory.in: Removed.
* Makefile.am, README, .cvsignore: Updated to reflect above.
2002-04-01 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Remove AC_EXEEXT (obsolete).
2002-03-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac:
AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
AM_INIT_AUTOMAKE([no-define foreign 1.6]).
* Makefile.am: Remove AUTOMAKE_OPTIONS.
2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Add autom4te.cache for autoconf > 2.52.
* configure.in: Remove.
* configure.ac: New file, generated from configure.in by autoupdate.
2001-01-24 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* config.h.in: Automatically generated. Remove from CVS.
2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
2000-10-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Switch to GNU-canonicalized autoconf macros.
2000-08-10 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* multigen: Fix BARE_CPU_CFLAGS.
2000-08-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* multigen: Fix usage.
2000-08-10 Joel Sherrill <joel@OARcorp.com>
* ChangeLog: New file.

26
tools/build/Makefile.am Normal file
View File

@@ -0,0 +1,26 @@
##
## $Id$
##
ACLOCAL_AMFLAGS = -I ../../aclocal
bin_PROGRAMS = cklength eolstrip packhex unhex rtems-bin2c
noinst_PROGRAMS = binpatch
cklength_SOURCES = cklength.c
eolstrip_SOURCES = eolstrip.c
packhex_SOURCES = packhex.c
unhex_SOURCES = unhex.c
binpatch_SOURCES = binpatch.c
rtems_bin2c_SOURCES = rtems-bin2c.c
bin_SCRIPTS = install-if-change
noinst_SCRIPTS = search-id.sh multigen cvsignore-add.sh
EXTRA_DIST = search-id.sh multigen cvsignore-add.sh
noinst_SCRIPTS += doxy-filter
EXTRA_DIST += doxy-filter
include $(top_srcdir)/../../automake/host.am

10
tools/build/README Normal file
View File

@@ -0,0 +1,10 @@
#
# $Id$
#
Misc. support tools for RTEMS workspaces.
install-if-change
Smart install script that also can append suffixes as it
installs (suffixes used for debug and profile variants).
Requires bash or ksh.

156
tools/build/binpatch.c Normal file
View File

@@ -0,0 +1,156 @@
/*
* $Id$
*/
#include <stdio.h>
#include <stdlib.h>
/*
* This function will patch binary file
*/
static char buf[512];
static void
usage(void)
{
printf("usage: binpatch [-h] <ofile> <ifile> <reloc> <off> <byte0> "
"[<byte1> [<byte2> [<byte3>]]]\n");
printf("this function patches binary file at specified offset with\n");
printf("up to 4 bytes provided on command line \n");
printf("-h - prints this message\n\n");
printf("<ofile> - output file\n");
printf("<ifile> - input ifile\n");
printf("<reloc> - relocation address of image\n");
printf("<off> - offset of patch, offset in file is at off - reloc\n");
printf("<byte0> - byte 0 of patch\n");
printf("<byte1> - byte 1 of patch\n");
printf("<byte2> - byte 1 of patch\n");
printf("<byte3> - byte 1 of patch\n");
return;
}
int
main(int argc, char **argv)
{
int c;
FILE *ofp, *ifp;
char patch[4], *end;
int patchLen, tmp, i, off, cnt, patched, len, reloc;
/* parse command line options */
while ((c = getopt(argc, argv, "h")) >= 0)
{
switch (c)
{
case 'h':
usage();
return 0;
default:
usage();
return 1;
}
}
if(argc < 6)
{
usage();
return 1;
}
/* Let us get offset in file */
reloc = strtol(argv[3], &end, 0);
if(end == argv[3] || off < 0)
{
fprintf(stderr, "bad reloc value %s\n", argv[3]);
return 1;
}
off = strtol(argv[4], &end, 0);
if(end == argv[4] || off < 0 || off < reloc)
{
fprintf(stderr, "bad offset value %s\n", argv[4]);
return 1;
}
off -= reloc;
/* Let us get patch */
patchLen = argc - 5;
for(i=0; i<patchLen; i++)
{
tmp = strtol(argv[5+i], &end, 0);
if(end == argv[4+i] || tmp < 0 || tmp > 0xff)
{
fprintf(stderr, "bad byte value %s\n", argv[5+i]);
return 1;
}
patch[i] = tmp;
}
ifp = fopen(argv[2], "r");
if(ifp == NULL)
{
fprintf(stderr, "unable to open file %s\n", argv[2]);
return 1;
}
ofp = fopen(argv[1], "w");
if(ofp == NULL)
{
fprintf(stderr, "unable to open file %s\n", argv[1]);
return 1;
}
cnt = 0;
patched = 0;
for(;;)
{
len = fread(buf, 1, sizeof(buf), ifp);
if(len == 0)
{
break;
}
if(cnt <= off && (cnt + len) > off)
{
/* Perform patch */
for(i=0; i<patchLen && (off+i)<(cnt+len); i++)
{
buf[off-cnt+i] = patch[i];
}
patched = 1;
}
else if(cnt > off && cnt < (off + patchLen))
{
/* Perform patch */
for(i=cnt-off; i<patchLen; i++)
{
buf[off-cnt+i] = patch[i];
}
patched = 1;
}
fwrite(buf, 1, len, ofp);
cnt += len;
}
fclose(ifp);
fclose(ofp);
if(!patched)
{
fprintf(stderr, "warning: offset is beyond input file length\n");
fprintf(stderr, " no patch is performed\n");
}
return 0;
}

377
tools/build/cklength.c Normal file
View File

@@ -0,0 +1,377 @@
/*
* cklength - check the length of lines in a file
*
* This program check to see if the files passed to it on the command line
* contain a line which exceeds the maximum allowable length. The default
* maximum line length is 80.
*
* usage: cklength [ -v ] [ arg ... ] files...
* -l length -- maximum line length
* -v -- verbose
*
* $Id$
*/
#define GETOPTARGS "l:nNv"
char *USAGE = "\
usage: cklength [ -v ] [ arg ... ] files... \n\
-l length -- maximum line length\n\
-n -- report line numbers for offending lines\n\
-N -- report line numbers and length for offending lines\n\
-v -- verbose\n\
\n\
Print the name of files which have at least 1 line which exceeds the\n\
maximum line length. The default maximum line length is 80.\n\
";
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <memory.h>
#include <stdarg.h>
#include <errno.h>
#include "config.h"
#ifndef VMS
#ifndef HAVE_STRERROR
extern int sys_nerr;
extern char *sys_errlist[];
#define strerror( _err ) \
((_err) < sys_nerr) ? sys_errlist [(_err)] : "unknown error"
#else /* HAVE_STRERROR */
char *strerror ();
#endif
#else /* VMS */
char *strerror (int,...);
#endif
#define BUFFER_SIZE 512
#define SUCCESS 0
#define FAILURE -1
#define Failed(x) (((int) (x)) == FAILURE)
#define TRUE 1
#define FALSE 0
#define STREQ(a,b) (strcmp(a,b) == 0)
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
/*
* Definitions for unsigned "ints"; especially for use in data structures
* that will be shared among (potentially) different cpu's (we punt on
* byte ordering problems tho)
*/
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
/*
* vars controlled by command line options
*/
int verbose = FALSE; /* be verbose */
int report_line_numbers = FALSE; /* report line numbers of offenders */
int report_line_length = FALSE; /* report line length of offenders */
int line_length = 80; /* maximum allowable line length */
extern char *optarg; /* getopt(3) control vars */
extern int optind, opterr;
char *progname; /* for error() */
int process(char *arg);
void error(int errn, ...);
long getparm(char *s, long min, long max, char *msg);
#define ERR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
#define ERR_FATAL (ERR_ERRNO / 2) /* fatal error ; no return */
#define ERR_ABORT (ERR_ERRNO / 4) /* fatal error ; abort */
#define ERR_MASK (ERR_ERRNO | ERR_FATAL | ERR_ABORT) /* all */
#define stol(p) strtol(p, (char **) NULL, 0)
int Open(), Read(), Write();
int main(
int argc,
char **argv
)
{
register int c;
int showusage = FALSE; /* usage error? */
int rc = 0;
/*
* figure out invocation leaf-name
*/
if ((progname = strrchr(argv[0], '/')) == (char *) NULL)
progname = argv[0];
else
progname++;
argv[0] = progname; /* for getopt err reporting */
/*
* Check options and arguments.
*/
opterr = 0; /* we'll report all errors */
while ((c = getopt(argc, argv, GETOPTARGS)) != EOF)
switch (c)
{
case 'l': /* line length */
line_length = atoi( optarg );
if ( line_length < 0 || line_length > BUFFER_SIZE )
error(ERR_FATAL, "(%d) is illegal line length\n",line_length);
break;
case 'n': /* toggle report_line_numbers */
report_line_numbers = ! report_line_numbers;
break;
case 'N': /* toggle both reports */
report_line_numbers = ! report_line_numbers;
report_line_length = ! report_line_length;
break;
case 'v': /* toggle verbose */
verbose = ! verbose;
break;
case '?':
showusage = TRUE;
}
if (showusage)
{
(void) fprintf(stderr, "%s", USAGE);
exit(1);
}
/*
* traverse and process the arguments
*/
for ( ; argv[optind]; optind++)
if (Failed(process(argv[optind])))
rc = FAILURE;
return rc;
}
/*
* process(arg)
*/
int
process(char *arg)
{
FILE *in;
char *bptr;
char buffer[ BUFFER_SIZE ];
int line_number;
int length;
int count;
int rc = SUCCESS; /* succeed by default */
in = fopen( arg, "r" );
if (!in)
error( ERR_ERRNO | ERR_FATAL, "Unable to open file (%s)\n", arg );
count = 0;
for ( line_number=1 ; ; line_number++ ) {
bptr = fgets( buffer, BUFFER_SIZE, in );
if (!bptr)
break;
/*
* Don't count the carriage return.
*/
length = strlen( buffer ) - 1;
if ( length <= line_length )
continue;
if ( count == 0 ) {
fprintf( stderr, "%s\n", arg );
if ( !report_line_numbers )
break;
}
if ( verbose )
fprintf( stderr, "TOO LONG:%d: %s\n", line_number, buffer );
if ( report_line_numbers ) {
if ( report_line_length )
fprintf( stderr, "%d: %d\n" , line_number, length );
else
fprintf( stderr, "%d\n" , line_number );
}
count++;
}
fclose( in );
return rc;
}
/*
* error(errn, arglist)
* report an error to stderr using printf(3) conventions.
* Any output is preceded by '<progname>: '
*
* Uses ERR_FATAL bit to request exit(errn)
* ERR_ABORT to request abort()
* ERR_ERRNO to indicate use of errno instead of argument.
*
* If resulting 'errn' is non-zero, it is assumed to be an 'errno' and its
* associated error message is appended to the output.
*/
/*VARARGS*/
void
error(int error_flag, ...)
{
va_list arglist;
register char *format;
int local_errno;
extern int errno;
(void) fflush(stdout); /* in case stdout/stderr same */
local_errno = error_flag & ~ERR_MASK;
if (error_flag & ERR_ERRNO) /* use errno? */
local_errno = errno;
va_start(arglist, error_flag);
format = va_arg(arglist, char *);
(void) fprintf(stderr, "%s: ", progname);
(void) vfprintf(stderr, format, arglist);
va_end(arglist);
if (local_errno)
(void) fprintf(stderr, " (%s)\n", strerror(local_errno));
(void) fflush(stderr);
if (error_flag & (ERR_FATAL | ERR_ABORT))
{
if (error_flag & ERR_FATAL)
{
error(0, "fatal error, exiting");
exit(local_errno ? local_errno : 1);
}
else
{
error(0, "fatal error, aborting");
abort();
}
}
}
long
getparm(char *s,
long min,
long max,
char *msg)
{
long val;
if ( ! strchr("0123456789-", *s))
{
error(ERR_FATAL, "'%s' is not a number", s);
return min;
}
val = strtol(s, (char **) NULL, 0);
if ((val < min) || (val > max))
{
if (min == max)
error(ERR_FATAL, "%s can only be %ld", s, min);
else
error(ERR_FATAL, "%s must be between %ld and %ld", msg, min, max);
}
return val;
}
/*
* Open()
* Perform open(2), returning the file descriptor. Prints
* error message if open fails.
*/
int
Open(char *file,
int oflag,
int mode)
{
int O_fd;
if (Failed(O_fd = open(file, oflag, mode)))
error(
ERR_ERRNO | ERR_FATAL,
"open('%s', 0x%x, 0%o) failed", file, oflag, mode
);
return O_fd;
}
/*
* Read()
* Perform read(2); prints error message if fails.
*/
int
Read(int file,
char *buffer,
unsigned int count)
{
int nbytes;
if (Failed(nbytes = read(file, buffer, count)))
error(
ERR_ERRNO | ERR_FATAL,
"read(%d, 0x%x, %d) failed", file, buffer, count
);
return nbytes;
}
/*
* Write()
* Perform write(2); prints error message if fails.
*/
int
Write(int file,
char *buffer,
unsigned int count)
{
int nbytes;
if (Failed(nbytes = write(file, buffer, count)))
error(
ERR_ERRNO | ERR_FATAL,
"write(%d, 0x%x, %d) failed", file, buffer, count
);
return nbytes;
}

55
tools/build/config.h.in Normal file
View File

@@ -0,0 +1,55 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

26
tools/build/configure.ac Normal file
View File

@@ -0,0 +1,26 @@
#
# $Id$
#
AC_PREREQ([2.68])
AC_INIT([rtems-tools-build],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla])
AC_CONFIG_SRCDIR([install-if-change.in])
RTEMS_TOP(../..)
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([no-define foreign 1.11.1])
AM_MAINTAINER_MODE
AC_PROG_CC
AC_CHECK_HEADERS([getopt.h libgen.h])
AC_CHECK_FUNCS(strerror strtol basename)
RTEMS_PATH_KSH
AC_CONFIG_HEADERS([config.h])
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([install-if-change],[chmod +x install-if-change])
AC_OUTPUT

25
tools/build/cvsignore-add.sh Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/sh
#
# Find a file in the directory tree and create or add to a .cvsignore
# file that file name so it is ignored.
#
# Copyright 2001 Cybertec Pty Limited
# All rights reserved.
#
# $Id$
#
#
# We need one parameter, the file to add.
#
if [ $# -eq 0 ]; then
echo "Usage: $0 file, where file is the one to be added."
exit 1
fi
for f in `find . -name $1`;
do
echo "`dirname $f`/.cvsignore"
echo "$1" >> `dirname $f`/.cvsignore
done

21
tools/build/doxy-filter Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/sh
# doxygen input filter
# $Id$
# usage: doxy-filter <input-file-name>
# Reads <input-file> and writes to stdout.
file=$1
# Does file contain a doxygen @file directive?
if ! grep -q '@file' $file >/dev/null ; then
# No, add one
echo "/** @file $file */"
cat $file
else
# Yes, adjust path to work around doxygen not being able to
# distinguish file names properly
exec sed -e "s,@file.*$,@file $file," $file
fi

366
tools/build/eolstrip.c Normal file
View File

@@ -0,0 +1,366 @@
/*
* eolstrip - strip white space from end of lines
*
* This program strips the white space from the end of every line in the
* specified program.
*
* usage: eolstrip [ -v ] [ arg ... ] files...
* -v -- verbose
*
* $Id$
*/
#define GETOPTARGS "vt"
char *USAGE = "\
usage: cklength [ -v ] [ arg ... ] files... \n\
-v -- verbose\n\
-t -- test only .. DO NOT OVERWRITE FILE!!!\n\
\n\
Strip the white space from the end of every line on the list of files.\n\
";
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <memory.h>
#include <stdarg.h>
#include <errno.h>
#include "config.h"
#ifndef VMS
#ifndef HAVE_STRERROR
extern int sys_nerr;
extern char *sys_errlist[];
#define strerror( _err ) \
((_err) < sys_nerr) ? sys_errlist [(_err)] : "unknown error"
#else /* HAVE_STRERROR */
char *strerror ();
#endif
#else /* VMS */
char *strerror (int,...);
#endif
#define BUFFER_SIZE 2048
#define MAX_PATH 2048
#define SUCCESS 0
#define FAILURE -1
#define Failed(x) (((int) (x)) == FAILURE)
#define TRUE 1
#define FALSE 0
#define STREQ(a,b) (strcmp(a,b) == 0)
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
/*
* Definitions for unsigned "ints"; especially for use in data structures
* that will be shared among (potentially) different cpu's (we punt on
* byte ordering problems tho)
*/
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
/*
* vars controlled by command line options
*/
int verbose = FALSE; /* be verbose */
int test_only = FALSE; /* test only */
extern char *optarg; /* getopt(3) control vars */
extern int optind, opterr;
char *progname; /* for error() */
int process(char *arg);
void error(int errn, ...);
long getparm(char *s, long min, long max, char *msg);
#define ERR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
#define ERR_FATAL (ERR_ERRNO / 2) /* fatal error ; no return */
#define ERR_ABORT (ERR_ERRNO / 4) /* fatal error ; abort */
#define ERR_MASK (ERR_ERRNO | ERR_FATAL | ERR_ABORT) /* all */
#define stol(p) strtol(p, (char **) NULL, 0)
int Open(), Read(), Write();
int main(
int argc,
char **argv
)
{
register int c;
int showusage = FALSE; /* usage error? */
int rc = 0;
/*
* figure out invocation leaf-name
*/
if ((progname = strrchr(argv[0], '/')) == (char *) NULL)
progname = argv[0];
else
progname++;
argv[0] = progname; /* for getopt err reporting */
/*
* Check options and arguments.
*/
opterr = 0; /* we'll report all errors */
while ((c = getopt(argc, argv, GETOPTARGS)) != EOF)
switch (c)
{
case 't': /* toggle test only mode */
test_only = ! test_only;
break;
case 'v': /* toggle verbose */
verbose = ! verbose;
break;
case '?':
showusage = TRUE;
}
if (showusage)
{
(void) fprintf(stderr, "%s", USAGE);
exit(1);
}
/*
* traverse and process the arguments
*/
for ( ; argv[optind]; optind++)
if (Failed(process(argv[optind])))
rc = FAILURE;
return rc;
}
/*
* process(arg)
*/
int
process(char *arg)
{
FILE *in;
FILE *out = (FILE *) 0;
char outname[ MAX_PATH ];
char *bptr;
char buffer[ BUFFER_SIZE ];
int length;
int line_number;
int rc = SUCCESS; /* succeed by default */
in = fopen( arg, "r" );
if (!in)
error( ERR_ERRNO | ERR_FATAL, "Unable to open file (%s)\n", arg );
if ( !test_only ) {
sprintf( outname, "%s.eoltmp", arg );
out = fopen( outname, "w" );
if (!out)
error( ERR_ERRNO | ERR_FATAL, "Unable to open file (%s)\n", arg );
}
if ( verbose )
fprintf( stderr, "Processing %s\n", arg );
for ( line_number=1 ; ; line_number++ ) {
bptr = fgets( buffer, BUFFER_SIZE, in );
if (!bptr)
break;
/*
* Don't count the carriage return.
*/
length = strlen( buffer ) - 1;
if ( buffer[ length ] != '\n' )
error(ERR_ERRNO|ERR_FATAL, "Line %d too long in %s\n", line_number, arg);
while ( isspace( (unsigned char) buffer[ length ] ) )
buffer[ length-- ] = '\0';
if ( test_only ) {
fprintf( stderr, "%s\n", arg );
break;
}
fprintf( out, "%s\n", buffer );
}
fclose( in );
if ( !test_only ) {
fclose( out );
rename( outname, arg );
}
return rc;
}
/*
* error(errn, arglist)
* report an error to stderr using printf(3) conventions.
* Any output is preceded by '<progname>: '
*
* Uses ERR_FATAL bit to request exit(errn)
* ERR_ABORT to request abort()
* ERR_ERRNO to indicate use of errno instead of argument.
*
* If resulting 'errn' is non-zero, it is assumed to be an 'errno' and its
* associated error message is appended to the output.
*/
/*VARARGS*/
void
error(int error_flag, ...)
{
va_list arglist;
register char *format;
int local_errno;
extern int errno;
(void) fflush(stdout); /* in case stdout/stderr same */
local_errno = error_flag & ~ERR_MASK;
if (error_flag & ERR_ERRNO) /* use errno? */
local_errno = errno;
va_start(arglist, error_flag);
format = va_arg(arglist, char *);
(void) fprintf(stderr, "%s: ", progname);
(void) vfprintf(stderr, format, arglist);
va_end(arglist);
if (local_errno)
(void) fprintf(stderr, " (%s)\n", strerror(local_errno));
else
(void) fprintf(stderr, "\n");
(void) fflush(stderr);
if (error_flag & (ERR_FATAL | ERR_ABORT))
{
if (error_flag & ERR_FATAL)
{
error(0, "fatal error, exiting");
exit(local_errno ? local_errno : 1);
}
else
{
error(0, "fatal error, aborting");
abort();
}
}
}
long
getparm(char *s,
long min,
long max,
char *msg)
{
long val;
if ( ! strchr("0123456789-", *s))
{
error(ERR_FATAL, "'%s' is not a number", s);
return min;
}
val = strtol(s, (char **) NULL, 0);
if ((val < min) || (val > max))
{
if (min == max)
error(ERR_FATAL, "%s can only be %ld", s, min);
else
error(ERR_FATAL, "%s must be between %ld and %ld", msg, min, max);
}
return val;
}
/*
* Open()
* Perform open(2), returning the file descriptor. Prints
* error message if open fails.
*/
int
Open(char *file,
int oflag,
int mode)
{
int O_fd;
if (Failed(O_fd = open(file, oflag, mode)))
error(
ERR_ERRNO | ERR_FATAL,
"open('%s', 0x%x, 0%o) failed", file, oflag, mode
);
return O_fd;
}
/*
* Read()
* Perform read(2); prints error message if fails.
*/
int
Read(int file,
char *buffer,
unsigned int count)
{
int nbytes;
if (Failed(nbytes = read(file, buffer, count)))
error(
ERR_ERRNO | ERR_FATAL,
"read(%d, 0x%x, %d) failed", file, buffer, count
);
return nbytes;
}
/*
* Write()
* Perform write(2); prints error message if fails.
*/
int
Write(int file,
char *buffer,
unsigned int count)
{
int nbytes;
if (Failed(nbytes = write(file, buffer, count)))
error(
ERR_ERRNO | ERR_FATAL,
"write(%d, 0x%x, %d) failed", file, buffer, count
);
return nbytes;
}

View File

@@ -0,0 +1,142 @@
#!@KSH@ -p
#
# Either bash or ksh will be ok for this; requires (( )) arithmetic
# (-p above just says to not parse $ENV file; makes it faster for
# those of us who set $ENV)
#
# install files if they have changed by running 'cmp', then 'install'
# as necessary.
#
# Optionally, can append a suffix before last existing suffix (if any)
#
# NOTE
# We avoid using typical install(1M) programs since they have
# large variability across systems and we also need to support ou
# -V option.
# So we just copy and chmod by hand.
#
# $Id$
#
progname=`basename $0`
#progname=${0##*/} # fast basename hack for ksh, bash
USAGE=\
"usage: $progname [ -vmV ] file [ file ... ] dest-directory-or-file
-v -- verbose
-V suffix -- suffix to append to targets (before any . suffix)
eg: -V _g would change 'foo' to 'foo_g' and
'libfoo.a' to 'libfoo_g.a'
-m mode -- mode for new file(s)"
fatal() {
if [ "$1" ]
then
echo $* >&2
fi
echo "$USAGE" 1>&2
exit 1
}
#
# process the options
#
verbose=""
suffix=""
mode=""
while getopts vm:V: OPT
do
case "$OPT" in
v)
verbose="yes";;
V)
eval suffix=$OPTARG;;
m)
mode="$OPTARG";;
*)
fatal
esac
done
shiftcount=`expr $OPTIND - 1`
shift $shiftcount
args=$*
#
# Separate source file(s) from dest directory or file
#
files=""
dest=""
for d in $args
do
files="$files $dest"
dest=$d
done
if [ ! "$files" ] || [ ! "$dest" ]
then
fatal "missing files or invalid destination"
fi
#
# Process the arguments
#
targets=""
for f in $files
do
# leaf=`basename $f`
leaf=${f##*/} # fast basename hack for ksh, bash
target=$dest
if [ -d $dest ]
then
# if we were given a suffix, then add it as appropriate
if [ "$suffix" ]
then
case $f in
*.*)
# leaf=`echo $leaf |
# /bin/sed "s/\([~\.]*\)\.\(.*\)$/\1$suffix.\2/"`
# ksh,bash hack for above sed script
leaf=${leaf%%.*}$suffix.${leaf#*.}
[ "$verbose" = "yes" ] &&
echo "$progname: $f will be installed as $leaf"
;;
*)
leaf=$leaf$suffix;;
esac
fi
target=$target/$leaf
fi
[ ! -r $f ] && fatal "can not read $f"
if cmp -s $f $target
then
[ "$verbose" = "yes" ] && echo "'$f' not newer than '$target'"
else
[ "$verbose" = "yes" ] && echo "rm -f $target"
rm -f $target
echo "cp -p $f $target"
cp -p $f $target || exit 1
targets="$targets $target" # keep list for chmod below
fi
done
if [ "$mode" -a "$targets" ]
then
[ "$verbose" = "yes" ] && echo "chmod $mode $targets"
chmod $mode $targets
fi
exit 0
# Local Variables: ***
# mode:ksh ***
# End: ***

173
tools/build/multigen Executable file
View File

@@ -0,0 +1,173 @@
#!/bin/sh
# $Id$
version=0.1
verbose=0
target=
custom=0
config=0
usage()
{
program=`basename $0`
cat << EOF
$program generates RTEMS custom/*.cfgs and config-files for gcc multilib
variants a target's gcc supports
Usage: $program [options]
Options:
--target=STRING target
--custom generate make/custom/*.cfg files
--config generate config scripts
--rtems=DIR use DIR as location of RTEMS source tree
-v, --verbose verbose
-h, --help Print this usage
--version Print version and exit
Examples:
$program --config --target=sh-rtems --rtems=/usr/src/rtems-4.5.0
Generates config scripts for all possible bare BSPs from all
valid multilib variants sh-rtems-gcc supports
$program --custom --target=sh-rtems --rtems=/usr/src/rtems-4.5.0
Generates /usr/src/rtems-4.5.0/make/custom/*.cfg files
for all possible bare BSPs from the multilib variants
sh-rtems-gcc supports
Written by Ralf Corsepius <corsepiu@faw.uni-ulm.de>
EOF
}
while test $# -gt 0; do
case "$1" in
--rtems=*)
rtems_srcdir=`echo "$1" | sed -e 's%--rtems=\(.*\)%\1%g'`
;;
--target=*)
target=`echo "$1" | sed -e 's%--target=\(.*\)%\1%g'`
;;
-v|--verbose)
verbose=1
;;
--custom)
custom=1
;;
--config)
config=1
;;
--version)
echo `basename $0` version $version
exit 0
;;
-h|--help)
usage
exit 1
;;
*)
echo "unknown option $1"
usage
exit 1
;;
esac
shift
done
if test $# -gt 0; then
echo "Invalid number of arguments"
exit 1
fi
if test x$target = x; then
echo "Missing required option:"
echo " --target"
exit 1
fi
if test x$rtems_srcdir = x; then
echo "Missing required option:"
echo " --rtems"
exit 1
fi
if test $config -eq 0 && test $custom -eq 0; then
echo "Missing required option:"
echo " --config"
echo " --custom"
echo " (At least one of these is required)"
exit 1
fi
if test ! -r $rtems_srcdir/VERSION; then
echo "Can't find rtems"
echo "Check value passed to --rtems=<DIR>"
exit 1
fi
if test x$target != x ;then
target_prefix=$target-
fi
# Check for CC
saved_IFS=$IFS; IFS=":"
for i in $PATH; do
if test -f $i/${target_prefix}gcc; then
CC=$i/${target_prefix}gcc
break
fi
done
IFS=$saved_IFS
if test x$CC = x; then
echo "No valid gcc found"
exit 1
fi
test $verbose -gt 0 && echo "Using $CC"
for i in `${CC} --print-multi-lib 2>/dev/null`; do
dir=`echo $i | sed -e 's/;.*$//'`
case $dir in
.) f=$target
flags=""
;;
*) f=`echo $target-$dir | sed -e 's%\/%-%g'`
flags=`echo $i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`
;;
esac
if test $config -gt 0; then
cfg="rtems-config.$f"
test $verbose -gt 0 && echo "Generating: $cfg"
cat << EOF > $cfg
#!/bin/sh
${rtems_srcdir}/configure --target=$target \\
'--enable-bare-cpu-cflags=$flags' \\
--enable-rtemsbsp="bare" \\
--enable-bare-cpu-model=NONE \\
--disable-networking \\
--disable-tests \\
--enable-maintainer-mode
EOF
chmod +x $cfg
fi
if test $custom -gt 0; then
cfg=${rtems_srcdir}/make/custom/bare-$f.cfg
test $verbose -gt 0 && echo "Generating: $cfg"
cat << EOF > $cfg
# Config file for the bare-$f BSP
BARE_CPU_CFLAGS=$flags
BARE_CPU_MODEL=NONE
include \$(RTEMS_ROOT)/make/custom/bare.cfg
EOF
fi
done
exit 0

565
tools/build/packhex.c Normal file
View File

@@ -0,0 +1,565 @@
/***** P A C K H E X . C ************************************************
*
* Packhex is a hex-file compaction utility. It attempts to concatenate
* hex records to produce more size-efficient packaging.
*
* Limitations: Input files must be correctly formatted. This utility
* is not robust enough to detect hex-record formatting
* errors.
*
* Published: May 1993 Embedded Systems Programming magazine
* "Creating Faster Hex Files"
*
* URL: ESP magazine: http://www.embedded.com
* Source Code: ftp://ftp.mfi.com/pub/espmag/1993/pakhex.zip
*
* Author: Mark Gringrich
*
* Compiler: Microsoft C 6.0
* cl /F 1000 packhex.c
*
*
* $Id$
*
**************************************************************************/
/* #define SMALLER_RECORDS */
#ifdef SMALLER_RECORDS
#define MAX_LEN_S1_RECS 128
#define MAX_LEN_S2_RECS 128
#define MAX_LEN_S3_RECS 128
#else
#define MAX_LEN_S1_RECS 252
#define MAX_LEN_S2_RECS 251
#define MAX_LEN_S3_RECS 250
#endif
/*--------------------------------- includes ---------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#ifndef VMS
#ifndef HAVE_STRERROR
extern int sys_nerr;
extern char *sys_errlist[];
#define strerror( _err ) \
((_err) < sys_nerr) ? sys_errlist [(_err)] : "unknown error"
#else /* HAVE_STRERROR */
char *strerror ();
#endif
#else /* VMS */
char *strerror (int,...);
#endif
#if defined(__unix__) && !defined(EXIT_FAILURE)
#define EXIT_FAILURE -1
#define EXIT_SUCCESS 0
#endif
/*--------------------------------- defines ----------------------------------*/
#define YES 1
#define MAX_LINE_SIZE 600
#define EOS '\0'
/*---------------------------------- macros ----------------------------------*/
/* Convert ASCII hexadecimal digit to value. */
#define HEX_DIGIT( C ) ( ( ( ( C ) > '9' ) ? ( C ) + 25 : ( C ) ) & 0xF )
/*--------------------------------- typedefs ---------------------------------*/
typedef unsigned char Boolean;
typedef unsigned char Uchar;
typedef unsigned int Uint;
typedef unsigned long Ulong;
typedef struct /* Functions and constant returning Hex-record vital stats. */
{
Boolean ( *is_data_record )( char * );
Ulong ( *get_address )( char * );
Uint ( *get_data_count )( char * );
const Uint max_data_count;
char *( *get_data_start )( char * );
void ( *put_data_record )( Uint, Ulong, char * );
} Rec_vitals;
/*--------------------------- function prototypes ----------------------------*/
Rec_vitals * identify_first_data_record( char *, int );
Ulong get_ndigit_hex( char *, int );
/*----------------------------- Intel Hex format -----------------------------*/
/*
* Intel Hex data-record layout
*
* :aabbbbccd...dee
*
* : - header character
* aa - record data byte count, a 2-digit hex value
* bbbb - record address, a 4-digit hex value
* cc - record type, a 2-digit hex value:
* "00" is a data record
* "01" is an end-of-data record
* "02" is an extended-address record
* "03" is a start record
* d...d - data (always an even number of chars)
* ee - record checksum, a 2-digit hex value
* checksum = 2's complement
* [ (sum of bytes: aabbbbccd...d) modulo 256 ]
*/
Boolean is_intel_data_rec( char * rec_str )
{
return( ( rec_str[ 0 ] == ':' ) && ( rec_str[ 8 ] == '0' ) );
}
Uint get_intel_rec_data_count( char * rec_str )
{
return( ( Uint ) get_ndigit_hex( rec_str + 1, 2 ) );
}
Ulong get_intel_rec_address( char * rec_str )
{
return( get_ndigit_hex( rec_str + 3, 4 ) );
}
char * get_intel_rec_data_start( char * rec_str )
{
return( rec_str + 9 );
}
void put_intel_data_rec( Uint count, Ulong address, char * data_str )
{
char *ptr;
Uint sum = count + ( address >> 8 & 0xff ) + ( address & 0xff );
for ( ptr = data_str ; *ptr != EOS ; ptr += 2 )
sum += ( Uint ) get_ndigit_hex( ptr, 2 );
printf(
":%02X%04lX00%s%02X\n", count, address, data_str, (~sum + 1) & 0xff
);
}
Rec_vitals intel_hex =
{
is_intel_data_rec,
get_intel_rec_address,
get_intel_rec_data_count,
255, /* Maximum data bytes in a record. */
get_intel_rec_data_start,
put_intel_data_rec
};
/*------------------------- Motorola S1-record format ------------------------*/
/*
* Motorola S-record data-record layout
*
* Sabbc...cd...dee
*
* S - header character
* a - record type, a 1-digit value:
* "0" is a header record
* "1" is a 2-byte-address data record
* "2" is a 3-byte-address data record
* "3" is a 4-byte-address data record
* "7" is a 4-byte-address end-of-data record
* "8" is a 3-byte-address end-of-data record
* "9" is a 2-byte-address end-of-data record
* bb - record length in bytes, a 2-digit hex value
* (record length doesn't count the header/type
* chars and checksum byte)
* c...c - record address, a 4-, 6-, or 8-digit value,
* depending on record type
* d...d - data (always an even number of chars)
* ee - record checksum, a 2-digit hex value
* checksum = 1's complement
* [ (sum of all bytes: bbc..cd...d) modulo 256 ]
*/
#define S1_COUNT_OFFSET 3
Boolean is_moto_s1_data_rec( char * rec_str )
{
return ( ( rec_str[ 0 ] == 'S' ) && ( rec_str[ 1 ] == '1' ) );
}
Uint get_moto_s1_rec_data_count( char * rec_str )
{
return( ( Uint ) get_ndigit_hex( rec_str + 2, 2 ) - S1_COUNT_OFFSET );
}
Ulong get_moto_s1_rec_address( char * rec_str )
{
return( get_ndigit_hex( rec_str + 4, 4 ) );
}
char * get_moto_s1_rec_data_start( char * rec_str )
{
return( rec_str + 8 );
}
void put_moto_s1_data_rec( Uint count, Ulong address, char * data_str )
{
char *ptr;
Uint sum = S1_COUNT_OFFSET + count +
( address >> 8 & 0xff ) + ( address & 0xff );
for ( ptr = data_str ; *ptr != EOS ; ptr += 2 )
sum += ( Uint ) get_ndigit_hex( ptr, 2 );
printf(
"S1%02X%04lX%s%02X\n",
count + S1_COUNT_OFFSET, address, data_str, ~sum & 0xff
);
}
Rec_vitals motorola_s1_rec =
{
is_moto_s1_data_rec,
get_moto_s1_rec_address,
get_moto_s1_rec_data_count,
MAX_LEN_S1_RECS, /* Maximum data bytes in a record. */
get_moto_s1_rec_data_start,
put_moto_s1_data_rec
};
/*------------------------- Motorola S2-record format ------------------------*/
#define S2_COUNT_OFFSET 4
Boolean is_moto_s2_data_rec( char * rec_str )
{
return ( ( rec_str[ 0 ] == 'S' ) && ( rec_str[ 1 ] == '2' ) );
}
Uint get_moto_s2_rec_data_count( char * rec_str )
{
return( ( Uint ) get_ndigit_hex( rec_str + 2, 2 ) - S2_COUNT_OFFSET );
}
Ulong get_moto_s2_rec_address( char * rec_str )
{
return( get_ndigit_hex( rec_str + 4, 6 ) );
}
char * get_moto_s2_rec_data_start( char * rec_str )
{
return( rec_str + 10 );
}
void put_moto_s2_data_rec( Uint count, Ulong address, char * data_str )
{
char *ptr;
Uint sum = S2_COUNT_OFFSET + count + ( address >> 16 & 0xff ) +
( address >> 8 & 0xff ) +
( address & 0xff );
for ( ptr = data_str ; *ptr != EOS ; ptr += 2 )
sum += ( Uint ) get_ndigit_hex( ptr, 2 );
printf(
"S2%02X%06lX%s%02X\n",
count + S2_COUNT_OFFSET, address, data_str, ~sum & 0xff
);
}
Rec_vitals motorola_s2_rec =
{
is_moto_s2_data_rec,
get_moto_s2_rec_address,
get_moto_s2_rec_data_count,
MAX_LEN_S2_RECS, /* Maximum data bytes in a record. */
get_moto_s2_rec_data_start,
put_moto_s2_data_rec
};
/*------------------------- Motorola S3-record format ------------------------*/
#define S3_COUNT_OFFSET 5
Boolean is_moto_s3_data_rec( char * rec_str )
{
return ( ( rec_str[ 0 ] == 'S' ) && ( rec_str[ 1 ] == '3' ) );
}
Uint get_moto_s3_rec_data_count( char * rec_str )
{
return( ( Uint ) get_ndigit_hex( rec_str + 2, 2 ) - S3_COUNT_OFFSET );
}
Ulong get_moto_s3_rec_address( char * rec_str )
{
return( get_ndigit_hex( rec_str + 4, 8 ) );
}
char * get_moto_s3_rec_data_start( char * rec_str )
{
return( rec_str + 12 );
}
void put_moto_s3_data_rec( Uint count, Ulong address, char * data_str )
{
char *ptr;
Uint sum = S3_COUNT_OFFSET + count + ( address >> 24 & 0xff ) +
( address >> 16 & 0xff ) +
( address >> 8 & 0xff ) +
( address & 0xff );
for ( ptr = data_str ; *ptr != EOS ; ptr += 2 )
sum += ( Uint ) get_ndigit_hex( ptr, 2 );
printf(
"S3%02X%08lX%s%02X\n",
count + S3_COUNT_OFFSET, address, data_str, ~sum & 0xff
);
}
Rec_vitals motorola_s3_rec =
{
is_moto_s3_data_rec,
get_moto_s3_rec_address,
get_moto_s3_rec_data_count,
MAX_LEN_S3_RECS, /* Maximum data bytes in a record. */
get_moto_s3_rec_data_start,
put_moto_s3_data_rec
};
/*-------------------- Put your favorite hex format here ---------------------*/
/*
* * * * The following is a template for an additional hex format: * * *
*
*
* Boolean is_X_data_rec( char * rec_str ) {}
*
* Uint get_X_rec_data_count( char * rec_str ) {}
*
* Ulong get_X_rec_address( char * rec_str ) {}
*
* char * get_X_rec_data_start( char * rec_str ) {}
*
* void put_X_data_rec( Uint count, Ulong address, char * data_str ) {}
*
* Rec_vitals X_rec =
* {
* is_X_data_rec,
* get_X_rec_address,
* get_X_rec_data_count,
* MAXIMUM DATA BYTES IN A RECORD,
* get_X_rec_data_start,
* put_X_data_rec
* };
*
*/
/*----------------------------------------------------------------------------*/
/*
* Put address of additional Rec_vitals structures
* in this array, before the NULL entry.
*/
Rec_vitals *formats[] =
{
&intel_hex,
&motorola_s1_rec,
&motorola_s2_rec,
&motorola_s3_rec,
( Rec_vitals * ) NULL
};
/**** main *****************************************************************
*
*
* Expects: Nothing (no command-line parameters).
*
* Returns: Exit status (EXIT_SUCCESS or EXIT_FAILURE).
*
* Reads hex records on the standard input and attempts to
* splice adjacent data fields together. Results appear on
* the standard output.
*
*******************************************************************************/
int main(
int argc,
char **argv
)
{
char inbuff[ MAX_LINE_SIZE ], outbuff[ MAX_LINE_SIZE ];
char *in_dptr, *out_dptr;
int d_total, d_count, d_excess, n;
int length;
Ulong in_rec_addr, out_rec_addr = 0;
Rec_vitals *rptr;
/* Sift through file until first hex record is identified. */
rptr = identify_first_data_record( inbuff, MAX_LINE_SIZE );
if ( rptr == NULL )
{
fputs( "No hex records found.\n", stderr );
exit( EXIT_FAILURE );
}
/* Attempt data-record splicing until end-of-file is reached. */
d_total = 0;
for (;;) {
if ( rptr->is_data_record( inbuff ) == YES )
{ /* Input record is a data record. */
d_count = rptr->get_data_count( inbuff );
in_rec_addr = rptr->get_address( inbuff );
in_dptr = rptr->get_data_start( inbuff );
if ( d_total == 0 || in_rec_addr != out_rec_addr + d_total )
{ /* Begin a new output record. */
if ( d_total != 0 )
rptr->put_data_record( d_total, out_rec_addr, outbuff );
out_dptr = outbuff;
n = d_total = d_count;
out_rec_addr = in_rec_addr;
}
else if
( ( d_excess = d_total + d_count - rptr->max_data_count ) > 0 )
{ /* Output a maximum-length record, then start a new record. */
strncat( outbuff, in_dptr, 2 * ( d_count - d_excess ) );
rptr->put_data_record(
rptr->max_data_count, out_rec_addr, outbuff
);
in_dptr += 2 * ( d_count - d_excess );
out_dptr = outbuff;
n = d_total = d_excess;
out_rec_addr += rptr->max_data_count;
}
else
{ /* Append input record's data field with accumulated data. */
out_dptr = outbuff + ( 2 * d_total );
d_total += n = d_count;
}
strncpy( out_dptr, in_dptr, 2 * n );
out_dptr[ 2 * n ] = EOS;
}
else
{ /* Not a data record;
* flush accumulated data then echo non-data record.
*/
if ( d_total != 0 )
{
rptr->put_data_record( d_total, out_rec_addr, outbuff );
d_total = 0;
}
puts( inbuff );
}
inbuff[ MAX_LINE_SIZE - 1 ] = '\0';
if ( !fgets( inbuff, MAX_LINE_SIZE, stdin ) )
break;
if ( inbuff[ MAX_LINE_SIZE - 1 ] ) {
fprintf( stderr, "Input line too long" );
exit( 1 );
}
length = strlen(inbuff);
inbuff[length - 1] = '\0';
}
return ( EXIT_SUCCESS );
}
/**** identify_first_data_record *******************************************
*
* Expects: Pointer to hex-record line buffer.
*
* Returns: Pointer to hex-record structure (NULL if no match found).
*
* Reads the standard input, line by line, searching for a valid
* record header character. If a valid header is found, a pointer
* to the hex-record's type structure is returned, otherwise NULL.
*
* The input-stream pointer is left pointing to the first valid hex record.
*
*******************************************************************************/
Rec_vitals * identify_first_data_record( char * buff_ptr, int max_length )
{
Rec_vitals ** ptr;
int length;
for ( ;; ) {
buff_ptr[ max_length - 1 ] = '\0';
if ( !fgets( buff_ptr, max_length, stdin ) )
break;
if ( buff_ptr[ max_length - 1 ] ) {
fprintf( stderr, "Input line too long" );
exit( 1 );
}
length = strlen(buff_ptr);
buff_ptr[length - 1] = '\0';
for ( ptr = formats ; *ptr != ( Rec_vitals * ) NULL ; ptr++ )
if ( ( *ptr )->is_data_record( buff_ptr ) == YES )
return( *ptr ); /* Successful return. */
puts( buff_ptr ); /* Echo non-hex-record line. */
}
return( ( Rec_vitals * ) NULL ); /* Unsuccessful return. */
}
/**** get_ndigit_hex *******************************************************
*
* Expects: Pointer to first ASCII hexadecimal digit, number of digits.
*
* Returns: Value of hexadecimal string as an unsigned long.
*
*******************************************************************************/
Ulong get_ndigit_hex( char * cptr, int digits )
{
Ulong value;
for ( value = 0 ; --digits >= 0 ; cptr++ )
value = ( value * 16L ) + HEX_DIGIT( *cptr );
return( value );
}

291
tools/build/rtems-bin2c.c Normal file
View File

@@ -0,0 +1,291 @@
/*
* bin2c.c
*
* convert a binary file into a C source array.
*
* THE "BEER-WARE LICENSE" (Revision 3.1415):
* sandro AT sigala DOT it wrote this file. As long as you retain this
* notice you can do whatever you want with this stuff. If we meet some
* day, and you think this stuff is worth it, you can buy me a beer in
* return. Sandro Sigala
*
* Subsequently modified by Joel Sherrill <joel.sherrill@oarcorp.com>
* to add a number of capabilities not in the original.
*
* syntax: bin2c [-c] [-z] <input_file> <output_file>
*
* -c do NOT add the "const" keyword to definition
* -s add the "static" keywork to definition
* -v verbose
* -z terminate the array with a zero (useful for embedded C strings)
*
* examples:
* bin2c -c myimage.png myimage_png.cpp
* bin2c -z sometext.txt sometext_txt.cpp
*
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
int useconst = 1;
int usestatic = 0;
int verbose = 0;
int zeroterminated = 0;
int createC = 1;
int createH = 1;
int myfgetc(FILE *f)
{
int c = fgetc(f);
if (c == EOF && zeroterminated) {
zeroterminated = 0;
return 0;
}
return c;
}
void process(const char *ifname, const char *ofname)
{
FILE *ifile, *ocfile, *ohfile;
char buf[PATH_MAX], *p;
char obasename[PATH_MAX];
char ocname[PATH_MAX];
char ohname[PATH_MAX];
const char *cp;
size_t len;
/* Error check */
if ( !ifname || !ofname ) {
fprintf(stderr, "process has NULL filename\n");
exit(1);
}
strncpy( obasename, ofname, PATH_MAX );
len = strlen( obasename );
if ( len >= 2 ) {
if ( obasename[len-2] == '.' ) {
if ( (obasename[len-1] == 'c') || (obasename[len-1] == 'h') )
obasename[len-2] = '\0';
}
}
sprintf( ocname, "%s.c", obasename );
sprintf( ohname, "%s.h", obasename );
if ( verbose ) {
fprintf(
stderr,
"in file: %s\n"
"c file: %s\n"
"h file: %s\n",
ifname,
ocname,
ohname
);
}
/* Open input and output files */
ifile = fopen(ifname, "rb");
if (ifile == NULL) {
fprintf(stderr, "cannot open %s for reading\n", ifname);
exit(1);
}
if ( createC ) {
ocfile = fopen(ocname, "wb");
if (ocfile == NULL) {
fprintf(stderr, "cannot open %s for writing\n", ocname);
exit(1);
}
}
if ( createH ) {
ohfile = fopen(ohname, "wb");
if (ohfile == NULL) {
fprintf(stderr, "cannot open %s for writing\n", ohname);
exit(1);
}
}
/* find basename */
char *ifbasename = strdup(ifname);
ifbasename = basename(ifbasename);
strcpy(buf, ifbasename);
for (p = buf; *p != '\0'; ++p)
if (!isalnum(*p))
*p = '_';
if ( createC ) {
/* print C file header */
fprintf(
ocfile,
"/*\n"
" * Declarations for C structure representing binary file %s\n"
" *\n"
" * WARNING: Automatically generated -- do not edit!\n"
" */\n"
"\n"
"#include <sys/types.h>\n"
"\n",
ifbasename
);
/* print structure */
fprintf(
ocfile,
"%s%sunsigned char %s[] = {\n ",
((usestatic) ? "static " : ""),
((useconst) ? "const " : ""),
buf
);
int c, col = 1;
while ((c = myfgetc(ifile)) != EOF) {
if (col >= 78 - 6) {
fprintf(ocfile, "\n ");
col = 1;
}
fprintf(ocfile, "0x%.2x, ", c);
col += 6;
}
fprintf(ocfile, "\n};\n");
/* print sizeof */
fprintf(
ocfile,
"\n"
"%s%ssize_t %s_size = sizeof(%s);\n",
((usestatic) ? "static " : ""),
((useconst) ? "const " : ""),
buf,
buf
);
} /* createC */
/*****************************************************************/
/****** END OF C FILE *****/
/*****************************************************************/
if ( createH ) {
/* print H file header */
fprintf(
ohfile,
"/*\n"
" * Extern declarations for C structure representing binary file %s\n"
" *\n"
" * WARNING: Automatically generated -- do not edit!\n"
" */\n"
"\n"
"#ifndef __%s_h\n"
"#define __%s_h\n"
"\n"
"#include <sys/types.h>\n"
"\n",
ifbasename, /* header */
obasename, /* ifndef */
obasename /* define */
);
/* print structure */
fprintf(
ohfile,
"extern %s%sunsigned char %s[];",
((usestatic) ? "static " : ""),
((useconst) ? "const " : ""),
buf
);
/* print sizeof */
fprintf(
ohfile,
"\n"
"extern %s%ssize_t %s_size;\n",
((usestatic) ? "static " : ""),
((useconst) ? "const " : ""),
buf
);
fprintf(
ohfile,
"\n"
"#endif\n"
);
} /* createH */
/*****************************************************************/
/****** END OF H FILE *****/
/*****************************************************************/
fclose(ifile);
if ( createC ) { fclose(ocfile); }
if ( createH ) { fclose(ohfile); }
}
void usage(void)
{
fprintf(
stderr,
"usage: bin2c [-csvzCH] <input_file> <output_file>\n"
" <input_file> is the binary file to convert\n"
" <output_file> should not have a .c or .h extension\n"
"\n"
" -c - do NOT use const in declaration\n"
" -s - do use static in declaration\n"
" -v - verbose\n"
" -z - add zero terminator\n"
" -H - create c-header only\n"
" -C - create c-source file only\n"
);
exit(1);
}
int main(int argc, char **argv)
{
while (argc > 3) {
if (!strcmp(argv[1], "-c")) {
useconst = 0;
--argc;
++argv;
} else if (!strcmp(argv[1], "-s")) {
usestatic = 1;
--argc;
++argv;
} else if (!strcmp(argv[1], "-v")) {
verbose = 1;
--argc;
++argv;
} else if (!strcmp(argv[1], "-z")) {
zeroterminated = 1;
--argc;
++argv;
} else if (!strcmp(argv[1], "-C")) {
createH = 0;
createC = 1;
--argc;
++argv;
} else if (!strcmp(argv[1], "-H")) {
createC = 0;
createH = 1;
--argc;
++argv;
} else {
usage();
}
}
if (argc != 3) {
usage();
}
/* process( input_file, output_basename ) */
process(argv[1], argv[2]);
return 0;
}

15
tools/build/search-id.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
#
# $Id$
#
find $1 -type f -a ! -name "*.scn" -a ! -name "bsp_specs" -a \
-print > /tmp/$$.0
find $1 -type f -a ! -name "*.scn" -a ! -name "bsp_specs" -a \
-exec grep -l '$Id' {} \; > /tmp/$$.1
diff /tmp/$$.0 /tmp/$$.1 > /tmp/$$.2
grep "<" /tmp/$$.2 | sed 's/< //' >&1
rm -f /tmp/$$*

737
tools/build/unhex.c Normal file
View File

@@ -0,0 +1,737 @@
/*
* unhex
* convert a hex file to binary equivalent. If more than one file name
* is given, then the output will be logically concatenated together.
* stdin and stdout are defaults. Verbose will enable checksum output.
*
* Supported input formats are Intel hex, Motorola S records, and TI 'B'
* records.
*
* Intel hex input format is
* Byte
* 1 Colon :
* 2..3 Record length, eg: "20"
* 4..7 load address nibbles
* 8..9 record type: "00" (data) or "02" base addr
* 10..x data bytes in ascii-hex
* x+1..x+2 cksum (2's compl of (len+addr+data))
* x+3 \n -- newline
*
* $Id$
*/
char *USAGE = "\
usage: unhex [-va] [ -o file ] [ file [file ... ] ]\n\
-v -- verbose\n\
-a base -- 1st byte of output corresponds to this address\n\
-l -- linear, just writes data out\n\
-o file -- output file; must not be input file\n\
-F k_bits -- \"holes\" in input will be filled with 0xFF's\n\
up to \"k_bits\" * 1024 bits\n\
";
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include "config.h"
#ifndef VMS
#ifndef HAVE_STRERROR
extern int sys_nerr;
extern char *sys_errlist[];
#define strerror( _err ) \
((_err) < sys_nerr) ? sys_errlist [(_err)] : "unknown error"
#else /* HAVE_STRERROR */
char *strerror ();
#endif
#else /* VMS */
char *strerror (int,...);
#endif
#define OK 0
#define FAILURE (-1)
#define Failed(x) ((x) == FAILURE)
#define TRUE 1
#define FALSE 0
typedef char bool;
#define STREQ(a,b) (strcmp(a,b) == 0)
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
/*
* Pick out designated bytes
*/
#define B0(x) ((x) & 0xff)
#define B1(x) B0((x) >> 8)
#define B2(x) B0((x) >> 16)
#define B3(x) B0((x) >> 24)
typedef struct buffer_rec {
u32 dl_destaddr;
u32 dl_jumpaddr;
int dl_count;
u8 dl_buf[512];
} buffer_rec;
/*
* vars controlled by command line options
*/
bool verbose = FALSE; /* be verbose */
bool linear = FALSE; /* just write out linear data */
char *outfilename = "-"; /* default output is stdout */
u32 base = 0L; /* base address */
u32 FFfill = 0L; /* how far to fill w 0xFF's */
extern char *optarg; /* getopt(3) control vars */
extern int optind;
char *progname; /* for error() */
void error(int errn, ...);
#define ERR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
#define ERR_FATAL (ERR_ERRNO / 2) /* error is fatal; no return */
#define ERR_ABORT (ERR_ERRNO / 4) /* error is fatal; abort */
#define ERR_MASK (ERR_ERRNO | ERR_FATAL | ERR_ABORT) /* all */
#ifdef HAVE_STRTOUL
#define stol(p) strtoul(p, (char **) NULL, 0)
#else
#define stol(p) strtol(p, (char **) NULL, 0)
#endif
int unhex(FILE *ifp, char *inm, FILE *ofp, char *onm);
int convert_Intel_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
int convert_S_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
int convert_TI_records(FILE *ifp, char *inm, FILE *ofp, char *onm);
void write_record(buffer_rec *tb, FILE *fp);
int getnibble(char **p);
int getbyte(char **p);
long getNbytes(char **p, int n);
void badformat(char *s, char *fname, char *msg);
#define get1bytes(p) ((int) getbyte(p))
#define get2bytes(p) ((int) getNbytes(p, 2))
#define get3bytes(p) getNbytes(p, 3)
#define get4bytes(p) getNbytes(p, 4)
char *BADADDR = "Invalid record address";
char *BADLEN = "Invalid record length";
char *BADBASE = "Bad base or starting address";
char *BADFMT = "Unrecognized record type";
char *BADDATA = "Invalid data byte";
char *BADCSUM = "Invalid checksum";
char *MISCSUM = "Checksum mismatch";
char *BADTYPE = "Unrecognized record type";
char *MISTYPE = "Incompatible record types";
int main(
int argc,
char **argv
)
{
register int c;
bool showusage = FALSE; /* usage error? */
int rc = 0;
FILE *outfp, *infp;
/*
* figure out invocation leaf-name
*/
if ((progname = strrchr(argv[0], '/')) == (char *) NULL)
progname = argv[0];
else
progname++;
argv[0] = progname; /* for getopt err reporting */
/*
* Check options and arguments.
*/
progname = argv[0];
while ((c = getopt(argc, argv, "F:a:o:vl")) != EOF)
switch (c)
{
case 'a': /* base address */
base = stol(optarg);
break;
case 'l': /* linear output */
linear = TRUE;
break;
case 'v': /* toggle verbose */
verbose = ! verbose;
break;
case 'o': /* output file */
outfilename = optarg;
break;
case 'F': /* 0xFF fill amount (bytes) */
FFfill = stol(optarg) * 1024L / 8L;
break;
case '?':
showusage = TRUE;
}
if (showusage)
{
(void) fprintf(stderr, "%s", USAGE);
exit(1);
}
if (linear && (base != 0))
{
error(0, "-l and -a may not be specified in combination");
exit(1);
}
if (STREQ(outfilename, "-"))
{
outfp = stdout;
outfilename = "stdout";
}
else
if ((outfp = fopen(outfilename, "w")) == (FILE *) NULL)
{
error(-1, "couldn't open '%s' for output", outfilename);
exit(1);
}
/*
* Now process the input files (or stdin, if none specified)
*/
if (argv[optind] == (char *) NULL) /* just stdin */
exit(unhex(stdin, "stdin", outfp, outfilename));
else
for (; (optarg = argv[optind]); optind++)
{
if (STREQ(optarg, "-"))
rc += unhex(stdin, "stdin", outfp, outfilename);
else
{
if ((infp = fopen(optarg, "r")) == (FILE *) NULL)
{
error(-1, "couldn't open '%s' for input", optarg);
exit(1);
}
rc += unhex(infp, optarg, outfp, outfilename);
}
}
return(rc);
}
u16 filesum;
int
unhex(FILE *ifp,
char *inm,
FILE *ofp,
char *onm)
{
int c;
filesum = 0;
/*
* Make sure holes will be filled with 0xFF's if requested. We
* do this the easy way by just filling the file with FF's before
* getting started. To do it more optimally would be quite a bit
* more difficult since the user can skip around as much as he/she
* likes in the input hex file addressing.
*
* We'll clean this up later (after this program has run) with
* 'stripffs'
*/
if (FFfill)
{
(void) fseek(ofp, 0, 0);
for (c = FFfill; c > 0; c--)
(void) fputc(0xFF, ofp);
}
/*
* Read the first char from file and determine record types
*/
if ((c = getc(ifp)) != EOF)
{
ungetc(c, ifp);
switch(c)
{
case 'S':
convert_S_records(ifp, inm, ofp, onm);
break;
case ':':
convert_Intel_records(ifp, inm, ofp, onm);
break;
case '9':
case 'B':
convert_TI_records(ifp, inm, ofp, onm);
break;
default:
{
char tmp[2];
tmp[0] = c; tmp[1] = 0;
badformat(tmp, inm, BADFMT);
}
}
}
if (verbose)
fprintf(stderr, "'%s' checksum is 0x%04x\n", inm, filesum);
return 0;
}
int
convert_Intel_records(
FILE *ifp,
char *inm,
FILE *ofp,
char *onm)
{
char buff[512];
char *p;
u8 cksum;
int incksum;
int c;
int rectype; /* record type */
int len; /* data length of current line */
u32 addr;
u32 base_address = 0;
bool endrecord = FALSE;
buffer_rec tb;
while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
{
p = &buff[0];
if (p[strlen(p)-1] == '\n') /* get rid of newline */
p[strlen(p)-1] = '\0';
if (p[strlen(p)-1] == '\r') /* get rid of any CR */
p[strlen(p)-1] = '\0';
tb.dl_count = 0;
if (*p != ':')
badformat(p, inm, BADFMT);
p++;
if ((len = getbyte(&p)) == -1) /* record len */
badformat(buff, inm, BADLEN);
if ((addr = get2bytes(&p)) == -1L) /* record addr */
badformat(buff, inm, BADADDR);
rectype = getbyte(&p);
cksum = len + B0(addr) + B1(addr) + rectype;
switch (rectype)
{
case 0x00: /* normal data record */
tb.dl_destaddr = base_address + addr;
while (len--)
{
if ((c = getbyte(&p)) == -1)
badformat(buff, inm, BADDATA);
cksum += c;
filesum += c;
tb.dl_buf[tb.dl_count++] = c;
}
break;
case 0x01: /* execution start address */
base_address = addr;
endrecord = TRUE;
break;
case 0x02: /* new base */
if ((base_address = get2bytes(&p)) == -1L)
badformat(buff, inm, BADBASE);
cksum += B0(base_address) + B1(base_address);
base_address <<= 4;
break;
case 0x03: /* seg/off execution start address */
{
u32 seg, off;
seg = get2bytes(&p);
off = get2bytes(&p);
if ((seg == -1L) || (off == -1L))
badformat(buff, inm, BADADDR);
cksum += B0(seg) + B1(seg) + B0(off) + B1(off);
tb.dl_jumpaddr = (seg << 4) + off;
break;
}
default:
error(0, "unknown Intel-hex record type: 0x%02x", rectype);
badformat(buff, inm, BADTYPE);
}
/*
* Verify checksums are correct in file.
*/
cksum = (-cksum) & 0xff;
if ((incksum = getbyte(&p)) == -1)
badformat(buff, inm, BADCSUM);
if (((u8) incksum) != cksum)
badformat(buff, inm, MISCSUM);
if (tb.dl_count)
write_record(&tb, ofp);
}
return 0;
}
int
convert_S_records(
FILE *ifp,
char *inm,
FILE *ofp,
char *onm)
{
char buff[512];
char *p;
u8 cksum;
int incksum;
int c;
int len; /* data length of current line */
int rectype; /* record type */
u32 addr;
bool endrecord = FALSE;
buffer_rec tb;
while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
{
p = &buff[0];
if (p[strlen(p)-1] == '\n') /* get rid of newline */
p[strlen(p)-1] = '\0';
if (p[strlen(p)-1] == '\r') /* get rid of any CR */
p[strlen(p)-1] = '\0';
tb.dl_count = 0;
if (*p != 'S')
badformat(p, inm, BADFMT);
p++;
if ((rectype = getnibble(&p)) == -1) /* record type */
badformat(buff, inm, BADTYPE);
if ((len = getbyte(&p)) == -1) /* record len */
badformat(buff, inm, BADLEN);
cksum = len;
switch (rectype)
{
case 0x00: /* comment field, ignored */
goto write_it;
case 0x01: /* data record, 16 bit addr */
if ((addr = get2bytes(&p)) == -1L)
badformat(buff, inm, BADADDR);
len -= 3;
goto doit;
case 0x02: /* ... 24 bit addr */
if ((addr = get3bytes(&p)) == -1L)
badformat(buff, inm, BADADDR);
len -= 4;
goto doit;
case 0x03: /* ... 32 bit addr */
if ((addr = get4bytes(&p)) == -1L)
badformat(buff, inm, BADADDR);
len -= 5;
doit:
cksum += B0(addr) + B1(addr) + B2(addr) + B3(addr);
tb.dl_destaddr = addr;
while (len--)
{
if ((c = getbyte(&p)) == -1)
badformat(buff, inm, BADDATA);
cksum += c;
filesum += c;
tb.dl_buf[tb.dl_count++] = c;
}
break;
case 0x07: /* 32 bit end record */
if ((addr = get4bytes(&p)) == -1L)
badformat(buff, inm, BADADDR);
goto end_rec;
case 0x08: /* 24 bit end record */
if ((addr = get3bytes(&p)) == -1L)
badformat(buff, inm, BADADDR);
goto end_rec;
case 0x09: /* 16 bit end record */
if ((addr = get2bytes(&p)) == -1L)
badformat(buff, inm, BADADDR);
end_rec:
cksum += B0(addr) + B1(addr) + B2(addr) + B3(addr);
tb.dl_jumpaddr = addr;
break;
default:
error(0, "unknown Motorola-S record type: 0x%02x", rectype);
badformat(buff, inm, BADTYPE);
break;
}
/*
* Verify checksums are correct in file.
*/
cksum = (~cksum) & 0xff;
if ((incksum = getbyte(&p)) == -1)
badformat(buff, inm, BADCSUM);
if (((u8) incksum) != cksum)
badformat(buff, inm, MISCSUM);
write_it:
if (tb.dl_count)
write_record(&tb, ofp);
}
return 0;
}
int
convert_TI_records(
FILE *ifp,
char *inm,
FILE *ofp,
char *onm)
{
char buff[512];
char *p;
int c;
bool endrecord = FALSE;
bool eol;
buffer_rec tb;
while ( ! endrecord && (fgets(buff, sizeof(buff), ifp)))
{
if (p[strlen(p)-1] == '\n') /* get rid of newline */
p[strlen(p)-1] = '\0';
if (p[strlen(p)-1] == '\r') /* get rid of any CR */
p[strlen(p)-1] = '\0';
tb.dl_count = 0;
p = &buff[0];
eol = FALSE;
while ( ! eol && ! endrecord)
{
switch (*p++)
{
case '9':
if (tb.dl_count)
write_record(&tb, ofp);
tb.dl_destaddr = get2bytes(&p);
break;
case 'B':
c = getbyte(&p);
filesum += c;
tb.dl_buf[tb.dl_count++] = c;
c = getbyte(&p);
filesum += c;
tb.dl_buf[tb.dl_count++] = c;
break;
case 'F':
eol = TRUE;
break;
case ':':
endrecord = TRUE;
break;
default:
badformat(p, inm, BADFMT);
}
}
if (tb.dl_count)
write_record(&tb, ofp);
}
return 0;
}
void
write_record(buffer_rec *tb,
FILE *fp)
{
if ( ! linear)
{
if (tb->dl_destaddr < base)
error(ERR_FATAL, "record at address 0x%x precedes base of 0x%x",
tb->dl_destaddr, base);
(void) fseek(fp, tb->dl_destaddr - base, 0);
}
(void) fwrite(tb->dl_buf, tb->dl_count, 1, fp);
tb->dl_destaddr += tb->dl_count;
tb->dl_count = 0;
}
int
getnibble(char **p)
{
register int val;
**p = toupper(**p);
switch (**p)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
val = **p - '0';
break;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
val = 10 + (**p - 'A');
break;
default:
return(-1);
}
*p += 1;
return(val & 0x0f);
}
int
getbyte(char **p)
{
int n0, n1;
if ((n0 = getnibble(p)) == -1)
return(-1);
if ((n1 = getnibble(p)) == -1)
return(-1);
return(((n0 << 4) + n1) & 0xff);
}
long
getNbytes(char **p,
int n)
{
int t;
u32 val = 0;
while (n--)
{
if ((t = getbyte(p)) == -1)
return(-1L);
val <<= 8;
val += t;
}
return(val);
}
void
badformat(char *s,
char *fname,
char *msg)
{
if (s[strlen(s)-1] == '\n') /* get rid of newline */
s[strlen(s)-1] = '\0';
error(0, "line '%s'::\n\tfrom file '%s'; %s", s, fname, msg);
exit(1);
}
/*
* error(errn, arglist)
* report an error to stderr using printf(3) conventions.
* Any output is preceded by '<progname>: '
*
* Uses ERR_EXIT bit to request exit(errn)
* ERR_ABORT to request abort()
* ERR_ERRNO to indicate use of errno instead of argument.
*
* If resulting 'errn' is non-zero, it is assumed to be an 'errno' and its
* associated error message is appended to the output.
*/
/*VARARGS*/
void
error(int error_flag, ...)
{
va_list arglist;
register char *format;
int local_errno;
extern int errno;
(void) fflush(stdout); /* in case stdout/stderr same */
local_errno = error_flag & ~ERR_MASK;
if (error_flag & ERR_ERRNO) /* use errno? */
local_errno = errno;
va_start(arglist, error_flag);
format = va_arg(arglist, char *);
(void) fprintf(stderr, "%s: ", progname);
(void) vfprintf(stderr, format, arglist);
va_end(arglist);
if (local_errno)
(void) fprintf(stderr, " (%s)\n", strerror(local_errno));
else
(void) fprintf(stderr, "\n");
(void) fflush(stderr);
if (error_flag & (ERR_FATAL | ERR_ABORT))
{
if (error_flag & ERR_FATAL)
{
error(0, "fatal error, exiting");
exit(local_errno ? local_errno : 1);
}
else
{
error(0, "fatal error, aborting");
abort();
}
}
}