mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-06-08 05:29:33 +00:00
Changes for v1.1-release
- increased optimization level to -1 - added -d option - changed output format
This commit is contained in:
parent
e62ed561aa
commit
d1faeee771
|
@ -1,18 +1,23 @@
|
||||||
#
|
#
|
||||||
# This makefile is intended for use with dmake(1) on Apple IIGS
|
# This makefile is intended for use with dmake(1) on Apple IIGS
|
||||||
#
|
#
|
||||||
# $Id: Makefile,v 1.3 1997/09/26 06:36:22 gdr Exp $
|
# $Id: Makefile,v 1.4 1997/09/28 16:41:12 gdr Exp $
|
||||||
#
|
#
|
||||||
|
# Created by Dave Tribby, September 1997
|
||||||
|
|
||||||
# Program name
|
# Program name
|
||||||
PROG = lseg
|
PROG = lseg
|
||||||
|
|
||||||
# Default stack size and optimization (can be overridden by cmd line)
|
# Default stack size and optimization (can be overridden by cmd line)
|
||||||
|
# These values have been tested and certified as working
|
||||||
.IF $(STACK) == $(NULL)
|
.IF $(STACK) == $(NULL)
|
||||||
STACK = 1024
|
STACK = 1024
|
||||||
.END
|
.END
|
||||||
|
.IF $(OPTIMIZE) == $(NULL)
|
||||||
|
OPTIMIZE = -1
|
||||||
|
.END
|
||||||
|
|
||||||
# Delivery directory
|
# Delivery directory
|
||||||
BINDIR = /usr/bin
|
BINDIR = /usr/bin
|
||||||
|
|
||||||
.INCLUDE: /src/gno/prog.mk
|
.INCLUDE : /src/gno/prog.mk
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
.\" Man page by Dave Tribby, September 1997
|
|
||||||
.\"
|
.\"
|
||||||
.\" $Id: lseg.1,v 1.2 1997/09/21 22:05:58 gdr Exp $
|
.\" $Id: lseg.1,v 1.3 1997/09/28 16:41:12 gdr Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH LSEG 1 "September 1997" "GNO" "Commands and Applications"
|
.TH LSEG 1 "September 1997" "GNO" "Commands and Applications"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.BR lseg
|
.BR lseg
|
||||||
\- list segments in an Object Module Format file
|
\- list segments in an Object Module Format file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.BR lseg " file ..."
|
.BR lseg
|
||||||
|
.RB [ -d ]
|
||||||
|
.IR file " ..."
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.BR lseg
|
.BR lseg
|
||||||
lists segments in an OMF (object module format) file. Four kinds
|
lists segments in an OMF (object module format) file. Four kinds
|
||||||
|
@ -21,29 +22,77 @@ A full description of OMF files is provided in Appendix F of
|
||||||
.IR "Apple IIGS GS/OS Reference" .
|
.IR "Apple IIGS GS/OS Reference" .
|
||||||
.PP
|
.PP
|
||||||
.BR lseg
|
.BR lseg
|
||||||
prints a report that includes the type and size of each segment
|
prints a report that includes the type, size, and name of each segment of each
|
||||||
of each file. Any file that is not a valid OMF file is so noted.
|
.IR file .
|
||||||
|
Any file that is not a valid OMF file is so noted.
|
||||||
.PP
|
.PP
|
||||||
.BR lseg
|
.BR lseg
|
||||||
can be used on executable files in the following ways: to help discover
|
can be used on executable files in the following ways: to help discover
|
||||||
the location of stack segments (for later editing to smaller sizes), as an
|
the location of stack segments (for later editing to appropriate sizes), as an
|
||||||
aid in determining how to segment large C files whose segments
|
aid in determining how to segment large C files whose segments
|
||||||
exceed the bank size, and for deciding which segments to recombine
|
exceed the bank size, and for deciding which segments to recombine
|
||||||
after excessive segmentation.
|
after excessive segmentation.
|
||||||
.PP
|
.PP
|
||||||
For object and library files,
|
|
||||||
.BR lseg
|
.BR lseg
|
||||||
examines each code segment and tries to figure out how
|
examines each code segment and tries to figure out how
|
||||||
many bytes of local storage are allocated from the stack at execution
|
many bytes of local storage are allocated from the stack at execution
|
||||||
time. This will be determined only if the startup code matches a recognized
|
time. This will be determined only if the startup code matches a recognized
|
||||||
algorithm, such as those used by ORCA/C. If it can be determined, the
|
algorithm, such as those used by ORCA/C. If it can be determined, the
|
||||||
value is printed at the end of the line preceeded by
|
value is printed in the column labeled "Stack".
|
||||||
string "Stack bytes:".
|
This value does not include parameters passed into the routine,
|
||||||
Note that this value does not include parameters passed into the routine,
|
or other use of the stack by the routine.
|
||||||
nor does it include any other use of the stack by the routine. If a
|
.PP
|
||||||
segment has an unusually large stack allocation, examine its source code
|
You can combine
|
||||||
|
.BR lseg
|
||||||
|
with other tools to ensure your program allocates the correct
|
||||||
|
amount of run-time stack space:
|
||||||
|
.RS 1
|
||||||
|
.IP
|
||||||
|
Run
|
||||||
|
.BR lseg
|
||||||
|
on your program's object file to identify routines with significant
|
||||||
|
local storage. If a
|
||||||
|
segment has an unusually large allocation, examine its source code
|
||||||
and see whether arrays can be made static (if the routine is not
|
and see whether arrays can be made static (if the routine is not
|
||||||
recursive) or can be allocated from standard memory by
|
recursive) or can be allocated from standard memory by
|
||||||
.IR malloc (3).
|
.IR malloc (3).
|
||||||
|
.IP
|
||||||
|
Add calls to the
|
||||||
|
.BR stack (3)
|
||||||
|
routines
|
||||||
|
.BR _beginStackCheck " and " _endStackCheck
|
||||||
|
to report overall run-time storage allocation.
|
||||||
|
.IP
|
||||||
|
You can also use ORCA/C's
|
||||||
|
.BR "#pragma debug"
|
||||||
|
with a parameter that sets bit 0 (a value of 1), which causes the
|
||||||
|
run-time code to check stack space at the beginning
|
||||||
|
of each function and halt the program if there is not enough.
|
||||||
|
.IP
|
||||||
|
Run
|
||||||
|
.BR lseg
|
||||||
|
on your program's linked file to determine if it has a "Direct-page/Stack"
|
||||||
|
segment. (If not, the system will allocate 4096 bytes of stack when it runs.)
|
||||||
|
You can set this value with
|
||||||
|
.BR "#pragma stacksize"
|
||||||
|
in programs compiled by ORCA/C.
|
||||||
|
.PP
|
||||||
|
If your program uses significantly less stack space at run-time than
|
||||||
|
is specified in the Direct-page/Stack segment, reduce the size so more is
|
||||||
|
available to other programs that run at the same time.
|
||||||
|
If your program uses more stack space than allocated, it can cause
|
||||||
|
serious problems such as system crashes.
|
||||||
|
.PP
|
||||||
|
Note: Be sure to remove run-time checking in the final version of you
|
||||||
|
program after you determine the appropriate stack size.
|
||||||
|
.PP
|
||||||
|
.BR lseg
|
||||||
|
returns status of 0 on success, and >0 if an error (e.g., file
|
||||||
|
not found) occurs.
|
||||||
|
.SH OPTIONS
|
||||||
|
.BR lseg
|
||||||
|
recognizes one option:
|
||||||
|
.IP \fB-d\fR
|
||||||
|
Print the segment and stack sizes in decimal rather than hexidecimal.
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Jawaid Bazyar for GNO/ME 1.0; updated by Dave Tribby for GNO/ME 2.0.6.
|
Jawaid Bazyar for GNO/ME 1.0; updated by Dave Tribby for GNO/ME 2.0.6.
|
||||||
|
|
|
@ -6,17 +6,18 @@
|
||||||
* Version 1.1 [v1.1] updated by Dave Tribby (Sept. 1997)
|
* Version 1.1 [v1.1] updated by Dave Tribby (Sept. 1997)
|
||||||
* - A few changes for GNO/ME 2.0.6
|
* - A few changes for GNO/ME 2.0.6
|
||||||
* - Added display of allocated stack bytes for code segments
|
* - Added display of allocated stack bytes for code segments
|
||||||
* - Reformatted output to align names and make room for new info
|
* - Reformatted output to use a table format and make room for new info
|
||||||
* - Sanity check to see whether file is an OMF file
|
* - Sanity check to see whether file is an OMF file
|
||||||
* - Use first field as block count for OMF version 1 files
|
* - Use first field as block count for OMF version 1 files
|
||||||
* - Continue processing files even if one cannot be opened
|
* - Continue processing files even if one of them cannot be opened
|
||||||
* - Use standard error reporting interfaces
|
* - Use standard error reporting interfaces
|
||||||
|
* - Print values in hex unless -d (decimal) flag is set
|
||||||
*
|
*
|
||||||
* $Id: lseg.c,v 1.2 1997/09/21 22:05:59 gdr Exp $
|
* $Id: lseg.c,v 1.3 1997/09/28 16:41:13 gdr Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Update for 2.0.6: Move optimization and stack size to Makefile
|
/* Update for 2.0.6: Move optimization and stack size to Makefile
|
||||||
/* #pragma optimize -1 /* Doesn't work for ORCA/C 2.1 */
|
/* #pragma optimize -1
|
||||||
/* #pragma stacksize 1024
|
/* #pragma stacksize 1024
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -29,6 +30,10 @@
|
||||||
#include <unistd.h> /* GNO 2.0.6: read() and close() moved to here */
|
#include <unistd.h> /* GNO 2.0.6: read() and close() moved to here */
|
||||||
#include <err.h> /* GNO 2.0.6: use standard error reporting */
|
#include <err.h> /* GNO 2.0.6: use standard error reporting */
|
||||||
|
|
||||||
|
/* [v1.1] Use library routine rather than macro, so that program */
|
||||||
|
/* code is less complicated and can be optimized by ORCA/C */
|
||||||
|
#undef putchar
|
||||||
|
|
||||||
typedef struct OMFhead {
|
typedef struct OMFhead {
|
||||||
longword BYTECNT;
|
longword BYTECNT;
|
||||||
longword RESSPC;
|
longword RESSPC;
|
||||||
|
@ -51,29 +56,32 @@ typedef struct OMFhead {
|
||||||
longword tempOrg;
|
longword tempOrg;
|
||||||
} OMFhead;
|
} OMFhead;
|
||||||
|
|
||||||
char *segTypes[] = {
|
char *segTypes[] = { /* [v1.1] Omit "unknown" for undefined segment types */
|
||||||
"Code",
|
"Code ",
|
||||||
"Data",
|
"Data ",
|
||||||
"Jump-table",
|
"Jump-table ",
|
||||||
"Unknown",
|
"",
|
||||||
"Pathname",
|
"Pathname ",
|
||||||
"Unknown",
|
"",
|
||||||
"Unknown",
|
"",
|
||||||
"Unknown",
|
"",
|
||||||
"Library Dictionary",
|
"Library Dictionary",
|
||||||
"Unknown",
|
"",
|
||||||
"Unknown",
|
"",
|
||||||
"Unknown",
|
"",
|
||||||
"Unknown",
|
"",
|
||||||
"Unknown",
|
"",
|
||||||
"Unknown",
|
"",
|
||||||
"Unknown",
|
"",
|
||||||
"Initialization",
|
"Initialization ",
|
||||||
"Unknown",
|
"",
|
||||||
"Direct-page/Stack"};
|
"Direct-page/Stack "};
|
||||||
|
|
||||||
|
|
||||||
/* --- Start of new routines [v1.1] --- */
|
/* --- Start of new code [v1.1] --- */
|
||||||
|
|
||||||
|
/* Option for decimal rather than hex output */
|
||||||
|
int decimal_output=FALSE;
|
||||||
|
|
||||||
/* Snippit of code to be analyzed for allocated stack size */
|
/* Snippit of code to be analyzed for allocated stack size */
|
||||||
static char code[8];
|
static char code[8];
|
||||||
|
@ -160,7 +168,13 @@ void checkCodeStack(int fd)
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
while ( (value = readSegRec(fd)) == 0 );
|
while ( (value = readSegRec(fd)) == 0 );
|
||||||
if (value > 0) printf(" Stack bytes: %d", value);
|
if (value > 0)
|
||||||
|
if (decimal_output)
|
||||||
|
printf("%6d ", value);
|
||||||
|
else
|
||||||
|
printf("0x%04X ", value);
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the file under consideration not an OMF file? */
|
/* Is the file under consideration not an OMF file? */
|
||||||
|
@ -179,23 +193,16 @@ int notOMF(OMFhead *headPnt)
|
||||||
|
|
||||||
void prntAscii(char *s, int l)
|
void prntAscii(char *s, int l)
|
||||||
{
|
{
|
||||||
/* Pad with blanks if < 18 chars [v1.1] */
|
|
||||||
int pad;
|
|
||||||
|
|
||||||
pad = 18 - l;
|
|
||||||
putchar('"');
|
putchar('"');
|
||||||
while (l--) {
|
while (l--) {
|
||||||
*s &= 0x7F;
|
*s &= 0x7F;
|
||||||
if (*s < ' ') {
|
if (*s < ' ') {
|
||||||
putchar('^');
|
putchar('^');
|
||||||
putchar(*s+'@');
|
putchar(*s+'@');
|
||||||
pad--;
|
|
||||||
} else putchar(*s);
|
} else putchar(*s);
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
putchar('"');
|
putchar('"');
|
||||||
while (pad-- > 0)
|
|
||||||
putchar(' ');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char name[256];
|
char name[256];
|
||||||
|
@ -203,26 +210,24 @@ char name[256];
|
||||||
* The caller is responsible for opening the file, passing its refNum,
|
* The caller is responsible for opening the file, passing its refNum,
|
||||||
* and closing it after we're done
|
* and closing it after we're done
|
||||||
*/
|
*/
|
||||||
void scanOMF(int fd)
|
void scanOMF(int fd, char *fname)
|
||||||
{
|
{
|
||||||
OMFhead header;
|
OMFhead header;
|
||||||
longword off = 0l;
|
longword off = 0l;
|
||||||
PositionRecGS p;
|
PositionRecGS p;
|
||||||
int kind;
|
int kind;
|
||||||
int stsize = 0;
|
int i;
|
||||||
|
|
||||||
p.pCount = 2;
|
p.pCount = 2;
|
||||||
p.refNum = fd;
|
p.refNum = fd;
|
||||||
GetEOF(&p);
|
GetEOF(&p);
|
||||||
|
|
||||||
while (off < p.position) {
|
while (off < p.position) {
|
||||||
/* printf("offset: %ld\t\t",off); */
|
|
||||||
printf(" ");
|
|
||||||
lseek(fd, off, SEEK_SET);
|
lseek(fd, off, SEEK_SET);
|
||||||
read(fd,&header,sizeof(header));
|
read(fd,&header,sizeof(header));
|
||||||
/* First time through, check validity of OMF header [v1.1] */
|
/* First time through, check validity of OMF header [v1.1] */
|
||||||
if (off == 0 && notOMF(&header)) {
|
if (off == 0 && notOMF(&header)) {
|
||||||
printf("Not a recognized OMF file\n");
|
printf("Note: %s is not a recognized OMF file\n", fname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lseek(fd, off+header.DISPNAME+10, SEEK_SET);
|
lseek(fd, off+header.DISPNAME+10, SEEK_SET);
|
||||||
|
@ -233,22 +238,39 @@ int stsize = 0;
|
||||||
name[0] = header.LABLEN;
|
name[0] = header.LABLEN;
|
||||||
read(fd, name+1, header.LABLEN);
|
read(fd, name+1, header.LABLEN);
|
||||||
}
|
}
|
||||||
prntAscii(name+1,name[0]);
|
printf("%s",fname);
|
||||||
|
i = strlen(fname);
|
||||||
|
while (i++ < 20) putchar(' ');
|
||||||
|
|
||||||
kind = header.KIND & 0x1F;
|
kind = header.KIND & 0x1F;
|
||||||
if (kind < 0x13) {
|
switch (kind) {
|
||||||
printf(" %s segment (%02X) %06lX bytes",
|
case 0x00:
|
||||||
segTypes[kind],kind,header.LENGTH);
|
if (decimal_output)
|
||||||
/* Check code segment for stack allocation [v1.1] */
|
printf(" %s %8ld ", segTypes[kind],header.LENGTH);
|
||||||
if (kind == 0) {
|
else
|
||||||
/* Position to beginning of data */
|
printf(" %s 0x%06lX ", segTypes[kind],header.LENGTH);
|
||||||
lseek(fd, off+header.DISPDATA, SEEK_SET);
|
/* Check code segment for stack allocation [v1.1] */
|
||||||
/* Check the code */
|
/* Position to beginning of data */
|
||||||
checkCodeStack(fd);
|
lseek(fd, off+header.DISPDATA, SEEK_SET);
|
||||||
}
|
/* Check the code */
|
||||||
|
checkCodeStack(fd);
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
case 0x02:
|
||||||
|
case 0x04:
|
||||||
|
case 0x08:
|
||||||
|
case 0x10:
|
||||||
|
case 0x12:
|
||||||
|
if (decimal_output)
|
||||||
|
printf(" %s %8ld ", segTypes[kind],header.LENGTH);
|
||||||
|
else
|
||||||
|
printf(" %s 0x%06lX ", segTypes[kind],header.LENGTH);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf(" unknown (0x%02X) ", kind);
|
||||||
|
}
|
||||||
|
prntAscii(name+1,name[0]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
|
||||||
if (kind == 0x12) /* got a stack segment */
|
|
||||||
stsize = (word) header.LENGTH;
|
|
||||||
/* In OMF version 1, the first field is a block count */
|
/* In OMF version 1, the first field is a block count */
|
||||||
if (header.VERSION == 1)
|
if (header.VERSION == 1)
|
||||||
off += (header.BYTECNT * 512);
|
off += (header.BYTECNT * 512);
|
||||||
|
@ -257,21 +279,16 @@ int stsize = 0;
|
||||||
/* Check for unusual case that causes infinite loop [v1.1] */
|
/* Check for unusual case that causes infinite loop [v1.1] */
|
||||||
if (header.BYTECNT == 0) break;
|
if (header.BYTECNT == 0) break;
|
||||||
}
|
}
|
||||||
/* The default stack size for programs is 4096 */
|
|
||||||
if (stsize)
|
|
||||||
printf("\tStack size: %d\n", stsize);
|
|
||||||
else
|
|
||||||
printf("\tDefault stack size: 4096\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage(void)
|
void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"usage: lseg filename...\n");
|
fprintf(stderr,"usage: lseg [-d] filename...\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Added for 2.0.6: Check on how much stack space a C program uses. */
|
/* [v1.1] Check on how much stack space a C program uses. */
|
||||||
#if defined(__STACK_CHECK__)
|
#if defined(__STACK_CHECK__)
|
||||||
#ifndef _GNO_GNO_H_
|
#ifndef _GNO_GNO_H_
|
||||||
#include <gno/gno.h>
|
#include <gno/gno.h>
|
||||||
|
@ -287,21 +304,41 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int exit_status=0;
|
int exit_status=0;
|
||||||
|
int ch;
|
||||||
|
|
||||||
#if defined(__STACK_CHECK__)
|
#if defined(__STACK_CHECK__)
|
||||||
_beginStackCheck();
|
_beginStackCheck();
|
||||||
atexit(report_stack);
|
atexit(report_stack);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc == 1) usage();
|
/* Get option, if present */
|
||||||
argv++; argc--;
|
while ((ch = getopt(argc, argv, "d")) != EOF) {
|
||||||
|
switch(ch) {
|
||||||
|
case 'd':
|
||||||
|
decimal_output = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv = argv + optind;
|
||||||
|
|
||||||
|
/* Make sure that at least one filename was provided */
|
||||||
|
if (argc < 1) usage();
|
||||||
|
|
||||||
|
/* Print header [v1.1] */
|
||||||
|
printf(
|
||||||
|
"File Type Size Stack Name\n");
|
||||||
|
printf(
|
||||||
|
"-------------------- ------------------ -------- ------ ----------------\n");
|
||||||
|
|
||||||
while (argc-- > 0) {
|
while (argc-- > 0) {
|
||||||
if ((fd = open(*argv, O_RDONLY)) < 0) {
|
if ((fd = open(*argv, O_RDONLY)) < 0) {
|
||||||
exit_status = 1;
|
exit_status = 1;
|
||||||
warn("%s", *argv);
|
warn("%s", *argv);
|
||||||
} else {
|
} else {
|
||||||
printf("File: %s\n",*argv);
|
scanOMF(fd,*argv);
|
||||||
scanOMF(fd);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
++argv;
|
++argv;
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Resources for version and comment
|
* Resources for version and comment
|
||||||
*
|
* $Id: lseg.rez,v 1.3 1997/09/28 16:41:13 gdr Exp $
|
||||||
* $Id: lseg.rez,v 1.2 1997/09/26 06:36:01 gdr Exp $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PROG "lseg"
|
#define PROG "lseg"
|
||||||
#define DESC "List segments of an Object Module Format file."
|
#define DESC "List segments of an Object Module Format file."
|
||||||
|
|
||||||
|
@ -14,7 +12,7 @@
|
||||||
*/
|
*/
|
||||||
resource rVersion (1, purgeable3) {
|
resource rVersion (1, purgeable3) {
|
||||||
{ 1, 1, 0, /* Version 1.1.0 */
|
{ 1, 1, 0, /* Version 1.1.0 */
|
||||||
beta, /* development|alpha|beta|final|release */
|
release, /* development|alpha|beta|final|release */
|
||||||
0 }, /* non-final release number */
|
0 }, /* non-final release number */
|
||||||
verUS, /* Country */
|
verUS, /* Country */
|
||||||
PROG, /* Program name */
|
PROG, /* Program name */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user