recording file death

This commit is contained in:
K. Richard Pixley
1992-12-08 04:53:09 +00:00
parent 181ba9ee43
commit a362ee2363
7 changed files with 0 additions and 977 deletions

View File

@ -1,127 +0,0 @@
1) You should be aware that GNU-C, as with any other decent compiler,
will do things when optimization is turned on that you may not expect.
Sometimes intermediate results are not written to variables, if they are only
used in one place, and sometimes variables that are not used at all will not be
written to the symbol table. Also, parameters to inline functions are often
inaccessible. You can see the assembly code equivalent by using KP7 in the
debugger, and from this you can tell if in fact a variable should have the
value that you expect. You can find out if a variable lives withing a register
by doing a 'show symbol/addr'.
2) Overly complex data types, such as:
int (*(*(*(*(*(* sarr6)[1])[1])[2])[3])[4])[5];
will not be debugged properly, since the debugging record overflows an internal
debugger buffer. gcc-as will convert these to *void as far as the debugger
symbol table is concerned, which will avoid any problems, and the assembler
will give you a message informing you that this has happened.
3) You must, of course, compile and link with /debug. If you link
without debug, you still get traceback table in the executable, but there is no
symbol table for variables.
4) Included in the patches to VMS.C are fixes to two bugs that are
unrelated to the changes that I have made. One of these made it impossible to
debug small programs sometimes, and the other caused the debugger to become
confused about which routine it was in, and give this incorrect info in
tracebacks.
5) If you are using the GNU-C++ compiler, you should modify the
compiler driver file GNU_CC:[000000]GCC.COM (or GXX.COM). If you have a
seperate GXX.COM, then you need to change one line in GXX.COM to:
$ if f$locate("D",p2) .ne. P2_Length then Debug = " ""-G0"""
Notice zero---> ^
If you are using a GCC.COM that does both C and C++, add the following lines to
GCC.COM:
$!
$! Use old style debugging records for VMS
$!
$ if (Debug.nes."" ).and. Plus then Debug = " ""-G0"""
after the variables Plus and Debug are set. The reason for this, is that C++
compiler by default generates debugging records that are more complex,
with many new syntactical elements that allow for the new features of the
language. The -G0 switch tells the C++ compiler to use the old style debugging
records. Until the debugger understands C++ there is not any point to try and
use the expanded syntax.
6) When you have nested scopes, i.e.:
main(){
int i;
{int i;
{int i;
};};}
and you say "EXAM i" the debugger needs to figure out which variable you
actually want to reference. I have arranged things to define a block to the
debugger when you use brackets to enter a new scope, so in the example above,
the variables would be described as:
TEST\main\i
TEST\main\$0\i
TEST\main\$0\$0\i
At each level, the block name is a number with a dollar sign prefix, the
numbers start with 0 and count upward. When you say EXAM i, the debugger looks
at the current PC, and decides which block it is currently in. It works from
the innermost level outward until it finds a block that has the variable "i"
defined. You can always specify the scope explicitly.
7) With C++, there can be a lot of inline functions, and it would be
rather restrictive to force the user to debug the program by converting all of
the inline functions to normal functions. What I have done is to essentially
"add" (with the debugger) source lines from the include files that contain the
inline functions. Thus when you step into an inline function it appears as if
you have called the function, and you can examine variables and so forth.
There are several *very* important differences, however. First of all, since
there is no function call involved, you cannot step over the inline function
call - you always step into it. Secondly, since the same source lines are used
in many locations, there is a seperate copy of the source for *each* usage.
Without this, breakpoints do not work, since we must have a 1-to-1 mapping
between source lines and PC.
Since you cannot step over inline function calls, it can be a real pain
if you are not really interested in what is going on for that function call.
What I have done is to use the "-D" switch for the assembler to toggle the
following behavior. With the "-D" switch, all inline functions are included in
the object file, and you can debug everything. Without the "-D" switch
(default case with VMS implementation), inline functions are included *only* if
they did not come from system header files (i.e. from GNU_CC_INCLUDE: or
GNU_GXX_INCLUDE:). Thus, without the switch the user only debugs his/her own
inline functions, and not the system ones. (This is especially useful if you do
a lot of stream I/O in C++). This probably will not provide enough granularity
for many users, but for now this is still somewhat experimental, and I would
like to reflect upon it and get some feedback before I go any further.
Possible solutions include an interactive prompting, a logical name, or a new
command line option in gcc.c (which is then passed through somehow to the guts
of the assembler).
The inline functions from header files appear after the source code
for the source file. This has the advantage that the source file itself is
numbered with the same line numbers that you get with an editor. In addition,
the entire header file is not included, since the assembler makes a list of
the min and max source lines that are used, and only includes those lines from
the first to the last actually used. (It is easy to change it to include the
whole file).
8) When you are debugging C++ objects, the object "this" is refered to
as "$this". Actually, the compiler writes it as ".this", but the period is
not good for the debugger, so I have a routine to convert it to a $. (It
actually converts all periods to $, but only for variables, since this was
intended to allow us to access "this".
9) If you use the asm("...") keyword for global symbols, you will not
be able to see that symbol with the debugger. The reason is that there are two
records for the symbol stored in the data structures of the assembler. One
contains the info such as psect number and offset, and the other one contains
the information having to do with the data type of the variable. In order to
debug as symbol, you need to be able to coorelate these records, and the only
way to do this is by name. The record with the storage attributes will take
the name used in the asm directive, and the record that specifies the data type
has the actual variable name, and thus when you use the asm directive to change
a variable name, the symbol becomes invisible.
10) Older versions of the compiler ( GNU-C 1.37.92 and earlier) place
global constants in the text psect. This is unfortunate, since to the linker
this appears to be an entry point. I sent a patch to the compiler to RMS,
which will generate a .const section for these variables, and patched the
assembler to put these variables into a psect just like that for normal
variables, except that they are marked NOWRT. static constants are still
placed in the text psect, since there is no need for any external access.

