* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)savenl.c 8.2 (Berkeley) 5/24/94";
* savenl - routines for saving namelist and line number information
* This module contains the routines that make pi dump a namelist
* at the end of the object file. We do this by first creating
* four temporary files in "startnlfile". One temp file contains
* the string table, one the symbol table, one the file name
* information and one the line number information.
* Prior to generation of the code for a statement the "lineno"
* routine is called to dump the line number and current object
* address. At the end of each block "savenl" is called to dump
* the strings and symbol structures.
* At the end of execution "copynlfile" is called and it copies
* the temp files onto the end of the obj file.
* In case of error, "removenlfile" is called to destroy the temp files.
* The only other changes to pi are in calling these routines from
* and the rest of the file
#include "../pdx/object.h"
#include "../pdx/object/objsym.rep"
#include "../pdx/mappings.h"
#include "../pdx/mappings/filetab.h"
LOCAL
char symname
[] = "/tmp/obj.symXXXXXX";
LOCAL
char strname
[] = "/tmp/obj.strXXXXXX";
LOCAL
char filesname
[] = "/tmp/obj.filesXXXXXX";
LOCAL
char linesname
[] = "/tmp/obj.linesXXXXXX";
* create temporary files for the namelist info
(void) mktemp(filesname
);
(void) mktemp(linesname
);
symfp
= fopen(symname
, "w");
strfp
= fopen(strname
, "w");
filesfp
= fopen(filesname
, "w");
linesfp
= fopen(linesname
, "w");
if (symfp
==NULL
|| strfp
==NULL
|| filesfp
==NULL
|| linesfp
==NULL
) {
fprintf(stderr
, "can't create /tmp/obj");
* now copy the temp files back to obj; strings, symbols, file names, and lines
* There's some efficiency garbage here that uses straight system
* calls rather than standard I/O library calls.
int symfd
, strfd
, filesfd
, linesfd
;
(void) fclose((FILE *) symfp
);
(void) fclose((FILE *) strfp
);
(void) fclose((FILE *) filesfp
);
(void) fclose((FILE *) linesfp
);
symfd
= open(symname
, 0);
strfd
= open(strname
, 0);
filesfd
= open(filesname
, 0);
linesfd
= open(linesname
, 0);
if (symfd
< 0 || strfd
< 0 || filesfd
< 0 || linesfd
< 0) {
fprintf(stderr
, "sync error on /tmp/obj");
if (lseek(ofil
, (off_t
)0, 2) == -1)
perror("copynlfile: lseek"), panic("copynlfile");
write(ofil
, (char *) (&nlhdr
), sizeof(nlhdr
));
n
= read(strfd
, buff
, BUFSIZ
- sizeof(nlhdr
));
while ((n
= read(fd
, buff
, BUFSIZ
)) > 0) {
r
= nlsize
+ sizeof(nlhdr
);
#define isblock(s) (s->class == FUNC || s->class == PROC)
#define isbuiltin(s) ((s->nl_block&037) == 0 && isblock(s))
#define symno(p) (p==NULL ? 0 : nloff(p))
struct nl nl
[], *nlp
, ntab
[], *nlact
;
putblock("main program");
nlsp
= (struct nls
*) nlact
;
for (p
= nlp
; p
!= to
;) {
if (p
== nlsp
->nls_low
) {
if (nlsp
== ((struct nls
*) &ntab
[0]))
if (isbuiltin(p
) || symno(p
) == 0) {
nlsize
+= sizeof(OBJSYM
) + sizeof(int);
(void) putw(symno(p
), symfp
);
s
->strindex
= nlhdr
.stringsize
;
s
->oblkno
= (p
->nl_block
&037);
s
->typno
= symno(p
->type
);
s
->chno
= symno(p
->chain
);
s
->osymvalue
.orangev
.lower
= p
->range
[0];
s
->osymvalue
.orangev
.upper
= p
->range
[1];
s
->osymvalue
.ofuncv
.codeloc
= p
->value
[NL_ENTLOC
];
} else if (p
->class == RECORD
|| p
->class == VARNT
) {
s
->osymvalue
.ovarnt
.vtorecno
= symno(p
->ptr
[2]);
s
->osymvalue
.ovarnt
.vtagno
= symno(p
->ptr
[3]);
fwrite((char *) s
, sizeof(*s
), 1, symfp
);
* Dump a line number and the current object location counter.
* To save space the difference from the previous line number and offset
* (one byte each) is dumped.
LOCAL
int olc
= HEADER_BYTES
;
nlsize
+= sizeof(OBJLINE
);
info
.separate
.lineincr
= line
- oline
;
info
.separate
.addrincr
= ((unsigned short) (lc
- olc
));
(void) putw((int) info
.together
, linesfp
);
* put out a file name entry, including:
* the current line number for the new file
* the current location counter
* the string table address of the file name
* an index into the current line number information
nlsize
+= sizeof(FILETAB
);
ft
.addr
= ((LINENO
) lc
- HEADER_BYTES
);
ft
.filename
= (char *) nlhdr
.stringsize
;
ft
.lineindex
= nlhdr
.nlines
;
fwrite((char *) (&ft
), sizeof(ft
), 1, filesfp
);
* put out a dummy symbol at the beginning of a block
nlsize
+= sizeof(OBJSYM
) + sizeof(int);
zerosym
.strindex
= nlhdr
.stringsize
;
fwrite((char *) (&zerosym
), sizeof(zerosym
), 1, symfp
);
* put out a string to the string table file
for (p
= s
; *p
!= '\0'; p
++) {
nlhdr
.stringsize
+= (p
- s
+ 1);