View File

@ -1,289 +0,0 @@
/* gdb_block.c - Deal with GDB blocks
Copyright (C) 1987 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* Implements .gdbblk, .gdbbeg, .gdbend concepts.
* No other modules need to know the details of these concepts.
*
* During assembly, note the addresses of block beginnings and ends.
* Each block has a begin-address, an end-address, a number, and
* a place in the GDB symbol file to place the 2 addresses.
* Block numbers are 0, 1, ... with no gaps.
*
* During assembly, we don't actually know the addresses, so they are
* expressed as {frag-address + offset-in-frag}.
*
* gdb_block_begin ()
* Call once before using this package.
*
* gdb_block_beg (number, frag, offset)
* Note a block beginning.
*
* gdb_block_end (number, frag, offset)
* Note a block end.
*
* gdb_block_position (block_number, pos)
* Remember, after assembly, to copy a structure containing
* the beginning and ending addresses of block number
* block_number into the gdb file, starting at position pos.
*
* gdb_block_emit (block_number, where_in_gdb_symbol_file)
* Emit a block begin/end locations to a place in the GDB symbol
* file.
*
* uses:
* xmalloc()
* gdb_alter()
*/
#include "as.h"
/*
* malloc() calls are considered expensive. So ...
*
* We remember blocks by making a tree, and each block number has a leaf.
* The tree is 3 levels, and we don't allocate interior nodes until they
* are needed. Both leaves and interior nodes are allocated in lumps,
* which should save on malloc() calls. Due to the way we break up a
* block number to navigate through the tree, we insist that lumps of
* memory contain a power of 2 items each. Powers of 2 may differ
* for different levels of tree.
*/
/*
* A block number:
*
* +---------------+---------------+---------------+
* | | | |
* | Z2-part bits | Z1-part bits | Z0-part bits |
* | | | |
* +---------------+---------------+---------------+
*
* High order Low order
*
* "Z" is short for "siZe".
*/
#define LOG_2_Z0 (8) /* How many bits are in Z0 part? */
#define LOG_2_Z1 (8) /* How many bits are in Z1 part? */
#define LOG_2_Z2 (8) /* How many bits are in Z2 part? */
#define BLOCK_NUMBER_LIMIT (1 << (LOG_2_Z0 + LOG_2_Z1 + LOG_2_Z2))
/* What is the first block number that is */
/* "too big"? */
struct gdb_block
{
fragS * begin_frag;
fragS * end_frag;
long int begin_where_in_frag;
long int end_where_in_frag;
long int position; /* In GDB symbols file. */
};
typedef struct gdb_block node_0_T [1 << LOG_2_Z0];
typedef node_0_T * node_1_T [1 << LOG_2_Z1];
typedef node_1_T * node_2_T [1 << LOG_2_Z2];
static long int highest_block_number_seen;
static node_2_T * root; /* 3 level tree of block locations. */
static node_2_T * new_2 ();
char * xmalloc();
void gdb_alter();
void
gdb_block_begin ()
{
root = new_2 ();
highest_block_number_seen = -1;
}
static node_0_T *
new_0 ()
{
register node_0_T * place;
place = (node_0_T *) xmalloc ((long)sizeof(node_0_T));
bzero ((char *)place, sizeof(node_0_T));
return (place);
}
static node_1_T *
new_1 ()
{
register node_1_T * place;
place = (node_1_T *) xmalloc ((long)sizeof(node_1_T));
bzero ((char *)place, sizeof(node_1_T));
return (place);
}
static node_2_T *
new_2 ()
{
register node_2_T * place;
place = (node_2_T *) xmalloc ((long)sizeof(node_2_T));
bzero ((char *)place, sizeof(node_2_T));
return (place);
}
static struct gdb_block *
find (block_number)
register long int block_number;
{
register node_1_T ** pp_1;
register node_0_T ** pp_0;
register struct gdb_block * b;
register int index0;
register int index1;
register int index2;
#ifdef SUSPECT
if (block_number >= BLOCK_NUMBER_LIMIT)
{
as_fatal ("gdb_block: Block number = %ld.", block_number);
}
#endif
index2 = block_number >> (LOG_2_Z0 + LOG_2_Z1);
index1 = block_number >> (LOG_2_Z0) & ((1 << LOG_2_Z1) - 1);
index0 = block_number & ((1 << LOG_2_Z0) - 1);
pp_1 = * root + index2;
if (* pp_1 == 0)
{
* pp_1 = new_1 ();
}
pp_0 = ** pp_1 + index1;
if (* pp_0 == 0)
{
* pp_0 = new_0 ();
}
b = ** pp_0 + index0;
return (b);
}
static struct gdb_block *
find_create (block_number)
long int block_number;
{
if (highest_block_number_seen < block_number)
{
highest_block_number_seen = block_number;
}
return (find (block_number));
}
void
gdb_block_beg (block_number, frag, offset)
long int block_number;
fragS * frag;
long int offset;
{
struct gdb_block * pointer;
pointer = find_create (block_number);
#ifdef SUSPECT
if (pointer -> begin_frag != 0)
{
as_warn( "Overwriting begin_frag for block # %ld.", block_number );
}
if (pointer -> begin_where_in_frag != 0)
{
as_warn( "Overwriting begin_where_in_frag for block # %ld.", block_number );
}
#endif
pointer -> begin_frag = frag;
pointer -> begin_where_in_frag = offset;
}
void
gdb_block_end (block_number, frag, offset)
long int block_number;
fragS * frag;
long int offset;
{
struct gdb_block * pointer;
pointer = find_create (block_number);
#ifdef SUSPECT
if (pointer -> end_frag != 0)
{
as_warn( "Overwriting end_frag for block # %ld.", block_number );
}
if (pointer -> end_where_in_frag != 0)
{
as_warn( "Overwriting end_where_in_frag for block # %ld.", block_number );
}
#endif
pointer -> end_frag = frag;
pointer -> end_where_in_frag = offset;
}
void
gdb_block_position (block_number, pos)
long int block_number;
long int pos;
{
struct gdb_block * pointer;
pointer = find_create (block_number);
if (pointer -> position != 0)
{
as_warn( "Overwriting old position %ld. in block #%ld.",
pointer -> position, block_number);
}
pointer -> position = pos;
}
void
gdb_block_emit ()
{
long int block_number;
struct gdb_block * b;
for (block_number = 0;
block_number <= highest_block_number_seen;
block_number ++)
{
b = find (block_number);
if (b -> begin_frag)
{
gdb_alter (b -> position,
(long int)
(b -> begin_frag -> fr_address + b -> begin_where_in_frag));
}
if (b -> end_frag)
{
gdb_alter (b -> position + sizeof( long int ),
(long int)
(b -> end_frag -> fr_address + b -> end_where_in_frag));
}
}
}
/* end: gdb_block.c */

View File

@ -1,80 +0,0 @@
/* gdb_file.c -o/s specific-
Copyright (C) 1987 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
static long file_len;
static FILE *file;
extern long get_len();
void
gdb_file_begin ()
{
}
void
gdb_file_end()
{
}
long int /* Open file, return size. 0: failed. */
gdb_file_size (filename)
char *filename;
{
struct stat stat_buf;
void as_perror();
file= fopen (filename, "r");
if (file == (FILE *)NULL)
{
as_perror ("Can't read GDB symbolic information file", filename);
file_len=0;
} else {
(void)fstat (fileno(file), &stat_buf);
file_len=stat_buf . st_size;
}
return ((long int)file_len );
}
void /* Read the file, don't return if failed. */
gdb_file_read (buffer, filename)
char * buffer;
char * filename;
{
register off_t size_wanted;
void as_perror();
size_wanted = file_len;
if (fread (buffer, size_wanted, 1, file) != 1)
{
as_perror ("Can't read GDB symbolic info file", filename);
as_fatal ("Failed to read %ld. chars of GDB symbolic information",
size_wanted);
}
if (fclose(file)==EOF)
{
as_perror ("Can't close GDB symbolic info file", filename);
as_fatal ("I quit in disgust");
}
}
/* end: gdb_file.c */

View File

@ -1,241 +0,0 @@
/* gdb-lines.c -- Deal with source lines for GDB format
Copyright (C) 1989, Free Software Foundation.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "as.h"
#include "obstack.h"
#include "frags.h"
/* This is a souce file that we're storing .gdbline information about */
/* .gdbline refers to files by numbers. We keep a linked list of them
We store a list of vectors for each file. Each element of the vector
contains a line-number, a frag, and an offset within the frag. */
struct g_line_file {
int gdb_line_file_file_number; /* fnum */
int gdb_line_file_number_of_vectors; /* nv */
long gdb_line_table_offset; /* taboff */
struct g_line_vector *gdb_line_file_vectors; /* vec */
struct g_line_file *gdb_line_file_next_file; /* nfile */
};
/* In order to save on space (We expect there to be LOTS of lines), we
store line-number/address pairs in bunches of MAX_LINES_PER_VECTOR
(originally fifty). Each vector descriptor contains
gdb_line_number_of_lines the number of line-number/address pairs
actually in this vector.
gdb_line_lines The actual vector.
gdb_line_next_vector The next vector descriptor in the linked list.
*/
struct g_line_vector {
int gdb_line_number_of_lines; /* nlines */
struct g_line *gdb_line_lines; /* lines */
struct g_line_vector *gdb_line_next_vector; /* nvec */
};
/* A .gdbline wants to store a line-number/address pair. Unfortunatly, we
don't know addresses yet, so we store frag/offset which we can use to
generate the address at write-out time. */
struct g_line {
int gdb_line_line_number; /* lno */
fragS *gdb_line_frag; /* lfrag */
int gdb_line_offset; /* loff */
};
/* The following is stolen from (gdb's? (or is it gcc's?) symseg.h file.
These structures describe the format for the line# symbolic info in
the gdb symbolic info file. This info is not particularly useful,
except to show what we're writing into. . . */
/* Source-file information.
This describes the relation between source files and line numbers
and addresses in the program text. */
struct sourcevector
{
int length; /* Number of source files described */
struct source *source[1]; /* Descriptions of the files */
};
/* Line number and address of one line. */
struct line
{
int linenum;
int address;
};
/* All the information on one source file. */
struct source
{
char *name; /* Name of file */
int nlines; /* Number of lines that follow */
struct line lines[1]; /* Information on each line */
};
/* End of text from symseg.h */
struct g_line_file *first_file;
struct g_line_file *add_file();
struct g_line_vector *add_vector();
#define MAX_LINES_PER_VECTOR 50 /* lpv */
/* We've been told that the current address corresponds to line LINENO in
file FILE_NUMBER */
void
gdb_line(file_number,lineno)
int file_number;
int lineno;
{
struct g_line_file *f;
struct g_line_vector *v;
struct g_line *line;
for(f=first_file;f;f=f->gdb_line_file_next_file)
if(f->gdb_line_file_file_number==file_number)
break;
if(!f) f=add_file(file_number);
v=f->gdb_line_file_vectors;
if(!v || v->gdb_line_number_of_lines==MAX_LINES_PER_VECTOR)
v=add_vector(f);
line= &(v->gdb_line_lines)[v->gdb_line_number_of_lines];
v->gdb_line_number_of_lines++;
line->gdb_line_line_number=lineno;
line->gdb_line_frag= frag_now;
line->gdb_line_offset=obstack_next_free(&frags)-frag_now->fr_literal;
}
/* We've been told where to store the .line table for file FILE_NUMBER */
void
gdb_line_tab(file_number,offset)
int file_number;
int offset;
{
struct g_line_file *f;
for(f=first_file;f;f=f->gdb_line_file_next_file)
if(f->gdb_line_file_file_number==file_number)
break;
if(!f) f=add_file(file_number);
if(f->gdb_line_table_offset)
as_warn("Ignoring duplicate .linetab for file %d",file_number);
else
f->gdb_line_table_offset=offset;
}
/* We've got a file (FILE_NUMBER) that we haven't heard about before. Create
an entry for it, etc. . . */
struct g_line_file *
add_file(file_number)
{
struct g_line_file *f;
f=(struct g_line_file *)xmalloc(sizeof(struct g_line_file));
f->gdb_line_file_file_number=file_number;
f->gdb_line_table_offset = 0;
f->gdb_line_file_number_of_vectors=0;
f->gdb_line_file_vectors=(struct g_line_vector *)0;
f->gdb_line_file_next_file=first_file;
first_file=f;
return f;
}
/* The last vector for file F is full. Allocate a new one. */
struct g_line_vector *
add_vector(f)
struct g_line_file *f;
{
struct g_line_vector *tmp_vec;
f->gdb_line_file_number_of_vectors++;
tmp_vec=(struct g_line_vector *)xmalloc(sizeof(struct g_line_vector));
tmp_vec->gdb_line_number_of_lines=0;
tmp_vec->gdb_line_lines=(struct g_line *)xmalloc(MAX_LINES_PER_VECTOR*sizeof(struct g_line));
tmp_vec->gdb_line_next_vector=f->gdb_line_file_vectors;
f->gdb_line_file_vectors=tmp_vec;
return tmp_vec;
}
/* All done. Time to write the stuff out. This should be fun. */
void
gdb_lines_emit()
{
struct g_line_file *f;
struct g_line_vector *v,*old_v,*v_tmp;
struct g_line *current_line_pointer; /* lp */
int n;
int previous_line_number;
long int current_gdb_segment_pos;
unsigned int number_of_things_in_table;
for(f=first_file;f;f=f->gdb_line_file_next_file) {
if(!f->gdb_line_table_offset) {
as_warn("No .gdblinetab given for file %d. Ignoring .gdbline(s) for it.");
continue;
}
/* Reverse the linked list of vectors. Since we built it
last entry first, this puts the first entry at the start
of the list. Thus we can manage to put out low line #s
at the start of the table. . .*/
v_tmp=0;
old_v=0;
for(v=f->gdb_line_file_vectors;v;v=v_tmp) {
v_tmp=v->gdb_line_next_vector;
v->gdb_line_next_vector=old_v;
old_v=v;
}
f->gdb_line_file_vectors=old_v;
/* Start putting stuff at the beginning of the table */
current_gdb_segment_pos=f->gdb_line_table_offset+sizeof(long int);
previous_line_number = -2;
number_of_things_in_table = 0;
/* For every vector in the table: */
for(v=f->gdb_line_file_vectors;v;v=v->gdb_line_next_vector) {
current_line_pointer=v->gdb_line_lines;
/* For every element of every vector */
for(n=v->gdb_line_number_of_lines;n;n--) {
if(current_line_pointer->gdb_line_line_number != previous_line_number + 1) {
/* Write out the line number */
gdb_alter(current_gdb_segment_pos, -(current_line_pointer->gdb_line_line_number));
current_gdb_segment_pos+=sizeof(long int);
number_of_things_in_table++;
}
previous_line_number = current_line_pointer->gdb_line_line_number;
/* And write out the address */
gdb_alter(current_gdb_segment_pos,current_line_pointer->gdb_line_frag->fr_address+current_line_pointer->gdb_line_offset);
current_gdb_segment_pos+=sizeof(long int);
number_of_things_in_table++;
current_line_pointer++;
}
}
gdb_alter(f->gdb_line_table_offset,number_of_things_in_table);
}
}

View File

@ -1,129 +0,0 @@
/* gdb_symbols.c - Deal with symbols for GDB format
Copyright (C) 1987 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* During assembly, note requests to place symbol values in the GDB
* symbol file. When symbol values are known and the symbol file is
* in memory, place the symbol values in the memory image of the file.
*
* This has static data: it is not data_sharable.
*
* gdb_symbols_begin ()
* Call once before using this package.
*
* gdb_symbols_fixup (symbolP, offset_in_file)
* Remember to put the value of a symbol into the GDB file.
*
* gdb_symbols_emit ()
* Perform all the symbol fixups.
*
* uses:
* xmalloc()
* gdb_alter()
*/
#include "as.h"
#include "struc-symbol.h"
#define SYM_GROUP (100) /* We allocate storage in lumps this big. */
struct gdb_symbol /* 1 fixup request. */
{
symbolS * gs_symbol;
long int gs_offset; /* Where in GDB symbol file. */
};
typedef struct gdb_symbol gdb_symbolS;
struct symbol_fixup_group
{
struct symbol_fixup_group * sfg_next;
gdb_symbolS sfg_item [SYM_GROUP];
};
typedef struct symbol_fixup_group symbol_fixup_groupS;
static symbol_fixup_groupS * root;
static short int used; /* # of last slot used. */
/* Counts down from SYM_GROUP. */
static symbol_fixup_groupS * /* Make storage for some more reminders. */
new_sfg ()
{
symbol_fixup_groupS * newP;
char * xmalloc();
newP = (symbol_fixup_groupS *) xmalloc ((long)sizeof(symbol_fixup_groupS));
newP -> sfg_next = root;
used = SYM_GROUP;
root = newP;
return (newP);
}
void
gdb_symbols_begin ()
{
root = 0;
(void)new_sfg ();
}
void /* Build a reminder to put a symbol value */
gdb_symbols_fixup (sy, offset) /* into the GDB symbol file. */
symbolS * sy; /* Which symbol. */
long int offset; /* Where in GDB symbol file. */
{
register symbol_fixup_groupS * p;
register gdb_symbolS * q;
p = root;
know( used >= 0 );
if ( used == 0)
{
p = new_sfg ();
}
q = p -> sfg_item + -- used;
q -> gs_symbol = sy;
q -> gs_offset = offset;
}
void
gdb_symbols_emit () /* Append GDB symbols to object file. */
{
symbol_fixup_groupS * sfgP;
void gdb_alter();
for (sfgP = root; sfgP; sfgP = sfgP -> sfg_next)
{
register gdb_symbolS * gsP;
register gdb_symbolS * limit;
limit = sfgP -> sfg_item +
(sfgP -> sfg_next ? 0 : used);
for (gsP = sfgP -> sfg_item + SYM_GROUP - 1;
gsP >= limit;
gsP --)
{
gdb_alter (gsP -> gs_offset,
(long int) gsP -> gs_symbol -> sy_value);
}
}
}
/* end: gdb_symbols.c */

View File

@ -1,110 +0,0 @@
/* gdb.c -as supports gdb-
Copyright (C) 1987 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This code is independent of the underlying operating system. */
#include "as.h"
static long int size; /* 0 or size of GDB symbol file. */
static char * where; /* Where we put symbol file in memory. */
#define SUSPECT /* JF */
long int /* 0 means don't call gdb_... routines */
gdb_begin (filename) /* because we failed to establish file */
/* in memory. */
char * filename; /* NULL: we have nothing to do. */
{
long int gdb_file_size();
char * xmalloc();
void gdb_file_begin();
void gdb_file_read();
void gdb_block_begin();
void gdb_symbols_begin();
gdb_file_begin();
size = 0;
if (filename && (size = gdb_file_size (filename)))
{
where = xmalloc( (long) size );
gdb_file_read (where, filename); /* Read, then close file. */
gdb_block_begin();
gdb_symbols_begin();
}
return (size);
}
void
gdb_end()
{
void gdb_file_end();
gdb_file_end();
}
void
gdb_emit (filename) /* Append GDB symbols to object file. */
char * filename;
{
void gdb_block_emit();
void gdb_symbols_emit();
void gdb_lines_emit();
void output_file_append();
gdb_block_emit ();
gdb_symbols_emit ();
gdb_lines_emit();
output_file_append (where, size, filename);
}
/*
Notes: We overwrite what was there.
We assume all overwrites are 4-char numbers.
*/
void
gdb_alter (offset, value) /* put value into GDB file + offset. */
long int offset;
long int value;
{
void md_number_to_chars();
#ifdef SUSPECT
if (offset > size - sizeof(long int) || offset < 0)
{
as_warn( "gdb_alter: offset=%d. size=%ld.\n", offset, size );
return;
}
#endif
#ifdef B_OUT
/* Symbol info will be used on the host machine only (only executable
* code is actually downloaded to the i80960). Therefore, leave it
* in host byte order.
*/
*(long int *)(where + offset) = value;
#else
md_number_to_chars (where + offset, value, 4);
#endif
}
/* end: gdb.c */

View File

@ -1 +0,0 @@
char gas960_ver[]= "gas960 1.2, Fri Nov 30 03:01:56 PST 1990";