diff options
author | YamaArashi <shadow962@live.com> | 2016-02-12 10:25:03 -0800 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2016-02-12 10:25:03 -0800 |
commit | 7e65adeeca85a232d11aeaa063227dad72f12e2f (patch) | |
tree | 630112ec27631ea4940f72713ee40d7742c4c295 /gcc | |
parent | e58748cc8494d3df2d83435078e5615641ddd9da (diff) |
misc cleanup
Diffstat (limited to 'gcc')
42 files changed, 10 insertions, 22101 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 39446a0..5e3173a 100755 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -605,7 +605,7 @@ SCHED_CFLAGS = @sched_cflags@ OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \ function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \ varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o regmove.o \ - dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o \ + dwarf2out.o bitmap.o alias.o \ integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o varray.o \ regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o gcse.o \ insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \ @@ -1339,9 +1339,9 @@ fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \ $(RTL_H) # CYGNUS LOCAL live range toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) \ - flags.h input.h insn-attr.h xcoffout.h defaults.h output.h range.h \ - insn-codes.h insn-config.h $(RECOG_H) Makefile toplev.h dwarfout.h \ - dwarf2out.h sdbout.h dbxout.h $(EXPR_H) \ + flags.h input.h insn-attr.h defaults.h output.h range.h \ + insn-codes.h insn-config.h $(RECOG_H) Makefile toplev.h \ + dwarf2out.h $(EXPR_H) \ $(lang_options_files) $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DTARGET_NAME=\"$(target_alias)\" \ @@ -1355,7 +1355,7 @@ rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H) varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \ function.h defaults.h $(EXPR_H) hard-reg-set.h $(REGS_H) \ - xcoffout.h output.h c-pragma.h toplev.h except.h dbxout.h sdbout.h + output.h c-pragma.h toplev.h except.h function.o : function.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ function.h insn-flags.h insn-codes.h $(EXPR_H) $(REGS_H) hard-reg-set.h \ insn-config.h $(RECOG_H) output.h toplev.h except.h @@ -1376,22 +1376,9 @@ explow.o : explow.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ hard-reg-set.h insn-config.h $(EXPR_H) $(RECOG_H) insn-flags.h insn-codes.h optabs.o : optabs.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ insn-flags.h insn-config.h insn-codes.h $(EXPR_H) $(RECOG_H) reload.h -# CYGNUS LOCAL live range -dbxout.o : dbxout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h $(REGS_H) \ - insn-config.h reload.h gstab.h xcoffout.h defaults.h output.h dbxout.h \ - toplev.h range.h -# END CYGNUS LOCAL -sdbout.o : sdbout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h except.h \ - function.h $(EXPR_H) output.h hard-reg-set.h $(REGS_H) defaults.h real.h \ - insn-config.h $(srcdir)/../include/obstack.h xcoffout.h c-pragma.h \ - sdbout.h toplev.h -dwarfout.o : dwarfout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) dwarf.h \ - flags.h insn-config.h reload.h output.h defaults.h toplev.h dwarfout.h dwarf2out.o : dwarf2out.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) dwarf2.h \ flags.h insn-config.h reload.h output.h defaults.h \ hard-reg-set.h $(REGS_H) $(EXPR_H) toplev.h dwarf2out.h dyn-string.h -xcoffout.o : xcoffout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) xcoffout.h \ - flags.h toplev.h output.h dbxout.h emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ except.h function.h $(REGS_H) insn-config.h $(RECOG_H) real.h \ $(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h @@ -1468,8 +1455,8 @@ $(SCHED_PREFIX)sched.o : $(SCHED_PREFIX)sched.c $(CONFIG_H) system.h $(RTL_H) \ # CYGNUS LOCAL live range final.o : final.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h $(REGS_H) \ $(RECOG_H) conditions.h insn-config.h insn-attr.h except.h real.h output.h \ - hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h \ - toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h dbxout.h range.h + hard-reg-set.h insn-flags.h insn-codes.h defaults.h \ + toplev.h reload.h dwarf2out.h range.h # END CYGNUS LOCAL recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) \ $(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \ @@ -1483,20 +1470,6 @@ $(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) \ insn-flags.h output.h insn-attr.h insn-codes.h system.h toplev.h $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(out_file) -# Build auxiliary files that support ecoff format. -mips-tfile: mips-tfile.o version.o $(LIBDEPS) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tfile.o version.o $(LIBS) - -mips-tfile.o : mips-tfile.c $(CONFIG_H) $(RTL_H) system.h machmode.h - -mips-tdump: mips-tdump.o version.o $(LIBDEPS) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tdump.o version.o $(LIBS) - -mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) system.h - -# Build file to support OSF/rose half-pic format. -halfpic.o: halfpic.c $(CONFIG_H) $(RTL_H) $(TREE_H) system.h - # Normally this target is not used; but it is used if you # define ALLOCA=alloca.o. In that case, you must get a suitable alloca.c # from the GNU Emacs distribution. diff --git a/gcc/README-bugs b/gcc/README-bugs deleted file mode 100755 index 06e15bb..0000000 --- a/gcc/README-bugs +++ /dev/null @@ -1,144 +0,0 @@ -The purpose of GCC pretesting is to verify that the new GCC -distribution, about to be released, works properly on your system *with -no change whatever*, when installed following the precise -recommendations that come with the distribution. - -Here are some guidelines on how to do pretesting so as to make it -helpful. All of them follow from common sense together with the -nature of the purpose and the situation. - -* It is absolutely vital that you mention even the smallest change or -departure from the standard sources and installation procedure. - -Otherwise, you are not testing the same program that I wrote. Testing -a different program is usually of no use whatever. It can even cause -trouble if you fail to tell me that you tested some other program -instead of what I know as GCC. I might think that GCC works, when in -fact it has not been properly tried, and might have a glaring fault. - -* Even changing the compilation options counts as a change in the -program. The GCC sources specify which compilation options to use. -Some of them are specified in makefiles, and some in machine-specific -configuration files. - -You have ways to override this--but if you do, then you are not -testing what ordinary users will do. Therefore, when pretesting, it -is vital to test with the default compilation options. - -(It is okay to test with nonstandard options as well as testing with -the standard ones.) - -* The machine and system configuration files of GCC are parts of -GCC. So when you test GCC, you need to do it with the -configuration files that come with GCC. - -If GCC does not come with configuration files for a certain machine, -and you test it with configuration files that don't come with GCC, -this is effectively changing GCC. Because the crucial fact about -the planned release is that, without changes, it doesn't work on that -machine. - -To make GCC work on that machine, I would need to install new -configuration files. That is not out of the question, since it is -safe--it certainly won't break any other machines that already work. -But you will have to rush me the legal papers to give the FSF -permission to use a large piece of text. - -* Look for recommendations for your system. - -You can find these recommendations in the Installation node of the -manual, and in the file INSTALL. (These two files have the same text.) - -These files say which configuration name to use for your machine, so -use the ones that are recommended. If you guess, you might guess -wrong and encounter spurious difficulties. What's more, if you don't -follow the recommendations then you aren't helping to test that its -recommendations are valid. - -These files may describe other things that you need to do to make GCC -work on your machine. If so, you should follow these recommendations -also, for the same reason. - -Also look at the Trouble chapter of the manual for items that -pertain to your machine. - -* Don't delay sending information. - -When you find a problem, please double check it if you can do so -quickly. But don't spend a long time double-checking. A good rule is -always to tell me about every problem on the same day you encounter -it, even if that means you can't find a solution before you report the -problem. - -I'd much rather hear about a problem today and a solution tomorrow -than get both of them tomorrow at the same time. - -* Make each bug report self-contained. - -If you refer back to another message, whether from you or from someone -else, then it will be necessary for anyone who wants to investigate -the bug to find the other message. This may be difficult, it is -probably time-consuming. - -To help me save time, simply copy the relevant parts of any previous -messages into your own bug report. - -In particular, if I ask you for more information because a bug report -was incomplete, it is best to send me the *entire* collection of -relevant information, all together. If you send just the additional -information, that makes me do extra work. There is even a risk that -I won't remember what question you are sending me the answer to. - -* Always be precise when talking about changes you have made. Show -things rather than describing them. Use exact filenames (relative to -the main directory of the distribution), not partial ones. For -example, say "I changed Makefile" rather than "I changed the -makefile". Instead of saying "I defined the MUMBLE macro", send a -diff that shows your change. - -* Always use `diff -c' to make diffs. If you don't include context, -it may be hard for me to figure out where you propose to make the -changes. I might have to ignore your patch because I can't tell what -it means. - -* When you write a fix, keep in mind that I can't install a change -that would break other systems. - -People often suggest fixing a problem by changing machine-independent -files such as toplev.c to do something special that a particular -system needs. Sometimes it is totally obvious that such changes would -break GCC for almost all users. I can't possibly make a change like -that. All I can do is send it back to you and ask you to find a fix -that is safe to install. - -Sometimes people send fixes that *might* be an improvement in -general--but it is hard to be sure of this. I can install such -changes some of the time, but not during pretest, when I am trying to -get a new version to work reliably as quickly as possible. - -The safest changes for me to install are changes to the configuration -files for a particular machine. At least I know those can't create -bugs on other machines. - -* Don't try changing GCC unless it fails to work if you don't change it. - -* Don't even suggest changes that would only make GCC cleaner. -Every change I install could introduce a bug, so I won't install -a change unless I see it is necessary. - -* If you would like to suggest changes for purposes other than fixing -serious bugs, don't wait till pretest time. Instead, send them just -after I make a release. That's the best time for me to install them. - -* In some cases, if you don't follow these guidelines, your -information might still be useful, but I might have to do more work to -make use of it. Unfortunately, I am so far behind in my work that I -just can't get the job done unless you help me to do it efficiently. - - - Thank you - rms - -Local Variables: -mode: text -End: diff --git a/gcc/README-fixinc b/gcc/README-fixinc deleted file mode 100755 index 4b303dd..0000000 --- a/gcc/README-fixinc +++ /dev/null @@ -1,9 +0,0 @@ -This README file is copied into the directory for GCC-only header files -when fixincludes is run by the makefile for GCC. - -Many of the files in this directory were made from the standard system -header files of this system by the shell script `fixincludes'. -They are system-specific, and will not work on any other kind of system. -They are also not part of GCC. The reason for making the files here -is to fix the places in the header files which use constructs -that are incompatible with ANSI C. diff --git a/gcc/bytecode.def b/gcc/bytecode.def deleted file mode 100755 index 5b24df7..0000000 --- a/gcc/bytecode.def +++ /dev/null @@ -1,322 +0,0 @@ -# -*- C -*- -# bytecode.def - definitions of bytecodes for the stack machine. - -# The production of the bytecode interpreter and compiler is -# heavily automated by using this file creatively. - -# Various elementary data types are understood by the bytecode interpreter. -# Q[IU] - quarter word (byte) signed and unsigned integers (char). -# H[IU] - half word signed and unsigned integers (short int, maybe int). -# S[IU] - single word signed and unsigned integers (maybe int, long int). -# D[IU] - double word signed and unsigned integers (long long int). -# SF - single precision floating point (float). -# DF - double precision floating point (double). -# XF - extended precision floating point (long double). -# P - pointer type for address arithmetic and other purposes. - -# The bytecode specification consists of a series of define_operator -# forms, that are parsed by preprocessors to automatically build -# various switch statements. -# define_operator(name, -# <C prototype code for implementing the operator>, -# <list of variations>) -# The <C prototype> is self explanatory. -# The <list of variations> consists of a (parenthesized list) of -# variation items, each of which is in itself a list. A variation -# item consists of a name suffix, the types of the input arguments -# expected on the stack (shallowest item first) and (optionally) the -# types of the output arguments (similarly ordered). Finally, the -# types of the literal arguments (if any) may appear. - -# Substitution in the C prototype code is as follows: -# Substitution happens only after a dollar sign. To get a literal -# dollar sign (why would you ever want one anyway?) use $$. -# $R1 means "result 1" $TR1 means "type name of result one" -# $S1 means "source 1" and similarly with $TS1. -# $L1 means "literal (inline) argument 1" and $TL1 means type thereof. -# - -# Notice that the number following $R doesn't affect the push order; -# it's used only for clarity and orthogonality, although it's checked -# to make sure it doesn't exceed the number of outputs. A $R reference -# results in a push, and represents the result lvalue. E.g. - -# $R1 = 2\, $R2 = 17 -# will expand to: -# INTERP_PUSH($TR1) = 2, INTERP_PUSH($TR2) = 17 -# - -# Opcode 0 should never happen. -define_operator(neverneverland, abort\(\), (())) - -# Stack manipulations. -define_operator(drop, 0, ((, (SI)))) -define_operator(duplicate, 0, ((, (SI), (SI, SI)))) -define_operator(over, 0, ((, (SI), (SI, SI)))) - -# Adjust stack pointer - -define_operator(setstack, 0, ((SI,,,(SI)))) -define_operator(adjstack, 0, ((SI,,,(SI)))) - -# Constants, loads, and stores. -define_operator(const, - $R1 = $L1, - ((QI,, (QI), (QI)), (HI,, (HI), (HI)), - (SI,, (SI), (SI)), (DI,, (DI), (DI)), - (SF,, (SF), (SF)), (DF,, (DF), (DF)), - (XF,, (XF), (XF)), (P,, (P), (P)))) -define_operator(load, - $R1 = *\($TR1 *\) $S1, - ((QI, (P), (QI)), (HI, (P), (HI)), - (SI, (P), (SI)), (DI, (P), (DI)), - (SF, (P), (SF)), (DF, (P), (DF)), - (XF, (P), (XF)), (P, (P), (P)))) -define_operator(store, - *\($TS2 *\) $S1 = $S2, - ((QI, (P, QI)), (HI, (P, HI)), - (SI, (P, SI)), (DI, (P, DI)), - (SF, (P, SF)), (DF, (P, DF)), - (XF, (P, XF)), (P, (P, P)), - (BLK, (SI, BLK, BLK)))) - -# Clear memory block - -define_operator(clear, $S1 + $S2, ((BLK, (SI, BLK)))) - - -# Advance pointer by SI constant - -define_operator(addconst, $R1 = $S1, ((PSI, (P), (P), (SI)))) - - -# newlocalSI is used for creating variable-sized storage during function -# initialization. - -# Create local space, return pointer to block - -define_operator(newlocal, $R1 = $S1, ((SI, (SI), (P)))) - - -# Push the address of a local variable. -define_operator(local, $R1 = locals + $L1, ((P,, (P), (SI)))) - -# Push the address of an argument variable. -define_operator(arg, $R1 = args + $L1, ((P,, (P), (SI)))) - -# Arithmetic conversions. -define_operator(convert, - $R1 = \($TR1\) $S1, - (# Signed integral promotions (sign extensions). - (QIHI, (QI), (HI)), (HISI, (HI), (SI)), (SIDI, (SI), (DI)), - (QISI, (QI), (SI)), - # Unsigned integral promotions (zero extensions). - (QUHU, (QU), (HU)), (HUSU, (HU), (SU)), (SUDU, (SU), (DU)), - (QUSU, (QU), (SU)), - # Floating promotions. - (SFDF, (SF), (DF)), (DFXF, (DF), (XF)), - # Integral truncation. - (HIQI, (HI), (QI)), (SIHI, (SI), (HI)), (DISI, (DI), (SI)), - (SIQI, (SI), (QI)), - # Unsigned truncation. - (SUQU, (SU), (QU)), - # Floating truncation. - (DFSF, (DF), (SF)), (XFDF, (XF), (DF)), - # Integral conversions to floating types. - (SISF, (SI), (SF)), (SIDF, (SI), (DF)), (SIXF, (SI), (XF)), - (SUSF, (SU), (SF)), (SUDF, (SU), (DF)), (SUXF, (SU), (XF)), - (DISF, (DI), (SF)), (DIDF, (DI), (DF)), (DIXF, (DI), (XF)), - (DUSF, (DU), (SF)), (DUDF, (DU), (DF)), (DUXF, (DU), (XF)), - # Floating conversions to integral types. - (SFSI, (SF), (SI)), (DFSI, (DF), (SI)), (XFSI, (XF), (SI)), - (SFSU, (SF), (SU)), (DFSU, (DF), (SU)), (XFSU, (XF), (SU)), - (SFDI, (SF), (DI)), (DFDI, (DF), (DI)), (XFDI, (XF), (DI)), - (SFDU, (SF), (DU)), (DFDU, (DF), (DU)), (XFDU, (XF), (DU)), - # Pointer/integer conversions. - (PSI, (P), (SI)), (SIP, (SI), (P)))) - -# Truth value conversion. These are necessary because conversions of, e.g., -# floating types to integers may not function correctly for large values. -define_operator(convert, - $R1 = !!$S1, - ((SIT, (SI), (T)), (DIT, (DI), (T)), - (SFT, (SF), (T)), (DFT, (DF), (T)), - (XFT, (XF), (T)), (PT, (P), (T)))) - -# Bit field load/store. - -# Load and zero-extend bitfield - -define_operator(zxload, $R1 = $S1, ((BI, (SU, SU, P), (SU)))) - -# Load and sign-extend bitfield - -define_operator(sxload, $R1 = $S1, ((BI, (SU, SU, P), (SI)))) - -# Store integer in bitfield - -define_operator(sstore, $R1 = $S1, ((BI, (SU, SU, P, SI)))) - - -# Binary operations. -define_operator(add, - $R1 = $S1 + $S2, - ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), - (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), - (XF, (XF, XF), (XF)), - (PSI, (P, SI), (P)))) -define_operator(sub, - $R1 = $S1 - $S2, - ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), - (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), - (XF, (XF, XF), (XF)), - (PP, (P, P), (SI)))) -define_operator(mul, - $R1 = $S1 * $S2, - ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), - (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)), - (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), - (XF, (XF, XF), (XF)))) -define_operator(div, - $R1 = $S1 / $S2, - ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), - (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)), - (SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)), - (XF, (XF, XF), (XF)))) -define_operator(mod, - $R1 = $S1 % $S2, - ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)), - (SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)))) -define_operator(and, - $R1 = $S1 & $S2, - ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) -define_operator(ior, - $R1 = $S1 | $S2, - ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) -define_operator(xor, - $R1 = $S1 ^ $S2, - ((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)))) -define_operator(lshift, - $R1 = $S1 << $S2, - ((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)), - (DI, (DI, SI), (DI)), (DU, (DU, SI), (DU)))) -define_operator(rshift, - $R1 = $S1 >> $S2, - ((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)), - (DI, (DI, SI), (DI)), (DU, (DU, SI), (DU)))) -define_operator(lt, - $R1 = $S1 < $S2, - ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), - (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), - (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), - (XF, (XF, XF), (T)), (P, (P, P), (T)))) -define_operator(le, - $R1 = $S1 <= $S2, - ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), - (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), - (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), - (XF, (XF, XF), (T)), (P, (P, P), (T)))) -define_operator(ge, - $R1 = $S1 >= $S2, - ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), - (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), - (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), - (XF, (XF, XF), (T)), (P, (P, P), (T)))) -define_operator(gt, - $R1 = $S1 > $S2, - ((SI, (SI, SI), (T)), (SU, (SU, SU), (T)), - (DI, (DI, DI), (T)), (DU, (DU, DU), (T)), - (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), - (XF, (XF, XF), (T)), (P, (P, P), (T)))) -define_operator(eq, - $R1 = $S1 == $S2, - ((SI, (SI, SI), (T)), (DI, (DI, DI), (T)), - (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), - (XF, (XF, XF), (T)), (P, (P, P), (T)))) -define_operator(ne, - $R1 = $S1 != $S2, - ((SI, (SI, SI), (T)), (DI, (DI, DI), (T)), - (SF, (SF, SF), (T)), (DF, (DF, DF), (T)), - (XF, (XF, XF), (T)), (P, (P, P), (T)))) - -# Unary operations. -define_operator(neg, - $R1 = -$S1, - ((SI, (SI), (SI)), (DI, (DI), (DI)), - (SF, (SF), (SF)), (DF, (DF), (DF)), - (XF, (XF), (XF)))) -define_operator(not, - $R1 = ~$S1, - ((SI, (SI), (SI)), (DI, (DI), (DI)))) -define_operator(not, - $R1 = !$S1, - ((T, (SI), (SI)))) - -# Increment operations. -define_operator(predec, - $R1 = *\($TR1 *\) $S1 -= $S2, - ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), - (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), - (P, (P, SI), (P)), (SF, (P, SF), (SF)), - (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), - (BI, (SU, SU, P, SI), (SI)))) - -define_operator(preinc, - $R1 = *\($TR1 *\) $S1 += $S2, - ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), - (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), - (P, (P, SI), (P)), (SF, (P, SF), (SF)), - (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), - (BI, (SU, SU, P, SI), (SI)))) - -define_operator(postdec, - $R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 -= $S2, - ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), - (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), - (P, (P, SI), (P)), (SF, (P, SF), (SF)), - (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), - (BI, (SU, SU, P, SI), (SI)))) - -define_operator(postinc, - $R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 += $S2, - ((QI, (P, QI), (QI)), (HI, (P, HI), (HI)), - (SI, (P, SI), (SI)), (DI, (P, DI), (DI)), - (P, (P, SI), (P)), (SF, (P, SF), (SF)), - (DF, (P, DF), (DF)), (XF, (P, XF), (XF)), - (BI, (SU, SU, P, SI), (SI)))) - -# Jumps. -define_operator(xjumpif, if \($S1\) pc = code->pc0 + $L1, ((, (T),, (SI)))) -define_operator(xjumpifnot, if \(! $S1\) pc = code->pc0 + $L1, ((, (T),, (SI)))) -define_operator(jump, pc = code->pc0 + $L1, ((,,,(SI)))) - -# This is for GCC2. It jumps to the address on the stack. -define_operator(jump, pc = \(void *\) $S1, ((P,,))) - -# Switches. In order to (eventually) support ranges we provide four different -# varieties of switches. Arguments are the switch index from the stack, the -# bytecode offset of the switch table, the size of the switch table, and -# the default label. -define_operator(caseSI, CASESI\($S1\, $L1\, $L2\, $L3\), ((, (SI),, (SI, SI, SI)))) -define_operator(caseSU, CASESU\($S1\, $L1\, $L2\, $L3\), ((, (SU),, (SI, SI, SI)))) -define_operator(caseDI, CASEDI\($S1\, $L1\, $L2\, $L3\), ((, (DI),, (SI, SI, SI)))) -define_operator(caseDU, CASEDU\($S1\, $L1\, $L2\, $L3\), ((, (DU),, (SI, SI, SI)))) - -# Procedure call. -# Stack arguments are (deepest first): -# procedure arguments in reverse order. -# pointer to the place to hold the return value. -# address of the call description vector. -# pointer to the procedure to be called. -define_operator(call, CALL\($S1\, $S2\, $S3\, sp\), ((, (P, P, P)))) - -# Procedure return. -# Pushes on interpreter stack: -# value of retptr (pointer to return value storage slot) -define_operator(return, $R1 = retptr, ((P,,(P)))) - -# Really return. -define_operator(ret, return, (())) - -# Print an obnoxious line number. -define_operator(linenote, fprintf\(stderr\, "%d\\n"\, $L1\), ((,,,(SI)))) diff --git a/gcc/bytecode.h b/gcc/bytecode.h deleted file mode 100755 index a029f93..0000000 --- a/gcc/bytecode.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Bytecode definitions for GNU C-compiler. - Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -extern int output_bytecode; -extern int stack_depth; -extern int max_stack_depth; - -/* Emit DI constant according to target machine word ordering */ - -#define bc_emit_bytecode_DI_const(CST) \ -{ int opcode; \ - opcode = (WORDS_BIG_ENDIAN \ - ? TREE_INT_CST_HIGH (CST) \ - : TREE_INT_CST_LOW (CST)); \ - bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ - opcode = (WORDS_BIG_ENDIAN \ - ? TREE_INT_CST_LOW (CST) \ - : TREE_INT_CST_HIGH (CST)); \ - bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ -} - -extern void bc_expand_expr (); -extern void bc_output_data_constructor (); -extern void bc_store_field (); -extern void bc_load_bit_field (); -extern void bc_store_bit_field (); -extern void bc_push_offset_and_size (); -extern void bc_init_mode_to_code_map (); - -/* These are just stubs, so the compiler will compile for targets - that aren't yet supported by the bytecode generator. */ - -#ifndef TARGET_SUPPORTS_BYTECODE - -#define MACHINE_SEG_ALIGN 1 -#define INT_ALIGN 1 -#define PTR_ALIGN 1 -#define NAMES_HAVE_UNDERSCORES -#define BC_NOP (0) -#define BC_GLOBALIZE_LABEL(FP, NAME) BC_NOP -#define BC_OUTPUT_COMMON(FP, NAME, SIZE, ROUNDED) BC_NOP -#define BC_OUTPUT_BSS(FP, NAME, SIZE, ROUNDED) BC_NOP -#define BC_OUTPUT_LOCAL(FP, NAME, SIZE, ROUNDED) BC_NOP -#define BC_OUTPUT_ALIGN(FP, ALIGN) BC_NOP -#define BC_OUTPUT_LABEL(FP, NAME) BC_NOP -#define BC_OUTPUT_SKIP(FP, SIZE) BC_NOP -#define BC_OUTPUT_LABELREF(FP, NAME) BC_NOP -#define BC_OUTPUT_FLOAT(FP, VAL) BC_NOP -#define BC_OUTPUT_DOUBLE(FP, VAL) BC_NOP -#define BC_OUTPUT_BYTE(FP, VAL) BC_NOP -#define BC_OUTPUT_FILE ASM_OUTPUT_FILE -#define BC_OUTPUT_ASCII ASM_OUTPUT_ASCII -#define BC_OUTPUT_IDENT ASM_OUTPUT_IDENT -#define BCXSTR(RTX) ((RTX)->bc_label) -#define BC_WRITE_FILE(FP) BC_NOP -#define BC_WRITE_SEGSYM(SEGSYM, FP) BC_NOP -#define BC_WRITE_RELOC_ENTRY(SEGRELOC, FP, OFFSET) BC_NOP -#define BC_START_BYTECODE_LINE(FP) BC_NOP -#define BC_WRITE_BYTECODE(SEP, VAL, FP) BC_NOP -#define BC_WRITE_RTL(R, FP) BC_NOP -#define BC_EMIT_TRAMPOLINE(TRAMPSEG, CALLINFO) BC_NOP -#define VALIDATE_STACK BC_NOP - -#endif /* !TARGET_SUPPORTS_BYTECODE */ diff --git a/gcc/bytetypes.h b/gcc/bytetypes.h deleted file mode 100755 index f915669..0000000 --- a/gcc/bytetypes.h +++ /dev/null @@ -1,35 +0,0 @@ -/* These should come from genemit */ - -/* Use __signed__ in case compiling with -traditional. */ - -typedef __signed__ char QItype; -typedef unsigned char QUtype; -typedef __signed__ short int HItype; -typedef unsigned short int HUtype; -typedef __signed__ long int SItype; -typedef unsigned long int SUtype; -typedef __signed__ long long int DItype; -typedef unsigned long long int DUtype; -typedef float SFtype; -typedef double DFtype; -typedef long double XFtype; -typedef char *Ptype; -typedef int Ttype; - - -typedef union stacktype -{ - QItype QIval; - QUtype QUval; - HItype HIval; - HUtype HUval; - SItype SIval; - SUtype SUval; - DItype DIval; - DUtype DUval; - SFtype SFval; - DFtype DFval; - XFtype XFval; - Ptype Pval; - Ttype Tval; -} stacktype; diff --git a/gcc/dbxout.c b/gcc/dbxout.c deleted file mode 100755 index ac55120..0000000 --- a/gcc/dbxout.c +++ /dev/null @@ -1,2927 +0,0 @@ -/* Output dbx-format symbol table information from GNU compiler. - Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Output dbx-format symbol table data. - This consists of many symbol table entries, each of them - a .stabs assembler pseudo-op with four operands: - a "name" which is really a description of one symbol and its type, - a "code", which is a symbol defined in stab.h whose name starts with N_, - an unused operand always 0, - and a "value" which is an address or an offset. - The name is enclosed in doublequote characters. - - Each function, variable, typedef, and structure tag - has a symbol table entry to define it. - The beginning and end of each level of name scoping within - a function are also marked by special symbol table entries. - - The "name" consists of the symbol name, a colon, a kind-of-symbol letter, - and a data type number. The data type number may be followed by - "=" and a type definition; normally this will happen the first time - the type number is mentioned. The type definition may refer to - other types by number, and those type numbers may be followed - by "=" and nested definitions. - - This can make the "name" quite long. - When a name is more than 80 characters, we split the .stabs pseudo-op - into two .stabs pseudo-ops, both sharing the same "code" and "value". - The first one is marked as continued with a double-backslash at the - end of its "name". - - The kind-of-symbol letter distinguished function names from global - variables from file-scope variables from parameters from auto - variables in memory from typedef names from register variables. - See `dbxout_symbol'. - - The "code" is mostly redundant with the kind-of-symbol letter - that goes in the "name", but not entirely: for symbols located - in static storage, the "code" says which segment the address is in, - which controls how it is relocated. - - The "value" for a symbol in static storage - is the core address of the symbol (actually, the assembler - label for the symbol). For a symbol located in a stack slot - it is the stack offset; for one in a register, the register number. - For a typedef symbol, it is zero. - - If DEBUG_SYMS_TEXT is defined, all debugging symbols must be - output while in the text section. - - For more on data type definitions, see `dbxout_type'. */ - -#include "config.h" -#include "system.h" - -#include "tree.h" -#include "rtl.h" -#include "flags.h" -#include "regs.h" -#include "insn-config.h" -#include "reload.h" -#include "defaults.h" -#include "output.h" /* ASM_OUTPUT_SOURCE_LINE may refer to sdb functions. */ -/* CYGNUS LOCAL LRS */ -#include "range.h" -/* END CYGNUS LOCAL */ -#include "dbxout.h" -#include "toplev.h" - -#ifdef XCOFF_DEBUGGING_INFO -#include "xcoffout.h" -#endif - -#ifndef ASM_STABS_OP -#define ASM_STABS_OP ".stabs" -#endif - -#ifndef ASM_STABN_OP -#define ASM_STABN_OP ".stabn" -#endif - -#ifndef DBX_TYPE_DECL_STABS_CODE -#define DBX_TYPE_DECL_STABS_CODE N_LSYM -#endif - -#ifndef DBX_STATIC_CONST_VAR_CODE -#define DBX_STATIC_CONST_VAR_CODE N_FUN -#endif - -#ifndef DBX_REGPARM_STABS_CODE -#define DBX_REGPARM_STABS_CODE N_RSYM -#endif - -#ifndef DBX_REGPARM_STABS_LETTER -#define DBX_REGPARM_STABS_LETTER 'P' -#endif - -/* This is used for parameters passed by invisible reference in a register. */ -#ifndef GDB_INV_REF_REGPARM_STABS_LETTER -#define GDB_INV_REF_REGPARM_STABS_LETTER 'a' -#endif - -#ifndef DBX_MEMPARM_STABS_LETTER -#define DBX_MEMPARM_STABS_LETTER 'p' -#endif - -#ifndef FILE_NAME_JOINER -#define FILE_NAME_JOINER "/" -#endif - -/* Nonzero means if the type has methods, only output debugging - information if methods are actually written to the asm file. This - optimization only works if the debugger can detect the special C++ - marker. */ - -#define MINIMAL_DEBUG 1 - -#ifdef NO_DOLLAR_IN_LABEL -#ifdef NO_DOT_IN_LABEL -#undef MINIMAL_DEBUG -#define MINIMAL_DEBUG 0 -#endif -#endif - -char *getpwd (); - -/* Typical USG systems don't have stab.h, and they also have - no use for DBX-format debugging info. */ - -#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) - -static int flag_minimal_debug = MINIMAL_DEBUG; - -/* Nonzero if we have actually used any of the GDB extensions - to the debugging format. The idea is that we use them for the - first time only if there's a strong reason, but once we have done that, - we use them whenever convenient. */ - -static int have_used_extensions = 0; - -/* Number for the next N_SOL filename stabs label. The number 0 is reserved - for the N_SO filename stabs label. */ - -static int source_label_number = 1; - -#ifdef DEBUG_SYMS_TEXT -#define FORCE_TEXT text_section (); -#else -#define FORCE_TEXT -#endif - -/* If there is a system stab.h, use it. Otherwise, use our own. */ - -#if defined (USG) || !defined (HAVE_STAB_H) -#include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */ -#else -#include <stab.h> - -/* This is a GNU extension we need to reference in this file. */ -#ifndef N_CATCH -#define N_CATCH 0x54 -#endif -#endif - -#ifdef __GNU_STAB__ -#define STAB_CODE_TYPE enum __stab_debug_code -#else -#define STAB_CODE_TYPE int -#endif - -/* 1 if PARM is passed to this function in memory. */ - -#define PARM_PASSED_IN_MEMORY(PARM) \ - (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM) - -/* A C expression for the integer offset value of an automatic variable - (N_LSYM) having address X (an RTX). */ -#ifndef DEBUGGER_AUTO_OFFSET -#define DEBUGGER_AUTO_OFFSET(X) \ - (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) -#endif - -/* A C expression for the integer offset value of an argument (N_PSYM) - having address X (an RTX). The nominal offset is OFFSET. */ -#ifndef DEBUGGER_ARG_OFFSET -#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET) -#endif - -/* Stream for writing to assembler file. */ - -static FILE *asmfile; - -/* Last source file name mentioned in a NOTE insn. */ - -static char *lastfile; - -/* CYGNUS LOCAL LRS */ -/* Current label number for the live range labels. */ - -static int range_current; - -/* Maximum number used for range markers. */ -int range_max_number; -static int range_max_number_for_parms; -/* END CYGNUS LOCAL */ - -/* Current working directory. */ - -static char *cwd; - -enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED}; - -/* Structure recording information about a C data type. - The status element says whether we have yet output - the definition of the type. TYPE_XREF says we have - output it as a cross-reference only. - The file_number and type_number elements are used if DBX_USE_BINCL - is defined. */ - -struct typeinfo -{ - enum typestatus status; -#ifdef DBX_USE_BINCL - int file_number; - int type_number; -#endif -}; - -/* Vector recording information about C data types. - When we first notice a data type (a tree node), - we assign it a number using next_type_number. - That is its index in this vector. */ - -struct typeinfo *typevec; - -/* Number of elements of space allocated in `typevec'. */ - -static int typevec_len; - -/* In dbx output, each type gets a unique number. - This is the number for the next type output. - The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */ - -static int next_type_number; - -#ifdef DBX_USE_BINCL - -/* When using N_BINCL in dbx output, each type number is actually a - pair of the file number and the type number within the file. - This is a stack of input files. */ - -struct dbx_file -{ - struct dbx_file *next; - int file_number; - int next_type_number; -}; - -/* This is the top of the stack. */ - -static struct dbx_file *current_file; - -/* This is the next file number to use. */ - -static int next_file_number; - -#endif /* DBX_USE_BINCL */ - -/* In dbx output, we must assign symbol-blocks id numbers - in the order in which their beginnings are encountered. - We output debugging info that refers to the beginning and - end of the ranges of code in each block - with assembler labels LBBn and LBEn, where n is the block number. - The labels are generated in final, which assigns numbers to the - blocks in the same way. */ - -static int next_block_number; - -/* These variables are for dbxout_symbol to communicate to - dbxout_finish_symbol. - current_sym_code is the symbol-type-code, a symbol N_... define in stab.h. - current_sym_value and current_sym_addr are two ways to address the - value to store in the symtab entry. - current_sym_addr if nonzero represents the value as an rtx. - If that is zero, current_sym_value is used. This is used - when the value is an offset (such as for auto variables, - register variables and parms). */ - -static STAB_CODE_TYPE current_sym_code; -static int current_sym_value; -static rtx current_sym_addr; - -/* Number of chars of symbol-description generated so far for the - current symbol. Used by CHARS and CONTIN. */ - -static int current_sym_nchars; - -/* Report having output N chars of the current symbol-description. */ - -#define CHARS(N) (current_sym_nchars += (N)) - -/* Break the current symbol-description, generating a continuation, - if it has become long. */ - -#ifndef DBX_CONTIN_LENGTH -#define DBX_CONTIN_LENGTH 80 -#endif - -#if DBX_CONTIN_LENGTH > 0 -#define CONTIN \ - do {if (current_sym_nchars > DBX_CONTIN_LENGTH) dbxout_continue ();} while (0) -#else -#define CONTIN -#endif - -void dbxout_types (); -void dbxout_args (); -void dbxout_symbol (); - -#if defined(ASM_OUTPUT_SECTION_NAME) -static void dbxout_function_end PROTO((void)); -#endif -static void dbxout_typedefs PROTO((tree)); -static void dbxout_type_index PROTO((tree)); -#if DBX_CONTIN_LENGTH > 0 -static void dbxout_continue PROTO((void)); -#endif -static void dbxout_type_fields PROTO((tree)); -static void dbxout_type_method_1 PROTO((tree, char *)); -static void dbxout_type_methods PROTO((tree)); -static void dbxout_range_type PROTO((tree)); -static void dbxout_type PROTO((tree, int, int)); -static void print_int_cst_octal PROTO((tree)); -static void print_octal PROTO((unsigned HOST_WIDE_INT, int)); -static void dbxout_type_name PROTO((tree)); -static void dbxout_symbol_location PROTO((tree, tree, char *, rtx)); -/* CYGNUS LOCAL LRS */ -static void dbxout_symbol_name PROTO((tree, char *, int, int)); -static void dbxout_live_range_alias PROTO((tree)); -static void dbxout_live_range_parms PROTO((tree, int)); -/* END CYGNUS LOCAL */ -static void dbxout_prepare_symbol PROTO((tree)); -static void dbxout_finish_symbol PROTO((tree)); -static void dbxout_block PROTO((tree, int, tree)); -static void dbxout_really_begin_function PROTO((tree)); - -#if defined(ASM_OUTPUT_SECTION_NAME) -static void -dbxout_function_end () -{ - static int scope_labelno = 0; - char lscope_label_name[100]; - /* Convert Ltext into the appropriate format for local labels in case - the system doesn't insert underscores in front of user generated - labels. */ - ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno); - ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Lscope", scope_labelno); - scope_labelno++; - - /* By convention, GCC will mark the end of a function with an N_FUN - symbol and an empty string. */ - fprintf (asmfile, "%s \"\",%d,0,0,", ASM_STABS_OP, N_FUN); - assemble_name (asmfile, lscope_label_name); - fputc ('-', asmfile); - assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); - fprintf (asmfile, "\n"); -} -#endif /* ! NO_DBX_FUNCTION_END */ - -/* At the beginning of compilation, start writing the symbol table. - Initialize `typevec' and output the standard data types of C. */ - -void -dbxout_init (asm_file, input_file_name, syms) - FILE *asm_file; - char *input_file_name; - tree syms; -{ - char ltext_label_name[100]; - - asmfile = asm_file; - - typevec_len = 100; - typevec = (struct typeinfo *) xmalloc (typevec_len * sizeof typevec[0]); - bzero ((char *) typevec, typevec_len * sizeof typevec[0]); - - /* Convert Ltext into the appropriate format for local labels in case - the system doesn't insert underscores in front of user generated - labels. */ - ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); - - /* Put the current working directory in an N_SO symbol. */ -#ifndef DBX_WORKING_DIRECTORY /* Only some versions of DBX want this, - but GDB always does. */ - if (use_gnu_debug_info_extensions) -#endif - { - if (!cwd && (cwd = getpwd ()) && (!*cwd || cwd[strlen (cwd) - 1] != '/')) - { - char *wdslash = xmalloc (strlen (cwd) + sizeof (FILE_NAME_JOINER)); - sprintf (wdslash, "%s%s", cwd, FILE_NAME_JOINER); - cwd = wdslash; - } - if (cwd) - { -#ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY - DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asmfile, cwd); -#else /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ - fprintf (asmfile, "%s ", ASM_STABS_OP); - output_quoted_string (asmfile, cwd); - fprintf (asmfile, ",%d,0,0,%s\n", N_SO, <ext_label_name[1]); -#endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ - } - } - -#ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME - /* This should NOT be DBX_OUTPUT_SOURCE_FILENAME. That - would give us an N_SOL, and we want an N_SO. */ - DBX_OUTPUT_MAIN_SOURCE_FILENAME (asmfile, input_file_name); -#else /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */ - /* We include outputting `Ltext:' here, - because that gives you a way to override it. */ - /* Used to put `Ltext:' before the reference, but that loses on sun 4. */ - fprintf (asmfile, "%s ", ASM_STABS_OP); - output_quoted_string (asmfile, input_file_name); - fprintf (asmfile, ",%d,0,0,%s\n", - N_SO, <ext_label_name[1]); - text_section (); - ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0); -#endif /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */ - - /* Possibly output something to inform GDB that this compilation was by - GCC. It's easier for GDB to parse it when after the N_SO's. This - is used in Solaris 2. */ -#ifdef ASM_IDENTIFY_GCC_AFTER_SOURCE - ASM_IDENTIFY_GCC_AFTER_SOURCE (asmfile); -#endif - - lastfile = input_file_name; - - next_type_number = 1; - next_block_number = 2; - -#ifdef DBX_USE_BINCL - current_file = (struct dbx_file *) xmalloc (sizeof *current_file); - current_file->next = NULL; - current_file->file_number = 0; - current_file->next_type_number = 1; - next_file_number = 1; -#endif - - /* Make sure that types `int' and `char' have numbers 1 and 2. - Definitions of other integer types will refer to those numbers. - (Actually it should no longer matter what their numbers are. - Also, if any types with tags have been defined, dbxout_symbol - will output them first, so the numbers won't be 1 and 2. That - happens in C++. So it's a good thing it should no longer matter). */ - -#ifdef DBX_OUTPUT_STANDARD_TYPES - DBX_OUTPUT_STANDARD_TYPES (syms); -#else - dbxout_symbol (TYPE_NAME (integer_type_node), 0); - dbxout_symbol (TYPE_NAME (char_type_node), 0); -#endif - - /* Get all permanent types that have typedef names, - and output them all, except for those already output. */ - - dbxout_typedefs (syms); -} - -/* Output any typedef names for types described by TYPE_DECLs in SYMS, - in the reverse order from that which is found in SYMS. */ - -static void -dbxout_typedefs (syms) - tree syms; -{ - if (syms) - { - dbxout_typedefs (TREE_CHAIN (syms)); - if (TREE_CODE (syms) == TYPE_DECL) - { - tree type = TREE_TYPE (syms); - if (TYPE_NAME (type) - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && TYPE_SIZE (type) != NULL_TREE - && ! TREE_ASM_WRITTEN (TYPE_NAME (type))) - dbxout_symbol (TYPE_NAME (type), 0); - } - } -} - -/* Change to reading from a new source file. Generate a N_BINCL stab. */ - -void -dbxout_start_new_source_file (filename) - char *filename; -{ -#ifdef DBX_USE_BINCL - struct dbx_file *n = (struct dbx_file *) xmalloc (sizeof *n); - - n->next = current_file; - n->file_number = next_file_number++; - n->next_type_number = 1; - current_file = n; - fprintf (asmfile, "%s ", ASM_STABS_OP); - output_quoted_string (asmfile, filename); - fprintf (asmfile, ",%d,0,0,0\n", N_BINCL); -#endif -} - -/* Revert to reading a previous source file. Generate a N_EINCL stab. */ - -void -dbxout_resume_previous_source_file () -{ -#ifdef DBX_USE_BINCL - struct dbx_file *next; - - fprintf (asmfile, "%s %d,0,0,0\n", ASM_STABN_OP, N_EINCL); - next = current_file->next; - free (current_file); - current_file = next; -#endif -} - -/* Output debugging info to FILE to switch to sourcefile FILENAME. */ - -void -dbxout_source_file (file, filename) - FILE *file; - char *filename; -{ - char ltext_label_name[100]; - - if (filename && (lastfile == 0 || strcmp (filename, lastfile))) - { -#ifdef DBX_OUTPUT_SOURCE_FILENAME - DBX_OUTPUT_SOURCE_FILENAME (file, filename); -#else - ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", - source_label_number); - fprintf (file, "%s ", ASM_STABS_OP); - output_quoted_string (file, filename); - fprintf (file, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]); - if (current_function_decl != NULL_TREE - && DECL_SECTION_NAME (current_function_decl) != NULL_TREE) - ; /* Don't change section amid function. */ - else - text_section (); - ASM_OUTPUT_INTERNAL_LABEL (file, "Ltext", source_label_number); - source_label_number++; -#endif - lastfile = filename; - } -} - -/* Output a line number symbol entry into output stream FILE, - for source file FILENAME and line number LINENO. */ - -void -dbxout_source_line (file, filename, lineno) - FILE *file; - char *filename; - int lineno; -{ - dbxout_source_file (file, filename); - -#ifdef ASM_OUTPUT_SOURCE_LINE - ASM_OUTPUT_SOURCE_LINE (file, lineno); -#else - fprintf (file, "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE, lineno); -#endif -} - -/* At the end of compilation, finish writing the symbol table. - Unless you define DBX_OUTPUT_MAIN_SOURCE_FILE_END, the default is - to do nothing. */ - -void -dbxout_finish (file, filename) - FILE *file; - char *filename; -{ -#ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END - DBX_OUTPUT_MAIN_SOURCE_FILE_END (file, filename); -#endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */ -} - -/* Output the index of a type. */ - -static void -dbxout_type_index (type) - tree type; -{ -#ifndef DBX_USE_BINCL - fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type)); - CHARS (3); -#else - struct typeinfo *t = &typevec[TYPE_SYMTAB_ADDRESS (type)]; - fprintf (asmfile, "(%d,%d)", t->file_number, t->type_number); - CHARS (7); -#endif -} - -#if DBX_CONTIN_LENGTH > 0 -/* Continue a symbol-description that gets too big. - End one symbol table entry with a double-backslash - and start a new one, eventually producing something like - .stabs "start......\\",code,0,value - .stabs "...rest",code,0,value */ - -static void -dbxout_continue () -{ -#ifdef DBX_CONTIN_CHAR - fprintf (asmfile, "%c", DBX_CONTIN_CHAR); -#else - fprintf (asmfile, "\\\\"); -#endif - dbxout_finish_symbol (NULL_TREE); - fprintf (asmfile, "%s \"", ASM_STABS_OP); - current_sym_nchars = 0; -} -#endif /* DBX_CONTIN_LENGTH > 0 */ - -/* Subroutine of `dbxout_type'. Output the type fields of TYPE. - This must be a separate function because anonymous unions require - recursive calls. */ - -static void -dbxout_type_fields (type) - tree type; -{ - tree tem; - /* Output the name, type, position (in bits), size (in bits) of each - field. */ - for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) - { - /* Omit here local type decls until we know how to support them. */ - if (TREE_CODE (tem) == TYPE_DECL) - continue; - /* Omit fields whose position or size are variable. */ - else if (TREE_CODE (tem) == FIELD_DECL - && (TREE_CODE (DECL_FIELD_BITPOS (tem)) != INTEGER_CST - || TREE_CODE (DECL_SIZE (tem)) != INTEGER_CST)) - continue; - /* Omit here the nameless fields that are used to skip bits. */ - else if (DECL_IGNORED_P (tem)) - continue; - else if (TREE_CODE (tem) != CONST_DECL) - { - /* Continue the line if necessary, - but not before the first field. */ - if (tem != TYPE_FIELDS (type)) - { - CONTIN; - } - - if (use_gnu_debug_info_extensions - && flag_minimal_debug - && TREE_CODE (tem) == FIELD_DECL - && DECL_VIRTUAL_P (tem) - && DECL_ASSEMBLER_NAME (tem)) - { - have_used_extensions = 1; - CHARS (3 + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (tem))); - fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile); - dbxout_type (DECL_FCONTEXT (tem), 0, 0); - fprintf (asmfile, ":"); - dbxout_type (TREE_TYPE (tem), 0, 0); - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))); - fputc (';', asmfile); - continue; - } - - if (DECL_NAME (tem)) - { - fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem))); - CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem))); - } - else - { - fprintf (asmfile, ":"); - CHARS (2); - } - - if (use_gnu_debug_info_extensions - && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem) - || TREE_CODE (tem) != FIELD_DECL)) - { - have_used_extensions = 1; - putc ('/', asmfile); - putc ((TREE_PRIVATE (tem) ? '0' - : TREE_PROTECTED (tem) ? '1' : '2'), - asmfile); - CHARS (2); - } - - dbxout_type ((TREE_CODE (tem) == FIELD_DECL - && DECL_BIT_FIELD_TYPE (tem)) - ? DECL_BIT_FIELD_TYPE (tem) - : TREE_TYPE (tem), 0, 0); - - if (TREE_CODE (tem) == VAR_DECL) - { - if (TREE_STATIC (tem) && use_gnu_debug_info_extensions) - { - char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)); - have_used_extensions = 1; - fprintf (asmfile, ":%s;", name); - CHARS (strlen (name)); - } - else - { - /* If TEM is non-static, GDB won't understand it. */ - fprintf (asmfile, ",0,0;"); - } - } - else if (TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST) - { - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))); - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (DECL_SIZE (tem))); - fputc (';', asmfile); - } - CHARS (23); - } - } -} - -/* Subroutine of `dbxout_type_methods'. Output debug info about the - method described DECL. DEBUG_NAME is an encoding of the method's - type signature. ??? We may be able to do without DEBUG_NAME altogether - now. */ - -static void -dbxout_type_method_1 (decl, debug_name) - tree decl; - char *debug_name; -{ - char c1 = 'A', c2; - - if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE) - c2 = '?'; - else /* it's a METHOD_TYPE. */ - { - tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))); - /* A for normal functions. - B for `const' member functions. - C for `volatile' member functions. - D for `const volatile' member functions. */ - if (TYPE_READONLY (TREE_TYPE (firstarg))) - c1 += 1; - if (TYPE_VOLATILE (TREE_TYPE (firstarg))) - c1 += 2; - - if (DECL_VINDEX (decl)) - c2 = '*'; - else - c2 = '.'; - } - - fprintf (asmfile, ":%s;%c%c%c", debug_name, - TREE_PRIVATE (decl) ? '0' : TREE_PROTECTED (decl) ? '1' : '2', c1, c2); - CHARS (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)) + 6 - - (debug_name - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)))); - if (DECL_VINDEX (decl)) - { - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (DECL_VINDEX (decl))); - fputc (';', asmfile); - dbxout_type (DECL_CONTEXT (decl), 0, 0); - fprintf (asmfile, ";"); - CHARS (8); - } -} - -/* Subroutine of `dbxout_type'. Output debug info about the methods defined - in TYPE. */ - -static void -dbxout_type_methods (type) - register tree type; -{ - /* C++: put out the method names and their parameter lists */ - tree methods = TYPE_METHODS (type); - tree type_encoding; - register tree fndecl; - register tree last; - char formatted_type_identifier_length[16]; - register int type_identifier_length; - - if (methods == NULL_TREE) - return; - - type_encoding = DECL_NAME (TYPE_NAME (type)); - -#if 0 - /* C++: Template classes break some assumptions made by this code about - the class names, constructor names, and encodings for assembler - label names. For now, disable output of dbx info for them. */ - { - char *ptr = IDENTIFIER_POINTER (type_encoding); - /* This should use index. (mrs) */ - while (*ptr && *ptr != '<') ptr++; - if (*ptr != 0) - { - static int warned; - if (!warned) - warned = 1; - return; - } - } -#endif - - type_identifier_length = IDENTIFIER_LENGTH (type_encoding); - - sprintf(formatted_type_identifier_length, "%d", type_identifier_length); - - if (TREE_CODE (methods) != TREE_VEC) - fndecl = methods; - else if (TREE_VEC_ELT (methods, 0) != NULL_TREE) - fndecl = TREE_VEC_ELT (methods, 0); - else - fndecl = TREE_VEC_ELT (methods, 1); - - while (fndecl) - { - tree name = DECL_NAME (fndecl); - int need_prefix = 1; - - /* Group together all the methods for the same operation. - These differ in the types of the arguments. */ - for (last = NULL_TREE; - fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last)); - fndecl = TREE_CHAIN (fndecl)) - /* Output the name of the field (after overloading), as - well as the name of the field before overloading, along - with its parameter list */ - { - /* This is the "mangled" name of the method. - It encodes the argument types. */ - char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)); - int show_arg_types = 0; - - CONTIN; - - last = fndecl; - - if (DECL_IGNORED_P (fndecl)) - continue; - - if (flag_minimal_debug) - { - char marker; - - /* We can't optimize a method which uses an anonymous - class, because the debugger will not be able to - associate the arbitrary class name with the actual - class. */ -#ifndef NO_DOLLAR_IN_LABEL - marker = '$'; -#else - marker = '.'; -#endif - if (strchr (debug_name, marker)) - show_arg_types = 1; - /* Detect ordinary methods because their mangled names - start with the operation name. */ - else if (!strncmp (IDENTIFIER_POINTER (name), debug_name, - IDENTIFIER_LENGTH (name))) - { - debug_name += IDENTIFIER_LENGTH (name); - if (debug_name[0] == '_' && debug_name[1] == '_') - { - char *method_name = debug_name + 2; - char *length_ptr = formatted_type_identifier_length; - /* Get past const and volatile qualifiers. */ - while (*method_name == 'C' || *method_name == 'V') - method_name++; - /* Skip digits for length of type_encoding. */ - while (*method_name == *length_ptr && *length_ptr) - length_ptr++, method_name++; - if (! strncmp (method_name, - IDENTIFIER_POINTER (type_encoding), - type_identifier_length)) - method_name += type_identifier_length; - debug_name = method_name; - } - } - /* Detect constructors by their style of name mangling. */ - else if (debug_name[0] == '_' && debug_name[1] == '_') - { - char *ctor_name = debug_name + 2; - char *length_ptr = formatted_type_identifier_length; - while (*ctor_name == 'C' || *ctor_name == 'V') - ctor_name++; - /* Skip digits for length of type_encoding. */ - while (*ctor_name == *length_ptr && *length_ptr) - length_ptr++, ctor_name++; - if (!strncmp (IDENTIFIER_POINTER (type_encoding), ctor_name, - type_identifier_length)) - debug_name = ctor_name + type_identifier_length; - } - /* The other alternative is a destructor. */ - else - show_arg_types = 1; - - /* Output the operation name just once, for the first method - that we output. */ - if (need_prefix) - { - fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name)); - CHARS (IDENTIFIER_LENGTH (name) + 2); - need_prefix = 0; - } - } - - dbxout_type (TREE_TYPE (fndecl), 0, show_arg_types); - - dbxout_type_method_1 (fndecl, debug_name); - } - if (!need_prefix) - { - putc (';', asmfile); - CHARS (1); - } - } -} - -/* Emit a "range" type specification, which has the form: - "r<index type>;<lower bound>;<upper bound>;". - TYPE is an INTEGER_TYPE. */ - -static void -dbxout_range_type (type) - tree type; -{ - fprintf (asmfile, "r"); - if (TREE_TYPE (type)) - dbxout_type (TREE_TYPE (type), 0, 0); - else if (TREE_CODE (type) != INTEGER_TYPE) - dbxout_type (type, 0, 0); /* E.g. Pascal's ARRAY [BOOLEAN] of INTEGER */ - else - { - /* Traditionally, we made sure 'int' was type 1, and builtin types - were defined to be sub-ranges of int. Unfortunately, this - does not allow us to distinguish true sub-ranges from integer - types. So, instead we define integer (non-sub-range) types as - sub-ranges of themselves. This matters for Chill. If this isn't - a subrange type, then we want to define it in terms of itself. - However, in C, this may be an anonymous integer type, and we don't - want to emit debug info referring to it. Just calling - dbxout_type_index won't work anyways, because the type hasn't been - defined yet. We make this work for both cases by checked to see - whether this is a defined type, referring to it if it is, and using - 'int' otherwise. */ - if (TYPE_SYMTAB_ADDRESS (type) != 0) - dbxout_type_index (type); - else - dbxout_type_index (integer_type_node); - } - if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST) - { - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))); - } - else - fprintf (asmfile, ";0"); - if (TYPE_MAX_VALUE (type) - && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST) - { - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))); - fputc (';', asmfile); - } - else - fprintf (asmfile, ";-1;"); -} - -/* Output a reference to a type. If the type has not yet been - described in the dbx output, output its definition now. - For a type already defined, just refer to its definition - using the type number. - - If FULL is nonzero, and the type has been described only with - a forward-reference, output the definition now. - If FULL is zero in this case, just refer to the forward-reference - using the number previously allocated. - - If SHOW_ARG_TYPES is nonzero, we output a description of the argument - types for a METHOD_TYPE. */ - -static void -dbxout_type (type, full, show_arg_types) - tree type; - int full; - int show_arg_types; -{ - register tree tem; - static int anonymous_type_number = 0; - - /* If there was an input error and we don't really have a type, - avoid crashing and write something that is at least valid - by assuming `int'. */ - if (type == error_mark_node) - type = integer_type_node; - else - { - /* Try to find the "main variant" with the same name but not const - or volatile. (Since stabs does not distinguish const and volatile, - there is no need to make them separate types. But types with - different names are usefully distinguished.) */ - - for (tem = TYPE_MAIN_VARIANT (type); tem; tem = TYPE_NEXT_VARIANT (tem)) - if (!TYPE_READONLY (tem) && !TYPE_VOLATILE (tem) - && TYPE_NAME (tem) == TYPE_NAME (type)) - { - type = tem; - break; - } - if (TYPE_NAME (type) - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type))) - full = 0; - } - - if (TYPE_SYMTAB_ADDRESS (type) == 0) - { - /* Type has no dbx number assigned. Assign next available number. */ - TYPE_SYMTAB_ADDRESS (type) = next_type_number++; - - /* Make sure type vector is long enough to record about this type. */ - - if (next_type_number == typevec_len) - { - typevec - = (struct typeinfo *) xrealloc (typevec, - typevec_len * 2 * sizeof typevec[0]); - bzero ((char *) (typevec + typevec_len), - typevec_len * sizeof typevec[0]); - typevec_len *= 2; - } - -#ifdef DBX_USE_BINCL - typevec[TYPE_SYMTAB_ADDRESS (type)].file_number - = current_file->file_number; - typevec[TYPE_SYMTAB_ADDRESS (type)].type_number - = current_file->next_type_number++; -#endif - } - - /* Output the number of this type, to refer to it. */ - dbxout_type_index (type); - -#ifdef DBX_TYPE_DEFINED - if (DBX_TYPE_DEFINED (type)) - return; -#endif - - /* If this type's definition has been output or is now being output, - that is all. */ - - switch (typevec[TYPE_SYMTAB_ADDRESS (type)].status) - { - case TYPE_UNSEEN: - break; - case TYPE_XREF: - /* If we have already had a cross reference, - and either that's all we want or that's the best we could do, - don't repeat the cross reference. - Sun dbx crashes if we do. */ - if (! full || TYPE_SIZE (type) == 0 - /* No way in DBX fmt to describe a variable size. */ - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - return; - break; - case TYPE_DEFINED: - return; - } - -#ifdef DBX_NO_XREFS - /* For systems where dbx output does not allow the `=xsNAME:' syntax, - leave the type-number completely undefined rather than output - a cross-reference. If we have already used GNU debug info extensions, - then it is OK to output a cross reference. This is necessary to get - proper C++ debug output. */ - if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && ! use_gnu_debug_info_extensions) - /* We must use the same test here as we use twice below when deciding - whether to emit a cross-reference. */ - if ((TYPE_NAME (type) != 0 - && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_IGNORED_P (TYPE_NAME (type))) - && !full) - || TYPE_SIZE (type) == 0 - /* No way in DBX fmt to describe a variable size. */ - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - { - typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF; - return; - } -#endif - - /* Output a definition now. */ - - fprintf (asmfile, "="); - CHARS (1); - - /* Mark it as defined, so that if it is self-referent - we will not get into an infinite recursion of definitions. */ - - typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_DEFINED; - - if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_ORIGINAL_TYPE (TYPE_NAME (type))) - { - dbxout_type (DECL_ORIGINAL_TYPE (TYPE_NAME (type)), 0, 0); - return; - } - - switch (TREE_CODE (type)) - { - case VOID_TYPE: - case LANG_TYPE: - /* For a void type, just define it as itself; ie, "5=5". - This makes us consider it defined - without saying what it is. The debugger will make it - a void type when the reference is seen, and nothing will - ever override that default. */ - dbxout_type_index (type); - break; - - case INTEGER_TYPE: - if (type == char_type_node && ! TREE_UNSIGNED (type)) - { - /* Output the type `char' as a subrange of itself! - I don't understand this definition, just copied it - from the output of pcc. - This used to use `r2' explicitly and we used to - take care to make sure that `char' was type number 2. */ - fprintf (asmfile, "r"); - dbxout_type_index (type); - fprintf (asmfile, ";0;127;"); - } - /* This used to check if the type's precision was more than - HOST_BITS_PER_WIDE_INT. That is wrong since gdb uses a - long (it has no concept of HOST_BITS_PER_WIDE_INT). */ - else if (use_gnu_debug_info_extensions - && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node) - || TYPE_PRECISION (type) >= HOST_BITS_PER_LONG)) - { - /* This used to say `r1' and we used to take care - to make sure that `int' was type number 1. */ - fprintf (asmfile, "r"); - dbxout_type_index (integer_type_node); - fprintf (asmfile, ";"); - print_int_cst_octal (TYPE_MIN_VALUE (type)); - fprintf (asmfile, ";"); - print_int_cst_octal (TYPE_MAX_VALUE (type)); - fprintf (asmfile, ";"); - } - else /* Output other integer types as subranges of `int'. */ - dbxout_range_type (type); - CHARS (22); - break; - - case REAL_TYPE: - /* This used to say `r1' and we used to take care - to make sure that `int' was type number 1. */ - fprintf (asmfile, "r"); - dbxout_type_index (integer_type_node); - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, int_size_in_bytes (type)); - fputs (";0;", asmfile); - CHARS (13); - break; - - case CHAR_TYPE: - if (use_gnu_debug_info_extensions) - { - fputs ("@s", asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - BITS_PER_UNIT * int_size_in_bytes (type)); - fputs (";-20;", asmfile); - } - else - { - /* Output the type `char' as a subrange of itself. - That is what pcc seems to do. */ - fprintf (asmfile, "r"); - dbxout_type_index (char_type_node); - fprintf (asmfile, ";0;%d;", TREE_UNSIGNED (type) ? 255 : 127); - } - CHARS (9); - break; - - case BOOLEAN_TYPE: - if (use_gnu_debug_info_extensions) - { - fputs ("@s", asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - BITS_PER_UNIT * int_size_in_bytes (type)); - fputs (";-16;", asmfile); - } - else /* Define as enumeral type (False, True) */ - fprintf (asmfile, "eFalse:0,True:1,;"); - CHARS (17); - break; - - case FILE_TYPE: - putc ('d', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - break; - - case COMPLEX_TYPE: - /* Differs from the REAL_TYPE by its new data type number */ - - if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE) - { - fprintf (asmfile, "r"); - dbxout_type_index (type); - fputc (';', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - int_size_in_bytes (TREE_TYPE (type))); - fputs (";0;", asmfile); - CHARS (12); /* The number is probably incorrect here. */ - } - else - { - /* Output a complex integer type as a structure, - pending some other way to do it. */ - fputc ('s', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, int_size_in_bytes (type)); - - fprintf (asmfile, "real:"); - CHARS (10); - dbxout_type (TREE_TYPE (type), 0, 0); - fprintf (asmfile, ",%d,%d;", - 0, TYPE_PRECISION (TREE_TYPE (type))); - CHARS (8); - fprintf (asmfile, "imag:"); - CHARS (5); - dbxout_type (TREE_TYPE (type), 0, 0); - fprintf (asmfile, ",%d,%d;;", - TYPE_PRECISION (TREE_TYPE (type)), - TYPE_PRECISION (TREE_TYPE (type))); - CHARS (9); - } - break; - - case SET_TYPE: - if (use_gnu_debug_info_extensions) - { - have_used_extensions = 1; - fputs ("@s", asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - BITS_PER_UNIT * int_size_in_bytes (type)); - fputc (';', asmfile); - /* Check if a bitstring type, which in Chill is - different from a [power]set. */ - if (TYPE_STRING_FLAG (type)) - fprintf (asmfile, "@S;"); - } - putc ('S', asmfile); - CHARS (1); - dbxout_type (TYPE_DOMAIN (type), 0, 0); - break; - - case ARRAY_TYPE: - /* Make arrays of packed bits look like bitstrings for chill. */ - if (TYPE_PACKED (type) && use_gnu_debug_info_extensions) - { - have_used_extensions = 1; - fputs ("@s", asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - BITS_PER_UNIT * int_size_in_bytes (type)); - fputc (';', asmfile); - fprintf (asmfile, "@S;"); - putc ('S', asmfile); - CHARS (1); - dbxout_type (TYPE_DOMAIN (type), 0, 0); - break; - } - /* Output "a" followed by a range type definition - for the index type of the array - followed by a reference to the target-type. - ar1;0;N;M for a C array of type M and size N+1. */ - /* Check if a character string type, which in Chill is - different from an array of characters. */ - if (TYPE_STRING_FLAG (type) && use_gnu_debug_info_extensions) - { - have_used_extensions = 1; - fprintf (asmfile, "@S;"); - } - tem = TYPE_DOMAIN (type); - if (tem == NULL) - { - fprintf (asmfile, "ar"); - dbxout_type_index (integer_type_node); - fprintf (asmfile, ";0;-1;"); - } - else - { - fprintf (asmfile, "a"); - dbxout_range_type (tem); - } - CHARS (14); - dbxout_type (TREE_TYPE (type), 0, 0); - break; - - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - { - int i, n_baseclasses = 0; - - if (TYPE_BINFO (type) != 0 - && TREE_CODE (TYPE_BINFO (type)) == TREE_VEC - && TYPE_BINFO_BASETYPES (type) != 0) - n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); - - /* Output a structure type. We must use the same test here as we - use in the DBX_NO_XREFS case above. */ - if ((TYPE_NAME (type) != 0 - && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_IGNORED_P (TYPE_NAME (type))) - && !full) - || TYPE_SIZE (type) == 0 - /* No way in DBX fmt to describe a variable size. */ - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - { - /* If the type is just a cross reference, output one - and mark the type as partially described. - If it later becomes defined, we will output - its real definition. - If the type has a name, don't nest its definition within - another type's definition; instead, output an xref - and let the definition come when the name is defined. */ - fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu"); - CHARS (3); -#if 0 /* This assertion is legitimately false in C++. */ - /* We shouldn't be outputting a reference to a type before its - definition unless the type has a tag name. - A typedef name without a tag name should be impossible. */ - if (TREE_CODE (TYPE_NAME (type)) != IDENTIFIER_NODE) - abort (); -#endif - if (TYPE_NAME (type) != 0) - dbxout_type_name (type); - else - fprintf (asmfile, "$$%d", anonymous_type_number++); - fprintf (asmfile, ":"); - typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF; - break; - } - - /* Identify record or union, and print its size. */ - fputc (((TREE_CODE (type) == RECORD_TYPE) ? 's' : 'u'), asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - int_size_in_bytes (type)); - - if (use_gnu_debug_info_extensions) - { - if (n_baseclasses) - { - have_used_extensions = 1; - fprintf (asmfile, "!%d,", n_baseclasses); - CHARS (8); - } - } - for (i = 0; i < n_baseclasses; i++) - { - tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i); - if (use_gnu_debug_info_extensions) - { - have_used_extensions = 1; - putc (TREE_VIA_VIRTUAL (child) ? '1' - : '0', - asmfile); - putc (TREE_VIA_PUBLIC (child) ? '2' - : '0', - asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT); - fputc (',', asmfile); - CHARS (15); - dbxout_type (BINFO_TYPE (child), 0, 0); - putc (';', asmfile); - } - else - { - /* Print out the base class information with fields - which have the same names at the types they hold. */ - dbxout_type_name (BINFO_TYPE (child)); - putc (':', asmfile); - dbxout_type (BINFO_TYPE (child), full, 0); - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT); - fputc (',', asmfile); - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (DECL_SIZE (TYPE_NAME (BINFO_TYPE (child)))) * BITS_PER_UNIT); - fputc (';', asmfile); - CHARS (20); - } - } - } - - CHARS (11); - - /* Write out the field declarations. */ - dbxout_type_fields (type); - if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE) - { - have_used_extensions = 1; - dbxout_type_methods (type); - } - putc (';', asmfile); - - if (use_gnu_debug_info_extensions && TREE_CODE (type) == RECORD_TYPE - /* Avoid the ~ if we don't really need it--it confuses dbx. */ - && TYPE_VFIELD (type)) - { - have_used_extensions = 1; - - /* Tell GDB+ that it may keep reading. */ - putc ('~', asmfile); - - /* We need to write out info about what field this class - uses as its "main" vtable pointer field, because if this - field is inherited from a base class, GDB cannot necessarily - figure out which field it's using in time. */ - if (TYPE_VFIELD (type)) - { - putc ('%', asmfile); - dbxout_type (DECL_FCONTEXT (TYPE_VFIELD (type)), 0, 0); - } - putc (';', asmfile); - CHARS (3); - } - break; - - case ENUMERAL_TYPE: - /* We must use the same test here as we use in the DBX_NO_XREFS case - above. We simplify it a bit since an enum will never have a variable - size. */ - if ((TYPE_NAME (type) != 0 - && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_IGNORED_P (TYPE_NAME (type))) - && !full) - || TYPE_SIZE (type) == 0) - { - fprintf (asmfile, "xe"); - CHARS (3); - dbxout_type_name (type); - typevec[TYPE_SYMTAB_ADDRESS (type)].status = TYPE_XREF; - fprintf (asmfile, ":"); - return; - } -#ifdef DBX_OUTPUT_ENUM - DBX_OUTPUT_ENUM (asmfile, type); -#else - if (use_gnu_debug_info_extensions - && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node)) - fprintf (asmfile, "@s%d;", TYPE_PRECISION (type)); - putc ('e', asmfile); - CHARS (1); - for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem)) - { - fprintf (asmfile, "%s:", IDENTIFIER_POINTER (TREE_PURPOSE (tem))); - if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0) - fprintf (asmfile, HOST_WIDE_INT_PRINT_UNSIGNED, - TREE_INT_CST_LOW (TREE_VALUE (tem))); - else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1 - && TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0) - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, - TREE_INT_CST_LOW (TREE_VALUE (tem))); - else - print_int_cst_octal (TREE_VALUE (tem)); - fprintf (asmfile, ","); - CHARS (20 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem))); - if (TREE_CHAIN (tem) != 0) - { - CONTIN; - } - } - putc (';', asmfile); - CHARS (1); -#endif - break; - - case POINTER_TYPE: - putc ('*', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - break; - - case METHOD_TYPE: - if (use_gnu_debug_info_extensions) - { - have_used_extensions = 1; - putc ('#', asmfile); - CHARS (1); - if (flag_minimal_debug && !show_arg_types) - { - /* Normally, just output the return type. - The argument types are encoded in the method name. */ - putc ('#', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - putc (';', asmfile); - CHARS (1); - } - else - { - /* When outputting destructors, we need to write - the argument types out longhand. */ - dbxout_type (TYPE_METHOD_BASETYPE (type), 0, 0); - putc (',', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - dbxout_args (TYPE_ARG_TYPES (type)); - putc (';', asmfile); - CHARS (1); - } - } - else - { - /* Treat it as a function type. */ - dbxout_type (TREE_TYPE (type), 0, 0); - } - break; - - case OFFSET_TYPE: - if (use_gnu_debug_info_extensions) - { - have_used_extensions = 1; - putc ('@', asmfile); - CHARS (1); - dbxout_type (TYPE_OFFSET_BASETYPE (type), 0, 0); - putc (',', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - } - else - { - /* Should print as an int, because it is really - just an offset. */ - dbxout_type (integer_type_node, 0, 0); - } - break; - - case REFERENCE_TYPE: - if (use_gnu_debug_info_extensions) - have_used_extensions = 1; - putc (use_gnu_debug_info_extensions ? '&' : '*', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - break; - - case FUNCTION_TYPE: - putc ('f', asmfile); - CHARS (1); - dbxout_type (TREE_TYPE (type), 0, 0); - break; - - default: - abort (); - } -} - -/* Print the value of integer constant C, in octal, - handling double precision. */ - -static void -print_int_cst_octal (c) - tree c; -{ - unsigned HOST_WIDE_INT high = TREE_INT_CST_HIGH (c); - unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (c); - int excess = (3 - (HOST_BITS_PER_WIDE_INT % 3)); - int width = TYPE_PRECISION (TREE_TYPE (c)); - - /* GDB wants constants with no extra leading "1" bits, so - we need to remove any sign-extension that might be - present. */ - if (width == HOST_BITS_PER_WIDE_INT * 2) - ; - else if (width > HOST_BITS_PER_WIDE_INT) - high &= (((HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT)) - 1); - else if (width == HOST_BITS_PER_WIDE_INT) - high = 0; - else - high = 0, low &= (((HOST_WIDE_INT) 1 << width) - 1); - - fprintf (asmfile, "0"); - - if (excess == 3) - { - print_octal (high, HOST_BITS_PER_WIDE_INT / 3); - print_octal (low, HOST_BITS_PER_WIDE_INT / 3); - } - else - { - unsigned HOST_WIDE_INT beg = high >> excess; - unsigned HOST_WIDE_INT middle - = ((high & (((HOST_WIDE_INT) 1 << excess) - 1)) << (3 - excess) - | (low >> (HOST_BITS_PER_WIDE_INT / 3 * 3))); - unsigned HOST_WIDE_INT end - = low & (((unsigned HOST_WIDE_INT) 1 - << (HOST_BITS_PER_WIDE_INT / 3 * 3)) - - 1); - - fprintf (asmfile, "%o%01o", (int)beg, (int)middle); - print_octal (end, HOST_BITS_PER_WIDE_INT / 3); - } -} - -static void -print_octal (value, digits) - unsigned HOST_WIDE_INT value; - int digits; -{ - int i; - - for (i = digits - 1; i >= 0; i--) - fprintf (asmfile, "%01o", (int)((value >> (3 * i)) & 7)); -} - -/* Output the name of type TYPE, with no punctuation. - Such names can be set up either by typedef declarations - or by struct, enum and union tags. */ - -static void -dbxout_type_name (type) - register tree type; -{ - tree t; - if (TYPE_NAME (type) == 0) - abort (); - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - { - t = TYPE_NAME (type); - } - else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) - { - t = DECL_NAME (TYPE_NAME (type)); - } - else - abort (); - - fprintf (asmfile, "%s", IDENTIFIER_POINTER (t)); - CHARS (IDENTIFIER_LENGTH (t)); -} - -/* Output a .stabs for the symbol defined by DECL, - which must be a ..._DECL node in the normal namespace. - It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL. - LOCAL is nonzero if the scope is less than the entire file. */ - -void -dbxout_symbol (decl, local) - tree decl; - int local; -{ - tree type = TREE_TYPE (decl); - tree context = NULL_TREE; - - /* Cast avoids warning in old compilers. */ - current_sym_code = (STAB_CODE_TYPE) 0; - current_sym_value = 0; - current_sym_addr = 0; - - /* Ignore nameless syms, but don't ignore type tags. */ - - if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL) - || DECL_IGNORED_P (decl)) - return; - - dbxout_prepare_symbol (decl); - - /* The output will always start with the symbol name, - so always count that in the length-output-so-far. */ - - if (DECL_NAME (decl) != 0) - current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (decl)); - - switch (TREE_CODE (decl)) - { - case CONST_DECL: - /* Enum values are defined by defining the enum type. */ - break; - - case FUNCTION_DECL: - if (DECL_RTL (decl) == 0) - return; - if (DECL_EXTERNAL (decl)) - break; - /* Don't mention a nested function under its parent. */ - context = decl_function_context (decl); - if (context == current_function_decl) - break; - if (GET_CODE (DECL_RTL (decl)) != MEM - || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) - break; - FORCE_TEXT; - - fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), - TREE_PUBLIC (decl) ? 'F' : 'f'); - - current_sym_code = N_FUN; - current_sym_addr = XEXP (DECL_RTL (decl), 0); - - if (TREE_TYPE (type)) - dbxout_type (TREE_TYPE (type), 0, 0); - else - dbxout_type (void_type_node, 0, 0); - - /* For a nested function, when that function is compiled, - mention the containing function name - as well as (since dbx wants it) our own assembler-name. */ - if (context != 0) - fprintf (asmfile, ",%s,%s", - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), - IDENTIFIER_POINTER (DECL_NAME (context))); - - dbxout_finish_symbol (decl); - break; - - case TYPE_DECL: -#if 0 - /* This seems all wrong. Outputting most kinds of types gives no name - at all. A true definition gives no name; a cross-ref for a - structure can give the tag name, but not a type name. - It seems that no typedef name is defined by outputting a type. */ - - /* If this typedef name was defined by outputting the type, - don't duplicate it. */ - if (typevec[TYPE_SYMTAB_ADDRESS (type)].status == TYPE_DEFINED - && TYPE_NAME (TREE_TYPE (decl)) == decl) - return; -#endif - /* Don't output the same typedef twice. - And don't output what language-specific stuff doesn't want output. */ - if (TREE_ASM_WRITTEN (decl) || TYPE_DECL_SUPPRESS_DEBUG (decl)) - return; - - FORCE_TEXT; - - { - int tag_needed = 1; - int did_output = 0; - - if (DECL_NAME (decl)) - { - /* Nonzero means we must output a tag as well as a typedef. */ - tag_needed = 0; - - /* Handle the case of a C++ structure or union - where the TYPE_NAME is a TYPE_DECL - which gives both a typedef name and a tag. */ - /* dbx requires the tag first and the typedef second. */ - if ((TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE) - && TYPE_NAME (type) == decl - && !(use_gnu_debug_info_extensions && have_used_extensions) - && !TREE_ASM_WRITTEN (TYPE_NAME (type)) - /* Distinguish the implicit typedefs of C++ - from explicit ones that might be found in C. */ - && DECL_ARTIFICIAL (decl)) - { - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - current_sym_code = DBX_TYPE_DECL_STABS_CODE; - current_sym_value = 0; - current_sym_addr = 0; - current_sym_nchars = 2 + IDENTIFIER_LENGTH (name); - - fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP, - IDENTIFIER_POINTER (name)); - dbxout_type (type, 1, 0); - dbxout_finish_symbol (NULL_TREE); - } - - /* Output typedef name. */ - fprintf (asmfile, "%s \"%s:", ASM_STABS_OP, - IDENTIFIER_POINTER (DECL_NAME (decl))); - - /* Short cut way to output a tag also. */ - if ((TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE) - && TYPE_NAME (type) == decl - /* Distinguish the implicit typedefs of C++ - from explicit ones that might be found in C. */ - && DECL_ARTIFICIAL (decl)) - { - if (use_gnu_debug_info_extensions && have_used_extensions) - { - putc ('T', asmfile); - TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1; - } -#if 0 /* Now we generate the tag for this case up above. */ - else - tag_needed = 1; -#endif - } - - putc ('t', asmfile); - current_sym_code = DBX_TYPE_DECL_STABS_CODE; - - dbxout_type (type, 1, 0); - dbxout_finish_symbol (decl); - did_output = 1; - } - - /* Don't output a tag if this is an incomplete type (TYPE_SIZE is - zero). This prevents the sun4 Sun OS 4.x dbx from crashing. */ - - if (tag_needed && TYPE_NAME (type) != 0 - && (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE - || (DECL_NAME (TYPE_NAME (type)) != 0)) - && TYPE_SIZE (type) != 0 - && !TREE_ASM_WRITTEN (TYPE_NAME (type))) - { - /* For a TYPE_DECL with no name, but the type has a name, - output a tag. - This is what represents `struct foo' with no typedef. */ - /* In C++, the name of a type is the corresponding typedef. - In C, it is an IDENTIFIER_NODE. */ - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - current_sym_code = DBX_TYPE_DECL_STABS_CODE; - current_sym_value = 0; - current_sym_addr = 0; - current_sym_nchars = 2 + IDENTIFIER_LENGTH (name); - - fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP, - IDENTIFIER_POINTER (name)); - dbxout_type (type, 1, 0); - dbxout_finish_symbol (NULL_TREE); - did_output = 1; - } - - /* If an enum type has no name, it cannot be referred to, - but we must output it anyway, since the enumeration constants - can be referred to. */ - if (!did_output && TREE_CODE (type) == ENUMERAL_TYPE) - { - current_sym_code = DBX_TYPE_DECL_STABS_CODE; - current_sym_value = 0; - current_sym_addr = 0; - current_sym_nchars = 2; - - /* Some debuggers fail when given NULL names, so give this a - harmless name of ` '. */ - fprintf (asmfile, "%s \" :T", ASM_STABS_OP); - dbxout_type (type, 1, 0); - dbxout_finish_symbol (NULL_TREE); - } - - /* Prevent duplicate output of a typedef. */ - TREE_ASM_WRITTEN (decl) = 1; - break; - } - - case PARM_DECL: - /* Parm decls go in their own separate chains - and are output by dbxout_reg_parms and dbxout_parms. */ - abort (); - - case RESULT_DECL: - /* Named return value, treat like a VAR_DECL. */ - case VAR_DECL: - if (DECL_RTL (decl) == 0) - return; - /* Don't mention a variable that is external. - Let the file that defines it describe it. */ - if (DECL_EXTERNAL (decl)) - break; - - /* If the variable is really a constant - and not written in memory, inform the debugger. */ - if (TREE_STATIC (decl) && TREE_READONLY (decl) - && DECL_INITIAL (decl) != 0 - && ! TREE_ASM_WRITTEN (decl) - && (DECL_FIELD_CONTEXT (decl) == NULL_TREE - || TREE_CODE (DECL_FIELD_CONTEXT (decl)) == BLOCK)) - { - if (TREE_PUBLIC (decl) == 0) - { - /* The sun4 assembler does not grok this. */ - char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); - if (TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE - || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) - { - HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl)); -#ifdef DBX_OUTPUT_CONSTANT_SYMBOL - DBX_OUTPUT_CONSTANT_SYMBOL (asmfile, name, ival); -#else - fprintf (asmfile, "%s \"%s:c=i", ASM_STABS_OP, name); - - fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, ival); - fprintf (asmfile, "\",0x%x,0,0,0\n", N_LSYM); -#endif - return; - } - else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE) - { - /* don't know how to do this yet. */ - } - break; - } - /* else it is something we handle like a normal variable. */ - } - - DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX); -#ifdef LEAF_REG_REMAP - if (leaf_function) - leaf_renumber_regs_insn (DECL_RTL (decl)); -#endif - - dbxout_symbol_location (decl, type, 0, DECL_RTL (decl)); - break; - - default: - break; - } -} - -/* Output the stab for DECL, a VAR_DECL, RESULT_DECL or PARM_DECL. - Add SUFFIX to its name, if SUFFIX is not 0. - Describe the variable as residing in HOME - (usually HOME is DECL_RTL (DECL), but not always). */ - -static void -dbxout_symbol_location (decl, type, suffix, home) - tree decl, type; - char *suffix; - rtx home; -{ - int letter = 0; - int regno = -1; - - /* Don't mention a variable at all - if it was completely optimized into nothingness. - - If the decl was from an inline function, then its rtl - is not identically the rtl that was used in this - particular compilation. */ - if (GET_CODE (home) == REG) - { - regno = REGNO (home); - if (regno >= FIRST_PSEUDO_REGISTER) - return; - } - else if (GET_CODE (home) == SUBREG) - { - rtx value = home; - int offset = 0; - while (GET_CODE (value) == SUBREG) - { - offset += SUBREG_WORD (value); - value = SUBREG_REG (value); - } - if (GET_CODE (value) == REG) - { - regno = REGNO (value); - if (regno >= FIRST_PSEUDO_REGISTER) - return; - regno += offset; - } - alter_subreg (home); - } - - /* The kind-of-variable letter depends on where - the variable is and on the scope of its name: - G and N_GSYM for static storage and global scope, - S for static storage and file scope, - V for static storage and local scope, - for those two, use N_LCSYM if data is in bss segment, - N_STSYM if in data segment, N_FUN otherwise. - (We used N_FUN originally, then changed to N_STSYM - to please GDB. However, it seems that confused ld. - Now GDB has been fixed to like N_FUN, says Kingdon.) - no letter at all, and N_LSYM, for auto variable, - r and N_RSYM for register variable. */ - - if (GET_CODE (home) == MEM - && GET_CODE (XEXP (home, 0)) == SYMBOL_REF) - { - if (TREE_PUBLIC (decl)) - { - letter = 'G'; - current_sym_code = N_GSYM; - } - else - { - current_sym_addr = XEXP (home, 0); - - letter = decl_function_context (decl) ? 'V' : 'S'; - - /* This should be the same condition as in assemble_variable, but - we don't have access to dont_output_data here. So, instead, - we rely on the fact that error_mark_node initializers always - end up in bss for C++ and never end up in bss for C. */ - if (DECL_INITIAL (decl) == 0 - || (!strcmp (lang_identify (), "cplusplus") - && DECL_INITIAL (decl) == error_mark_node)) - current_sym_code = N_LCSYM; - else if (DECL_IN_TEXT_SECTION (decl)) - /* This is not quite right, but it's the closest - of all the codes that Unix defines. */ - current_sym_code = DBX_STATIC_CONST_VAR_CODE; - else - { - /* Ultrix `as' seems to need this. */ -#ifdef DBX_STATIC_STAB_DATA_SECTION - data_section (); -#endif - current_sym_code = N_STSYM; - } - } - } - else if (regno >= 0) - { - letter = 'r'; - current_sym_code = N_RSYM; - current_sym_value = DBX_REGISTER_NUMBER (regno); - } - else if (GET_CODE (home) == MEM - && (GET_CODE (XEXP (home, 0)) == MEM - || (GET_CODE (XEXP (home, 0)) == REG - && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM - && REGNO (XEXP (home, 0)) != STACK_POINTER_REGNUM -#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM - && REGNO (XEXP (home, 0)) != ARG_POINTER_REGNUM -#endif - ))) - /* If the value is indirect by memory or by a register - that isn't the frame pointer - then it means the object is variable-sized and address through - that register or stack slot. DBX has no way to represent this - so all we can do is output the variable as a pointer. - If it's not a parameter, ignore it. - (VAR_DECLs like this can be made by integrate.c.) */ - { - if (GET_CODE (XEXP (home, 0)) == REG) - { - letter = 'r'; - current_sym_code = N_RSYM; - current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (home, 0))); - } - else - { - current_sym_code = N_LSYM; - /* RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))). - We want the value of that CONST_INT. */ - current_sym_value - = DEBUGGER_AUTO_OFFSET (XEXP (XEXP (home, 0), 0)); - } - - /* Effectively do build_pointer_type, but don't cache this type, - since it might be temporary whereas the type it points to - might have been saved for inlining. */ - /* Don't use REFERENCE_TYPE because dbx can't handle that. */ - type = make_node (POINTER_TYPE); - TREE_TYPE (type) = TREE_TYPE (decl); - } - else if (GET_CODE (home) == MEM - && GET_CODE (XEXP (home, 0)) == REG) - { - current_sym_code = N_LSYM; - current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (home, 0)); - } - else if (GET_CODE (home) == MEM - && GET_CODE (XEXP (home, 0)) == PLUS - && GET_CODE (XEXP (XEXP (home, 0), 1)) == CONST_INT) - { - current_sym_code = N_LSYM; - /* RTL looks like (MEM (PLUS (REG...) (CONST_INT...))) - We want the value of that CONST_INT. */ - current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (home, 0)); - } - else if (GET_CODE (home) == MEM - && GET_CODE (XEXP (home, 0)) == CONST) - { - /* Handle an obscure case which can arise when optimizing and - when there are few available registers. (This is *always* - the case for i386/i486 targets). The RTL looks like - (MEM (CONST ...)) even though this variable is a local `auto' - or a local `register' variable. In effect, what has happened - is that the reload pass has seen that all assignments and - references for one such a local variable can be replaced by - equivalent assignments and references to some static storage - variable, thereby avoiding the need for a register. In such - cases we're forced to lie to debuggers and tell them that - this variable was itself `static'. */ - current_sym_code = N_LCSYM; - letter = 'V'; - current_sym_addr = XEXP (XEXP (home, 0), 0); - } - else if (GET_CODE (home) == CONCAT) - { - tree subtype = TREE_TYPE (type); - - /* If the variable's storage is in two parts, - output each as a separate stab with a modified name. */ - if (WORDS_BIG_ENDIAN) - dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 0)); - else - dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0)); - - /* Cast avoids warning in old compilers. */ - current_sym_code = (STAB_CODE_TYPE) 0; - current_sym_value = 0; - current_sym_addr = 0; - dbxout_prepare_symbol (decl); - - if (WORDS_BIG_ENDIAN) - dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 1)); - else - dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 1)); - return; - } - else - /* Address might be a MEM, when DECL is a variable-sized object. - Or it might be const0_rtx, meaning previous passes - want us to ignore this variable. */ - return; - - /* Ok, start a symtab entry and output the variable name. */ - FORCE_TEXT; - -#ifdef DBX_STATIC_BLOCK_START - DBX_STATIC_BLOCK_START (asmfile, current_sym_code); -#endif - - /* CYGNUS LOCAL LRS */ - if (!DECL_LIVE_RANGE_RTL (decl) || !LIVE_RANGE_GDBSTAB_P ()) - dbxout_symbol_name (decl, suffix, letter, FALSE); - else - dbxout_symbol_name (decl, suffix, letter, 1); - /* END CYGNUS LOCAL */ - - dbxout_type (type, 0, 0); - dbxout_finish_symbol (decl); - - /* CYGNUS LOCAL LRS */ - dbxout_live_range_alias (decl); - /* END CYGNUS LOCAL */ - -#ifdef DBX_STATIC_BLOCK_END - DBX_STATIC_BLOCK_END (asmfile, current_sym_code); -#endif -} - -/* Output the symbol name of DECL for a stabs, with suffix SUFFIX. - Then output LETTER to indicate the kind of location the symbol has. */ - -/* CYGNUS LOCAL LRS */ -static void -dbxout_symbol_name (decl, suffix, letter, live_range_p) - tree decl; - char *suffix; - int letter; - int live_range_p; -{ - /* One slight hitch: if this is a VAR_DECL which is a static - class member, we must put out the mangled name instead of the - DECL_NAME. Note also that static member (variable) names DO NOT begin - with underscores in .stabs directives. */ - char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - char range_prefix[20]; - if (name == 0) - name = "(anon)"; - if (live_range_p == 1) - { - sprintf (range_prefix, "#%d=", ++range_max_number); - } - else if (live_range_p == 2) - { - sprintf (range_prefix, "#%d", range_max_number); - name = ""; - } - else - range_prefix[0] = '\0'; - fprintf (asmfile, "%s \"%s%s%s:", ASM_STABS_OP, range_prefix, name, - (suffix ? suffix : "")); - - if (letter) putc (letter, asmfile); -} -/* END CYGNUS LOCAL */ - -static void -dbxout_prepare_symbol (decl) - tree decl; -{ -#ifdef WINNING_GDB - char *filename = DECL_SOURCE_FILE (decl); - - dbxout_source_file (asmfile, filename); -#endif -} - -static void -dbxout_finish_symbol (sym) - tree sym; -{ -#ifdef DBX_FINISH_SYMBOL - DBX_FINISH_SYMBOL (sym); -#else - int line = 0; - if (use_gnu_debug_info_extensions && sym != 0) - line = DECL_SOURCE_LINE (sym); - - fprintf (asmfile, "\",%d,0,%d,", current_sym_code, line); - if (current_sym_addr) - output_addr_const (asmfile, current_sym_addr); - else - fprintf (asmfile, "%d", current_sym_value); - putc ('\n', asmfile); -#endif -} - -/* Output definitions of all the decls in a chain. */ - -void -dbxout_syms (syms) - tree syms; -{ - while (syms) - { - dbxout_symbol (syms, 1); - syms = TREE_CHAIN (syms); - } -} - -/* The following two functions output definitions of function parameters. - Each parameter gets a definition locating it in the parameter list. - Each parameter that is a register variable gets a second definition - locating it in the register. - - Printing or argument lists in gdb uses the definitions that - locate in the parameter list. But reference to the variable in - expressions uses preferentially the definition as a register. */ - -/* Output definitions, referring to storage in the parmlist, - of all the parms in PARMS, which is a chain of PARM_DECL nodes. */ - -void -dbxout_parms (parms) - tree parms; -{ - for (; parms; parms = TREE_CHAIN (parms)) - if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node) - { - /* CYGNUS LOCAL LRS */ - char range_prefix[20]; - /* END CYGNUS LOCAL */ - - dbxout_prepare_symbol (parms); - - /* Perform any necessary register eliminations on the parameter's rtl, - so that the debugging output will be accurate. */ - DECL_INCOMING_RTL (parms) - = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX); - DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX); -#ifdef LEAF_REG_REMAP - if (leaf_function) - { - leaf_renumber_regs_insn (DECL_INCOMING_RTL (parms)); - leaf_renumber_regs_insn (DECL_RTL (parms)); - } -#endif - - /* CYGNUS LOCAL LRS */ - /* Handle case where parameter was passed in a reg and had its - range split. - - In theory, we should only need to handle the REG case below. - Adding others is simple, but let's avoid unnecessary CYGNUS LOCAL - code. */ - if (GET_CODE (DECL_RTL (parms)) == REG - && DECL_LIVE_RANGE_RTL (parms) && LIVE_RANGE_GDBSTAB_P ()) - sprintf (range_prefix, "#%d=", ++range_max_number); - else - range_prefix[0] = '\0'; - /* END CYGNUS LOCAL */ - - if (PARM_PASSED_IN_MEMORY (parms)) - { - rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0); - - /* ??? Here we assume that the parm address is indexed - off the frame pointer or arg pointer. - If that is not true, we produce meaningless results, - but do not crash. */ - if (GET_CODE (addr) == PLUS - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - current_sym_value = INTVAL (XEXP (addr, 1)); - else - current_sym_value = 0; - - current_sym_code = N_PSYM; - current_sym_addr = 0; - - FORCE_TEXT; - if (DECL_NAME (parms)) - { - current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms)); - - fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, - IDENTIFIER_POINTER (DECL_NAME (parms)), - DBX_MEMPARM_STABS_LETTER); - } - else - { - current_sym_nchars = 8; - fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, - DBX_MEMPARM_STABS_LETTER); - } - - /* It is quite tempting to use: - - dbxout_type (TREE_TYPE (parms), 0, 0); - - as the next statement, rather than using DECL_ARG_TYPE(), so - that gcc reports the actual type of the parameter, rather - than the promoted type. This certainly makes GDB's life - easier, at least for some ports. The change is a bad idea - however, since GDB expects to be able access the type without - performing any conversions. So for example, if we were - passing a float to an unprototyped function, gcc will store a - double on the stack, but if we emit a stab saying the type is a - float, then gdb will only read in a single value, and this will - produce an erropneous value. */ - dbxout_type (DECL_ARG_TYPE (parms), 0, 0); - current_sym_value = DEBUGGER_ARG_OFFSET (current_sym_value, addr); - dbxout_finish_symbol (parms); - } - else if (GET_CODE (DECL_RTL (parms)) == REG) - { - rtx best_rtl; - char regparm_letter; - tree parm_type; - /* Parm passed in registers and lives in registers or nowhere. */ - - current_sym_code = DBX_REGPARM_STABS_CODE; - regparm_letter = DBX_REGPARM_STABS_LETTER; - current_sym_addr = 0; - - /* If parm lives in a register, use that register; - pretend the parm was passed there. It would be more consistent - to describe the register where the parm was passed, - but in practice that register usually holds something else. - - If we use DECL_RTL, then we must use the declared type of - the variable, not the type that it arrived in. */ - if (REGNO (DECL_RTL (parms)) >= 0 - && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) - { - best_rtl = DECL_RTL (parms); - parm_type = TREE_TYPE (parms); - } - /* If the parm lives nowhere, use the register where it was - passed. It is also better to use the declared type here. */ - else - { - best_rtl = DECL_INCOMING_RTL (parms); - parm_type = TREE_TYPE (parms); - } - current_sym_value = DBX_REGISTER_NUMBER (REGNO (best_rtl)); - - FORCE_TEXT; - /* CYGNUS LOCAL LRS */ - if (DECL_NAME (parms)) - { - current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms)); - fprintf (asmfile, "%s \"%s%s:%c", ASM_STABS_OP, - range_prefix, - IDENTIFIER_POINTER (DECL_NAME (parms)), - regparm_letter); - } - else - { - current_sym_nchars = 8; - fprintf (asmfile, "%s \"%s(anon):%c", ASM_STABS_OP, - range_prefix, regparm_letter); - } - /* END CYGNUS LOCAL */ - - dbxout_type (parm_type, 0, 0); - dbxout_finish_symbol (parms); - } - else if (GET_CODE (DECL_RTL (parms)) == MEM - && GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG - && REGNO (XEXP (DECL_RTL (parms), 0)) != HARD_FRAME_POINTER_REGNUM - && REGNO (XEXP (DECL_RTL (parms), 0)) != STACK_POINTER_REGNUM -#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM - && REGNO (XEXP (DECL_RTL (parms), 0)) != ARG_POINTER_REGNUM -#endif - ) - { - /* Parm was passed via invisible reference. - That is, its address was passed in a register. - Output it as if it lived in that register. - The debugger will know from the type - that it was actually passed by invisible reference. */ - - char regparm_letter; - /* Parm passed in registers and lives in registers or nowhere. */ - - current_sym_code = DBX_REGPARM_STABS_CODE; - if (use_gnu_debug_info_extensions) - regparm_letter = GDB_INV_REF_REGPARM_STABS_LETTER; - else - regparm_letter = DBX_REGPARM_STABS_LETTER; - - /* DECL_RTL looks like (MEM (REG...). Get the register number. - If it is an unallocated pseudo-reg, then use the register where - it was passed instead. */ - if (REGNO (XEXP (DECL_RTL (parms), 0)) >= 0 - && REGNO (XEXP (DECL_RTL (parms), 0)) < FIRST_PSEUDO_REGISTER) - current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0)); - else - current_sym_value = REGNO (DECL_INCOMING_RTL (parms)); - - current_sym_addr = 0; - - FORCE_TEXT; - if (DECL_NAME (parms)) - { - current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms))); - - fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, - IDENTIFIER_POINTER (DECL_NAME (parms)), - regparm_letter); - } - else - { - current_sym_nchars = 8; - fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, - regparm_letter); - } - - dbxout_type (TREE_TYPE (parms), 0, 0); - dbxout_finish_symbol (parms); - } - else if (GET_CODE (DECL_RTL (parms)) == MEM - && XEXP (DECL_RTL (parms), 0) != const0_rtx - /* ??? A constant address for a parm can happen - when the reg it lives in is equiv to a constant in memory. - Should make this not happen, after 2.4. */ - && ! CONSTANT_P (XEXP (DECL_RTL (parms), 0))) - { - /* Parm was passed in registers but lives on the stack. */ - - current_sym_code = N_PSYM; - /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))), - in which case we want the value of that CONST_INT, - or (MEM (REG ...)) or (MEM (MEM ...)), - in which case we use a value of zero. */ - if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG - || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM) - current_sym_value = 0; - else - current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)); - current_sym_addr = 0; - - /* Make a big endian correction if the mode of the type of the - parameter is not the same as the mode of the rtl. */ - if (BYTES_BIG_ENDIAN - && TYPE_MODE (TREE_TYPE (parms)) != GET_MODE (DECL_RTL (parms)) - && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms))) < UNITS_PER_WORD) - { - current_sym_value += UNITS_PER_WORD - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms))); - } - - FORCE_TEXT; - if (DECL_NAME (parms)) - { - current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms))); - - fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, - IDENTIFIER_POINTER (DECL_NAME (parms)), - DBX_MEMPARM_STABS_LETTER); - } - else - { - current_sym_nchars = 8; - fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, - DBX_MEMPARM_STABS_LETTER); - } - - current_sym_value - = DEBUGGER_ARG_OFFSET (current_sym_value, - XEXP (DECL_RTL (parms), 0)); - dbxout_type (TREE_TYPE (parms), 0, 0); - dbxout_finish_symbol (parms); - } - } -} - -/* Output definitions for the places where parms live during the function, - when different from where they were passed, when the parms were passed - in memory. - - It is not useful to do this for parms passed in registers - that live during the function in different registers, because it is - impossible to look in the passed register for the passed value, - so we use the within-the-function register to begin with. - - PARMS is a chain of PARM_DECL nodes. */ - -void -dbxout_reg_parms (parms) - tree parms; -{ - for (; parms; parms = TREE_CHAIN (parms)) - if (DECL_NAME (parms) && PARM_PASSED_IN_MEMORY (parms)) - { - dbxout_prepare_symbol (parms); - - /* Report parms that live in registers during the function - but were passed in memory. */ - if (GET_CODE (DECL_RTL (parms)) == REG - && REGNO (DECL_RTL (parms)) >= 0 - && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) - dbxout_symbol_location (parms, TREE_TYPE (parms), - 0, DECL_RTL (parms)); - else if (GET_CODE (DECL_RTL (parms)) == CONCAT) - dbxout_symbol_location (parms, TREE_TYPE (parms), - 0, DECL_RTL (parms)); - /* Report parms that live in memory but not where they were passed. */ - else if (GET_CODE (DECL_RTL (parms)) == MEM - && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms))) - dbxout_symbol_location (parms, TREE_TYPE (parms), - 0, DECL_RTL (parms)); - } -} - -/* Given a chain of ..._TYPE nodes (as come in a parameter list), - output definitions of those names, in raw form */ - -void -dbxout_args (args) - tree args; -{ - while (args) - { - putc (',', asmfile); - dbxout_type (TREE_VALUE (args), 0, 0); - CHARS (1); - args = TREE_CHAIN (args); - } -} - -/* Given a chain of ..._TYPE nodes, - find those which have typedef names and output those names. - This is to ensure those types get output. */ - -void -dbxout_types (types) - register tree types; -{ - while (types) - { - if (TYPE_NAME (types) - && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL - && ! TREE_ASM_WRITTEN (TYPE_NAME (types))) - dbxout_symbol (TYPE_NAME (types), 1); - types = TREE_CHAIN (types); - } -} - -/* Output everything about a symbol block (a BLOCK node - that represents a scope level), - including recursive output of contained blocks. - - BLOCK is the BLOCK node. - DEPTH is its depth within containing symbol blocks. - ARGS is usually zero; but for the outermost block of the - body of a function, it is a chain of PARM_DECLs for the function parameters. - We output definitions of all the register parms - as if they were local variables of that block. - - If -g1 was used, we count blocks just the same, but output nothing - except for the outermost block. - - Actually, BLOCK may be several blocks chained together. - We handle them all in sequence. */ - -static void -dbxout_block (block, depth, args) - register tree block; - int depth; - tree args; -{ - int blocknum; - - while (block) - { - /* Ignore blocks never expanded or otherwise marked as real. */ - if (TREE_USED (block)) - { -#ifndef DBX_LBRAC_FIRST - /* In dbx format, the syms of a block come before the N_LBRAC. */ - if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) - dbxout_syms (BLOCK_VARS (block)); - if (args) - dbxout_reg_parms (args); -#endif - - /* Now output an N_LBRAC symbol to represent the beginning of - the block. Use the block's tree-walk order to generate - the assembler symbols LBBn and LBEn - that final will define around the code in this block. */ - if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE) - { - char buf[20]; - blocknum = next_block_number++; - ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum); - - if (BLOCK_HANDLER_BLOCK (block)) - { - /* A catch block. Must precede N_LBRAC. */ - tree decl = BLOCK_VARS (block); - while (decl) - { -#ifdef DBX_OUTPUT_CATCH - DBX_OUTPUT_CATCH (asmfile, decl, buf); -#else - fprintf (asmfile, "%s \"%s:C1\",%d,0,0,", ASM_STABS_OP, - IDENTIFIER_POINTER (DECL_NAME (decl)), N_CATCH); - assemble_name (asmfile, buf); - fprintf (asmfile, "\n"); -#endif - decl = TREE_CHAIN (decl); - } - } - -#ifdef DBX_OUTPUT_LBRAC - DBX_OUTPUT_LBRAC (asmfile, buf); -#else - fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC); - assemble_name (asmfile, buf); -#if DBX_BLOCKS_FUNCTION_RELATIVE - fputc ('-', asmfile); - assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); -#endif - fprintf (asmfile, "\n"); -#endif - } - else if (depth > 0) - /* Count blocks the same way regardless of debug_info_level. */ - next_block_number++; - -#ifdef DBX_LBRAC_FIRST - /* On some weird machines, the syms of a block - come after the N_LBRAC. */ - if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) - dbxout_syms (BLOCK_VARS (block)); - if (args) - dbxout_reg_parms (args); -#endif - - /* Output the subblocks. */ - dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE); - - /* Refer to the marker for the end of the block. */ - if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE) - { - char buf[20]; - ASM_GENERATE_INTERNAL_LABEL (buf, "LBE", blocknum); -#ifdef DBX_OUTPUT_RBRAC - DBX_OUTPUT_RBRAC (asmfile, buf); -#else - fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC); - assemble_name (asmfile, buf); -#if DBX_BLOCKS_FUNCTION_RELATIVE - fputc ('-', asmfile); - assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); -#endif - fprintf (asmfile, "\n"); -#endif - } - } - block = BLOCK_CHAIN (block); - } -} - -/* Output the information about a function and its arguments and result. - Usually this follows the function's code, - but on some systems, it comes before. */ - -static void -dbxout_really_begin_function (decl) - tree decl; -{ - /* CYGNUS LOCAL LRS */ - range_max_number_for_parms = range_max_number; - /* END CYGNUS LOCAL */ - dbxout_symbol (decl, 0); - dbxout_parms (DECL_ARGUMENTS (decl)); - if (DECL_NAME (DECL_RESULT (decl)) != 0) - dbxout_symbol (DECL_RESULT (decl), 1); -} - -/* Called at beginning of output of function definition. */ - -void -dbxout_begin_function (decl) - tree decl; -{ -#ifdef DBX_FUNCTION_FIRST - dbxout_really_begin_function (decl); -#endif -} - -/* Output dbx data for a function definition. - This includes a definition of the function name itself (a symbol), - definitions of the parameters (locating them in the parameter list) - and then output the block that makes up the function's body - (including all the auto variables of the function). */ - -void -dbxout_function (decl) - tree decl; -{ -#ifndef DBX_FUNCTION_FIRST - dbxout_really_begin_function (decl); -#endif - dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); - /* CYGNUS LOCAL LRS */ - dbxout_live_range_parms (DECL_ARGUMENTS (decl), range_max_number_for_parms); - /* END CYGNUS LOCAL */ -#ifdef DBX_OUTPUT_FUNCTION_END - DBX_OUTPUT_FUNCTION_END (asmfile, decl); -#endif -#if defined(ASM_OUTPUT_SECTION_NAME) - if (use_gnu_debug_info_extensions -#if defined(NO_DBX_FUNCTION_END) - && ! NO_DBX_FUNCTION_END -#endif - ) - dbxout_function_end (); -#endif -} - -/* CYGNUS LOCAL LRS */ -/* Output live ranges for parameter aliases. This must happen after - the body of the function has been output since the stabs may - reference things defined within the function itself. */ -static void -dbxout_live_range_parms (parms, range_max_number_for_parms) - tree parms; - int range_max_number_for_parms; -{ - int save_range_max_number = range_max_number; - - range_max_number = range_max_number_for_parms; - for (; parms; parms = TREE_CHAIN (parms)) - if (GET_CODE (DECL_RTL (parms)) == REG - && DECL_LIVE_RANGE_RTL (parms) && LIVE_RANGE_GDBSTAB_P ()) - { - range_max_number++; - dbxout_live_range_alias (parms); - } - - range_max_number = save_range_max_number; -} - -/* Output an "alias" symbol for DECL if DECL's live range was split. */ -static void -dbxout_live_range_alias (decl) - tree decl; -{ - /* Was the symbol broken into different distinct ranges? If so, - output LRS debugging information. */ - if (DECL_LIVE_RANGE_RTL (decl) && LIVE_RANGE_GDBSTAB_P ()) - { - rtx rv = DECL_LIVE_RANGE_RTL (decl); - rtx r; - - /* Go through each of the ranges now and emit the registers now - occupied. */ - for (r = RANGE_VAR_LIST (rv); r != NULL_RTX ; r = XEXP (r, 1)) - { - rtx rinfo = XEXP (r, 0); - int i, regno; - int letter; - tree type = TREE_TYPE (decl); - - /* Find the variable amongs the range registers. */ - for (i = RANGE_INFO_NUM_REGS (rinfo)-1; i >= 0; i--) - if (RANGE_REG_SYMBOL_NODE (rinfo, i) == decl) - break; - - /* If the variable did not get a register in this range, and - we reverted it back to the original variable, just skip it. */ - if (i < 0) - continue; - - regno = RANGE_REG_COPY (rinfo, i); - if (reg_renumber[regno] >= 0) /* found a register */ - { - letter = 'r'; - current_sym_code = N_RSYM; - current_sym_value = DBX_REGISTER_NUMBER (reg_renumber[regno]); - } - else /* must be on the stack */ - { - rtx stack = regno_reg_rtx[regno]; - - letter = '\0'; - if (GET_CODE (stack) == MEM - && GET_CODE (XEXP (stack, 0)) == REG) - { - current_sym_code = N_LSYM; - current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (stack, 0)); - } - else if (GET_CODE (stack) == MEM - && GET_CODE (XEXP (stack, 0)) == PLUS - && GET_CODE (XEXP (XEXP (stack, 0), 1)) == CONST_INT) - { - current_sym_code = N_LSYM; - /* RTL looks like (MEM (PLUS (REG...) (CONST_INT...))) - We want the value of that CONST_INT. */ - current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (stack, 0)); - } - else if (GET_CODE (stack) == MEM - && GET_CODE (XEXP (stack, 0)) == CONST) - { - /* Handle an obscure case which can arise when optimizing and - when there are few available registers. (This is *always* - the case for i386/i486 targets). The RTL looks like (MEM - (CONST ...)) even though this variable is a local `auto' - or a local `register' variable. In effect, what has - happened is that the reload pass has seen that all - assignments and references for one such a local variable - can be replaced by equivalent assignments and references - to some static storage variable, thereby avoiding the need - for a register. In such cases we're forced to lie to - debuggers and tell them that this variable was itself - `static'. */ - current_sym_code = N_LCSYM; - letter = 'V'; - current_sym_addr = XEXP (XEXP (stack, 0), 0); - } - else - continue; - } - - dbxout_symbol_name (decl, 0, letter, 2); - dbxout_type (type, 0, 0); - - fprintf (asmfile, ";l(#%d,#%d)", - RANGE_INFO_MARKER_START (rinfo), - RANGE_INFO_MARKER_END (rinfo)); - dbxout_finish_symbol (NULL_TREE); - } - } -} - -/* Output information to mark the beginning or end of a live range. */ -void -dbxout_live_range (number) - int number; -{ - char label[256]; - - ASM_OUTPUT_INTERNAL_LABEL (asmfile, "LR", range_current); - ASM_GENERATE_INTERNAL_LABEL (label, "LR", range_current); - fprintf (asmfile, "%s \"#%d=\",%d,0,0,", ASM_STABS_OP, number, N_SLINE); - assemble_name (asmfile, label); - -#if DBX_BLOCKS_FUNCTION_RELATIVE - putc ('-', asmfile); - assemble_name (asmfile, - XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); -#endif - - putc ('\n', asmfile); - range_current++; - - if (number > range_max_number) - range_max_number = number; -} -/* END CYGNUS LOCAL -- meissner/live range */ -#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ diff --git a/gcc/dbxout.h b/gcc/dbxout.h deleted file mode 100755 index 1e45fa6..0000000 --- a/gcc/dbxout.h +++ /dev/null @@ -1,33 +0,0 @@ -/* dbxout.h - Various declarations for functions found in dbxout.c - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -extern void dbxout_init PROTO ((FILE *, char *, tree)); -extern void dbxout_finish PROTO ((FILE *, char *)); - -extern void dbxout_start_new_source_file PROTO ((char *)); -extern void dbxout_resume_previous_source_file PROTO ((void)); - -extern void dbxout_symbol PROTO ((tree, int)); -extern void dbxout_parms PROTO ((tree)); -extern void dbxout_reg_parms PROTO ((tree)); -extern void dbxout_syms PROTO ((tree)); -extern void dbxout_function PROTO ((tree)); -extern void dbxout_source_line PROTO ((FILE *, char*, int)); -extern void dbxout_begin_function PROTO ((tree)); diff --git a/gcc/dbxstclass.h b/gcc/dbxstclass.h deleted file mode 100755 index 2d003fe..0000000 --- a/gcc/dbxstclass.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Storage classes in XCOFF object file format designed for DBX's use. - This info is from the `Files Reference' manual for IBM's AIX version 3 - for the RS6000. */ - -#define C_GSYM 0x80 -#define C_LSYM 0x81 -#define C_PSYM 0x82 -#define C_RSYM 0x83 -#define C_RPSYM 0x84 -#define C_STSYM 0x85 - -#define C_BCOMM 0x87 -#define C_ECOML 0x88 -#define C_ECOMM 0x89 -#define C_DECL 0x8c -#define C_ENTRY 0x8d -#define C_FUN 0x8e diff --git a/gcc/doschk.c b/gcc/doschk.c deleted file mode 100755 index ad553df..0000000 --- a/gcc/doschk.c +++ /dev/null @@ -1,360 +0,0 @@ -/* -** DosFCheck - check file names for DOS consistency -** -** Distribute freely, it only encourages DOS compatibility! -** - DJ Delorie -*/ - -/* This file is not part of GCC. */ - -#include <stdio.h> -#ifdef __MSDOS__ -#include <alloc.h> -#else -#include <malloc.h> -#endif -#include <ctype.h> -#include <string.h> - -typedef struct ENT -{ - struct ENT *next; - char *dos_name; - char *full_name; - char *path; - int tagged; -} ENT; - -ENT *eroot = 0; - -int first_inv = 1; -int first_msg = 1; - -/****************************************************************\ - * Utility routines * -\****************************************************************/ - -void -invalid_msg () -{ - if (first_inv) - { - if (first_msg) - first_msg = 0; - else - putchar ('\n'); - printf ("The following files are not valid DOS file names:\n"); - first_inv = 0; - } -} - -ENT * -alloc_ent () -{ - ENT *rv = (ENT *)malloc (sizeof (ENT)); - if (rv == 0) - { - fprintf (stderr, "Unable to allocate memory for an ENT\n"); - exit (1); - } - memset (rv, 0, sizeof (ENT)); - return rv; -} - -void -fill_ent (ent, path) -ENT *ent; -char *path; -{ - char *first = path; - char *null = path+strlen (path); - char *last_slash = strrchr (path, '/'); - char *cp, *dp; - int dots_seen, chars_seen; - - if (last_slash+1 == null) - { - * --null = '\0'; - last_slash = strrchr (path, '/'); - } - - if (!last_slash) - { - last_slash = first-1; - } - - if (null-last_slash < 13) - ent->dos_name = (char *)malloc (null-last_slash); - else - ent->dos_name = (char *)malloc (13); - ent->full_name = (char *)malloc (null-last_slash); - ent->path = (char *)malloc (last_slash-first+1); - - strcpy (ent->full_name, last_slash+1); - if (last_slash > first) - { - strncpy (ent->path, first, last_slash-first); - ent->path[last_slash-first] = '\0'; - } - else - *ent->path = '\0'; - - cp = last_slash+1; - dp = ent->dos_name; - dots_seen = 0; - chars_seen = 0; - while (1) - { - if (! *cp) - break; - switch (*cp) - { - case '.': - if (cp == last_slash+1 && strcmp (last_slash+1, ".")) - { - invalid_msg (); - printf ("%s - file name cannot start with dot\n", path); - *dp = 0; - break; - } - if (dots_seen == 1) - { - invalid_msg (); - printf ("%s - too many dots\n", path); - *dp = '\0'; - break; - } - *dp++ = '.'; - chars_seen = 0; - dots_seen++; - break; - case '"': - case '*': - case '+': - case ',': - case ';': - case '<': - case '=': - case '>': - case '?': - case '[': - case '\\': - case ']': - case '|': - invalid_msg (); - printf ("%s - invalid character `%c'\n", path, *cp); - *dp++ = '?'; - chars_seen++; - break; - default: - if (dots_seen) - { - if (chars_seen >= 3) - break; - } - else - if (chars_seen >= 8) - break; - if ((*cp <= ' ') || (*cp >= 0x7f)) - { - invalid_msg (); - printf ("%s - invalid character `%c'\n", path, *cp); - *dp++ = '?'; - chars_seen++; - break; - } - if (islower (*cp)) - *dp++ = toupper (*cp); - else - *dp++ = *cp; - chars_seen++; - break; - } - cp++; - } - *dp++ = '\0'; -} - -int -compare_ent_dosname (e1, e2) -ENT **e1; -ENT **e2; -{ - int r = strcmp ((*e1)->dos_name, (*e2)->dos_name); - if (r == 0) - r = strcmp ((*e1)->path, (*e2)->path); - if (r == 0) - r = strcmp ((*e1)->full_name, (*e2)->full_name); - return r; -} - -int -compare_ent_fullname (e1, e2) -ENT **e1; -ENT **e2; -{ - int r = strncmp ((*e1)->full_name, (*e2)->full_name, 14); - if (r == 0) - r = strcmp ((*e1)->path, (*e2)->path); - if (r == 0) - r = strcmp ((*e1)->full_name, (*e2)->full_name); - return r; -} - -char * -mpath (ent) -ENT *ent; -{ - static char buf[500]; - if (ent->path && ent->path[0]) - sprintf (buf, "%s/%s", ent->path, ent->full_name); - else - return ent->full_name; - return buf; -} - -/****************************************************************\ - * List handling routines * -\****************************************************************/ - -void -add_ent (ent) -ENT *ent; -{ - ent->next = eroot; - eroot = ent; -} - -void -handle_input (line) -char *line; -{ - ENT *ent = alloc_ent (); - fill_ent (ent, line); - add_ent (ent); -} - -void -display_problems () -{ - ENT **elist, *ent; - int ecount, i, first, first_err; - - for (ecount=0, ent=eroot; ent; ent=ent->next, ecount++); - elist = (ENT **)malloc (sizeof (ENT *) * ecount); - for (ecount=0, ent=eroot; ent; ent=ent->next, ecount++) - elist[ecount] = ent; - - qsort (elist, ecount, sizeof (ENT *), compare_ent_dosname); - - first = 1; - first_err = 1; - for (i=0; i<ecount-1; i++) - { - if ((strcmp (elist[i]->dos_name, elist[i+1]->dos_name) == 0) - && (strcmp (elist[i]->path, elist[i+1]->path) == 0)) - { - if (first_err) - { - if (first_msg) - first_msg = 0; - else - putchar ('\n'); - printf ("The following resolve to the same DOS file names:\n"); - first_err = 0; - } - if (first) - { - printf ("%14s : %s\n", elist[i]->dos_name, mpath (elist[i])); - first = 0; - } - printf ("\t\t %s\n", mpath (elist[i+1])); - } - else - first = 1; - } - - qsort (elist, ecount, sizeof (ENT *), compare_ent_fullname); - - first = 1; - first_err = 1; - for (i=0; i<ecount-1; i++) - { - if ((strncmp (elist[i]->full_name, elist[i+1]->full_name, 14) == 0) - && (strcmp (elist[i]->path, elist[i+1]->path) == 0)) - { - if (first_err) - { - if (first_msg) - first_msg = 0; - else - putchar ('\n'); - printf ("The following resolve to the same SysV file names:\n"); - first_err = 0; - } - if (first) - { - printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i])); - first = 0; - elist[i]->tagged = 1; - } - printf ("\t\t %s\n", mpath (elist[i+1])); - elist[i+1]->tagged = 1; - } - else - first = 1; - } - - first_err = 1; - for (i=0; i<ecount; i++) - { - if ((strlen (elist[i]->full_name) > 14) && !elist[i]->tagged) - { - if (first_err) - { - if (first_msg) - first_msg = 0; - else - putchar ('\n'); - printf ("The following file names are too long for SysV:\n"); - first_err = 0; - } - printf ("%.14s : %s\n", elist[i]->full_name, mpath (elist[i])); - } - } -} - -/****************************************************************\ - * Main entry point * -\****************************************************************/ - -main (argc, argv) -int argc; -char **argv; -{ - FILE *input = stdin; - if (argc > 1) - { - input = fopen (argv[1], "r"); - if (!input) - { - perror (argv[1]); - exit (1); - } - } - while (1) - { - char line[500]; - char *lp; - fgets (line, 500, input); - if (feof (input)) - break; - lp = line+strlen (line); - while ((lp != line) && (*lp <= ' ')) - lp--; - lp[1] = 0; - handle_input (line); - } - display_problems (); -} - diff --git a/gcc/dwarf.h b/gcc/dwarf.h deleted file mode 100755 index 6aca017..0000000 --- a/gcc/dwarf.h +++ /dev/null @@ -1,315 +0,0 @@ -/* Declarations and definitions of codes relating to the DWARF symbolic - debugging information format. - - Written by Ron Guilmette (rfg@netcom.com) - -Copyright (C) 1992 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file is derived from the DWARF specification (a public document) - Revision 1.0.1 (April 8, 1992) developed by the UNIX International - Programming Languages Special Interest Group (UI/PLSIG) and distributed - by UNIX International. Copies of this specification are available from - UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. -*/ - -/* Tag names and codes. */ - -enum dwarf_tag { - TAG_padding = 0x0000, - TAG_array_type = 0x0001, - TAG_class_type = 0x0002, - TAG_entry_point = 0x0003, - TAG_enumeration_type = 0x0004, - TAG_formal_parameter = 0x0005, - TAG_global_subroutine = 0x0006, - TAG_global_variable = 0x0007, - /* 0x0008 -- reserved */ - /* 0x0009 -- reserved */ - TAG_label = 0x000a, - TAG_lexical_block = 0x000b, - TAG_local_variable = 0x000c, - TAG_member = 0x000d, - /* 0x000e -- reserved */ - TAG_pointer_type = 0x000f, - TAG_reference_type = 0x0010, - TAG_compile_unit = 0x0011, - TAG_string_type = 0x0012, - TAG_structure_type = 0x0013, - TAG_subroutine = 0x0014, - TAG_subroutine_type = 0x0015, - TAG_typedef = 0x0016, - TAG_union_type = 0x0017, - TAG_unspecified_parameters = 0x0018, - TAG_variant = 0x0019, - TAG_common_block = 0x001a, - TAG_common_inclusion = 0x001b, - TAG_inheritance = 0x001c, - TAG_inlined_subroutine = 0x001d, - TAG_module = 0x001e, - TAG_ptr_to_member_type = 0x001f, - TAG_set_type = 0x0020, - TAG_subrange_type = 0x0021, - TAG_with_stmt = 0x0022, - - /* GNU extensions */ - - TAG_format_label = 0x8000, /* for FORTRAN 77 and Fortran 90 */ - TAG_namelist = 0x8001, /* For Fortran 90 */ - TAG_function_template = 0x8002, /* for C++ */ - TAG_class_template = 0x8003 /* for C++ */ -}; - -#define TAG_lo_user 0x8000 /* implementation-defined range start */ -#define TAG_hi_user 0xffff /* implementation-defined range end */ -#define TAG_source_file TAG_compile_unit /* for backward compatibility */ - -/* Form names and codes. */ - -enum dwarf_form { - FORM_ADDR = 0x1, - FORM_REF = 0x2, - FORM_BLOCK2 = 0x3, - FORM_BLOCK4 = 0x4, - FORM_DATA2 = 0x5, - FORM_DATA4 = 0x6, - FORM_DATA8 = 0x7, - FORM_STRING = 0x8 -}; - -/* Attribute names and codes. */ - -enum dwarf_attribute { - AT_sibling = (0x0010|FORM_REF), - AT_location = (0x0020|FORM_BLOCK2), - AT_name = (0x0030|FORM_STRING), - AT_fund_type = (0x0050|FORM_DATA2), - AT_mod_fund_type = (0x0060|FORM_BLOCK2), - AT_user_def_type = (0x0070|FORM_REF), - AT_mod_u_d_type = (0x0080|FORM_BLOCK2), - AT_ordering = (0x0090|FORM_DATA2), - AT_subscr_data = (0x00a0|FORM_BLOCK2), - AT_byte_size = (0x00b0|FORM_DATA4), - AT_bit_offset = (0x00c0|FORM_DATA2), - AT_bit_size = (0x00d0|FORM_DATA4), - /* (0x00e0|FORM_xxxx) -- reserved */ - AT_element_list = (0x00f0|FORM_BLOCK4), - AT_stmt_list = (0x0100|FORM_DATA4), - AT_low_pc = (0x0110|FORM_ADDR), - AT_high_pc = (0x0120|FORM_ADDR), - AT_language = (0x0130|FORM_DATA4), - AT_member = (0x0140|FORM_REF), - AT_discr = (0x0150|FORM_REF), - AT_discr_value = (0x0160|FORM_BLOCK2), - /* (0x0170|FORM_xxxx) -- reserved */ - /* (0x0180|FORM_xxxx) -- reserved */ - AT_string_length = (0x0190|FORM_BLOCK2), - AT_common_reference = (0x01a0|FORM_REF), - AT_comp_dir = (0x01b0|FORM_STRING), - AT_const_value_string = (0x01c0|FORM_STRING), - AT_const_value_data2 = (0x01c0|FORM_DATA2), - AT_const_value_data4 = (0x01c0|FORM_DATA4), - AT_const_value_data8 = (0x01c0|FORM_DATA8), - AT_const_value_block2 = (0x01c0|FORM_BLOCK2), - AT_const_value_block4 = (0x01c0|FORM_BLOCK4), - AT_containing_type = (0x01d0|FORM_REF), - AT_default_value_addr = (0x01e0|FORM_ADDR), - AT_default_value_data2 = (0x01e0|FORM_DATA2), - AT_default_value_data4 = (0x01e0|FORM_DATA4), - AT_default_value_data8 = (0x01e0|FORM_DATA8), - AT_default_value_string = (0x01e0|FORM_STRING), - AT_friends = (0x01f0|FORM_BLOCK2), - AT_inline = (0x0200|FORM_STRING), - AT_is_optional = (0x0210|FORM_STRING), - AT_lower_bound_ref = (0x0220|FORM_REF), - AT_lower_bound_data2 = (0x0220|FORM_DATA2), - AT_lower_bound_data4 = (0x0220|FORM_DATA4), - AT_lower_bound_data8 = (0x0220|FORM_DATA8), - AT_private = (0x0240|FORM_STRING), - AT_producer = (0x0250|FORM_STRING), - AT_program = (0x0230|FORM_STRING), - AT_protected = (0x0260|FORM_STRING), - AT_prototyped = (0x0270|FORM_STRING), - AT_public = (0x0280|FORM_STRING), - AT_pure_virtual = (0x0290|FORM_STRING), - AT_return_addr = (0x02a0|FORM_BLOCK2), - AT_abstract_origin = (0x02b0|FORM_REF), - AT_start_scope = (0x02c0|FORM_DATA4), - AT_stride_size = (0x02e0|FORM_DATA4), - AT_upper_bound_ref = (0x02f0|FORM_REF), - AT_upper_bound_data2 = (0x02f0|FORM_DATA2), - AT_upper_bound_data4 = (0x02f0|FORM_DATA4), - AT_upper_bound_data8 = (0x02f0|FORM_DATA8), - AT_virtual = (0x0300|FORM_STRING), - - /* GNU extensions. */ - - AT_sf_names = (0x8000|FORM_DATA4), - AT_src_info = (0x8010|FORM_DATA4), - AT_mac_info = (0x8020|FORM_DATA4), - AT_src_coords = (0x8030|FORM_DATA4), - AT_body_begin = (0x8040|FORM_ADDR), - AT_body_end = (0x8050|FORM_ADDR) -}; - -#define AT_lo_user 0x2000 /* implementation-defined range start */ -#define AT_hi_user 0x3ff0 /* implementation-defined range end */ - -/* Location atom names and codes. */ - -enum dwarf_location_atom { - OP_REG = 0x01, - OP_BASEREG = 0x02, - OP_ADDR = 0x03, - OP_CONST = 0x04, - OP_DEREF2 = 0x05, - OP_DEREF4 = 0x06, - OP_ADD = 0x07, - - /* GNU extensions. */ - - OP_MULT = 0x80 -}; - -#define OP_LO_USER 0x80 /* implementation-defined range start */ -#define OP_HI_USER 0xff /* implementation-defined range end */ - -/* Fundamental type names and codes. */ - -enum dwarf_fundamental_type { - FT_char = 0x0001, - FT_signed_char = 0x0002, - FT_unsigned_char = 0x0003, - FT_short = 0x0004, - FT_signed_short = 0x0005, - FT_unsigned_short = 0x0006, - FT_integer = 0x0007, - FT_signed_integer = 0x0008, - FT_unsigned_integer = 0x0009, - FT_long = 0x000a, - FT_signed_long = 0x000b, - FT_unsigned_long = 0x000c, - FT_pointer = 0x000d, /* an alias for (void *) */ - FT_float = 0x000e, - FT_dbl_prec_float = 0x000f, - FT_ext_prec_float = 0x0010, /* breaks "classic" svr4 SDB */ - FT_complex = 0x0011, /* breaks "classic" svr4 SDB */ - FT_dbl_prec_complex = 0x0012, /* breaks "classic" svr4 SDB */ - /* 0x0013 -- reserved */ - FT_void = 0x0014, - FT_boolean = 0x0015, /* breaks "classic" svr4 SDB */ - FT_ext_prec_complex = 0x0016, /* breaks "classic" svr4 SDB */ - FT_label = 0x0017, - - /* GNU extensions - The low order byte must indicate the size (in bytes) for the type. - All of these types will probably break "classic" svr4 SDB */ - - FT_long_long = 0x8008, - FT_signed_long_long = 0x8108, - FT_unsigned_long_long = 0x8208, - - FT_int8 = 0x9001, - FT_signed_int8 = 0x9101, - FT_unsigned_int8 = 0x9201, - FT_int16 = 0x9302, - FT_signed_int16 = 0x9402, - FT_unsigned_int16 = 0x9502, - FT_int32 = 0x9604, - FT_signed_int32 = 0x9704, - FT_unsigned_int32 = 0x9804, - FT_int64 = 0x9908, - FT_signed_int64 = 0x9a08, - FT_unsigned_int64 = 0x9b08, - - FT_real32 = 0xa004, - FT_real64 = 0xa108, - FT_real96 = 0xa20c, - FT_real128 = 0xa310 -}; - -#define FT_lo_user 0x8000 /* implementation-defined range start */ -#define FT_hi_user 0xffff /* implementation defined range end */ - -/* Type modifier names and codes. */ - -enum dwarf_type_modifier { - MOD_pointer_to = 0x01, - MOD_reference_to = 0x02, - MOD_const = 0x03, - MOD_volatile = 0x04 -}; - -#define MOD_lo_user 0x80 /* implementation-defined range start */ -#define MOD_hi_user 0xff /* implementation-defined range end */ - -/* Array ordering names and codes. */ - -enum dwarf_array_dim_ordering { - ORD_row_major = 0, - ORD_col_major = 1 -}; - -/* Array subscript format names and codes. */ - -enum dwarf_subscr_data_formats { - FMT_FT_C_C = 0x0, - FMT_FT_C_X = 0x1, - FMT_FT_X_C = 0x2, - FMT_FT_X_X = 0x3, - FMT_UT_C_C = 0x4, - FMT_UT_C_X = 0x5, - FMT_UT_X_C = 0x6, - FMT_UT_X_X = 0x7, - FMT_ET = 0x8 -}; - -/* Derived from above for ease of use. */ - -#define FMT_CODE(_FUNDAMENTAL_TYPE_P, _UB_CONST_P, _LB_CONST_P) \ - (((_FUNDAMENTAL_TYPE_P) ? 0 : 4) \ - | ((_UB_CONST_P) ? 0 : 2) \ - | ((_LB_CONST_P) ? 0 : 1)) - -/* Source language names and codes. */ - -enum dwarf_source_language { - LANG_C89 = 0x00000001, - LANG_C = 0x00000002, - LANG_ADA83 = 0x00000003, - LANG_C_PLUS_PLUS = 0x00000004, - LANG_COBOL74 = 0x00000005, - LANG_COBOL85 = 0x00000006, - LANG_FORTRAN77 = 0x00000007, - LANG_FORTRAN90 = 0x00000008, - LANG_PASCAL83 = 0x00000009, - LANG_MODULA2 = 0x0000000a -}; - -#define LANG_lo_user 0x00008000 /* implementation-defined range start */ -#define LANG_hi_user 0x0000ffff /* implementation-defined range end */ - -/* Names and codes for GNU "macinfo" extension. */ - -enum dwarf_macinfo_record_type { - MACINFO_start = 's', - MACINFO_resume = 'r', - MACINFO_define = 'd', - MACINFO_undef = 'u' -}; diff --git a/gcc/dwarfout.c b/gcc/dwarfout.c deleted file mode 100755 index 6b53979..0000000 --- a/gcc/dwarfout.c +++ /dev/null @@ -1,6030 +0,0 @@ -/* Output Dwarf format symbol table information from the GNU C compiler. - Copyright (C) 1992, 1993, 95-97, 1998 Free Software Foundation, Inc. - Contributed by Ron Guilmette (rfg@monkeys.com) of Network Computing Devices. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" - -#ifdef DWARF_DEBUGGING_INFO -#include "system.h" -#include "dwarf.h" -#include "tree.h" -#include "flags.h" -#include "rtl.h" -#include "hard-reg-set.h" -#include "insn-config.h" -#include "reload.h" -#include "output.h" -#include "defaults.h" -#include "dwarfout.h" -#include "toplev.h" - -#if defined(DWARF_TIMESTAMPS) -#if !defined(POSIX) -extern time_t time PROTO ((time_t *)); /* FIXME: use NEED_DECLARATION_TIME */ -#endif /* !defined(POSIX) */ -#endif /* defined(DWARF_TIMESTAMPS) */ - -/* We cannot use <assert.h> in GCC source, since that would include - GCC's assert.h, which may not be compatible with the host compiler. */ -#undef assert -#ifdef NDEBUG -# define assert(e) -#else -# define assert(e) do { if (! (e)) abort (); } while (0) -#endif - -extern char *getpwd PROTO((void)); - -/* IMPORTANT NOTE: Please see the file README.DWARF for important details - regarding the GNU implementation of Dwarf. */ - -/* NOTE: In the comments in this file, many references are made to - so called "Debugging Information Entries". For the sake of brevity, - this term is abbreviated to `DIE' throughout the remainder of this - file. */ - -/* Note that the implementation of C++ support herein is (as yet) unfinished. - If you want to try to complete it, more power to you. */ - -#if !defined(__GNUC__) || (NDEBUG != 1) -#define inline -#endif - -/* How to start an assembler comment. */ -#ifndef ASM_COMMENT_START -#define ASM_COMMENT_START ";#" -#endif - -/* How to print out a register name. */ -#ifndef PRINT_REG -#define PRINT_REG(RTX, CODE, FILE) \ - fprintf ((FILE), "%s", reg_names[REGNO (RTX)]) -#endif - -/* Define a macro which returns non-zero for any tagged type which is - used (directly or indirectly) in the specification of either some - function's return type or some formal parameter of some function. - We use this macro when we are operating in "terse" mode to help us - know what tagged types have to be represented in Dwarf (even in - terse mode) and which ones don't. - - A flag bit with this meaning really should be a part of the normal - GCC ..._TYPE nodes, but at the moment, there is no such bit defined - for these nodes. For now, we have to just fake it. It it safe for - us to simply return zero for all complete tagged types (which will - get forced out anyway if they were used in the specification of some - formal or return type) and non-zero for all incomplete tagged types. -*/ - -#define TYPE_USED_FOR_FUNCTION(tagged_type) (TYPE_SIZE (tagged_type) == 0) - -/* Define a macro which returns non-zero for a TYPE_DECL which was - implicitly generated for a tagged type. - - Note that unlike the gcc front end (which generates a NULL named - TYPE_DECL node for each complete tagged type, each array type, and - each function type node created) the g++ front end generates a - _named_ TYPE_DECL node for each tagged type node created. - These TYPE_DECLs have DECL_ARTIFICIAL set, so we know not to - generate a DW_TAG_typedef DIE for them. */ -#define TYPE_DECL_IS_STUB(decl) \ - (DECL_NAME (decl) == NULL \ - || (DECL_ARTIFICIAL (decl) \ - && is_tagged_type (TREE_TYPE (decl)) \ - && decl == TYPE_STUB_DECL (TREE_TYPE (decl)))) - -extern int flag_traditional; -extern char *version_string; -extern char *language_string; - -/* Maximum size (in bytes) of an artificially generated label. */ - -#define MAX_ARTIFICIAL_LABEL_BYTES 30 - -/* Make sure we know the sizes of the various types dwarf can describe. - These are only defaults. If the sizes are different for your target, - you should override these values by defining the appropriate symbols - in your tm.h file. */ - -#ifndef CHAR_TYPE_SIZE -#define CHAR_TYPE_SIZE BITS_PER_UNIT -#endif - -#ifndef SHORT_TYPE_SIZE -#define SHORT_TYPE_SIZE (BITS_PER_UNIT * 2) -#endif - -#ifndef INT_TYPE_SIZE -#define INT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_TYPE_SIZE -#define LONG_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_LONG_TYPE_SIZE -#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE INT_TYPE_SIZE -#endif - -#ifndef WCHAR_UNSIGNED -#define WCHAR_UNSIGNED 0 -#endif - -#ifndef FLOAT_TYPE_SIZE -#define FLOAT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef DOUBLE_TYPE_SIZE -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -/* Structure to keep track of source filenames. */ - -struct filename_entry { - unsigned number; - char * name; -}; - -typedef struct filename_entry filename_entry; - -/* Pointer to an array of elements, each one having the structure above. */ - -static filename_entry *filename_table; - -/* Total number of entries in the table (i.e. array) pointed to by - `filename_table'. This is the *total* and includes both used and - unused slots. */ - -static unsigned ft_entries_allocated; - -/* Number of entries in the filename_table which are actually in use. */ - -static unsigned ft_entries; - -/* Size (in elements) of increments by which we may expand the filename - table. Actually, a single hunk of space of this size should be enough - for most typical programs. */ - -#define FT_ENTRIES_INCREMENT 64 - -/* Local pointer to the name of the main input file. Initialized in - dwarfout_init. */ - -static char *primary_filename; - -/* Pointer to the most recent filename for which we produced some line info. */ - -static char *last_filename; - -/* For Dwarf output, we must assign lexical-blocks id numbers - in the order in which their beginnings are encountered. - We output Dwarf debugging info that refers to the beginnings - and ends of the ranges of code for each lexical block with - assembler labels ..Bn and ..Bn.e, where n is the block number. - The labels themselves are generated in final.c, which assigns - numbers to the blocks in the same way. */ - -static unsigned next_block_number = 2; - -/* Counter to generate unique names for DIEs. */ - -static unsigned next_unused_dienum = 1; - -/* Number of the DIE which is currently being generated. */ - -static unsigned current_dienum; - -/* Number to use for the special "pubname" label on the next DIE which - represents a function or data object defined in this compilation - unit which has "extern" linkage. */ - -static int next_pubname_number = 0; - -#define NEXT_DIE_NUM pending_sibling_stack[pending_siblings-1] - -/* Pointer to a dynamically allocated list of pre-reserved and still - pending sibling DIE numbers. Note that this list will grow as needed. */ - -static unsigned *pending_sibling_stack; - -/* Counter to keep track of the number of pre-reserved and still pending - sibling DIE numbers. */ - -static unsigned pending_siblings; - -/* The currently allocated size of the above list (expressed in number of - list elements). */ - -static unsigned pending_siblings_allocated; - -/* Size (in elements) of increments by which we may expand the pending - sibling stack. Actually, a single hunk of space of this size should - be enough for most typical programs. */ - -#define PENDING_SIBLINGS_INCREMENT 64 - -/* Non-zero if we are performing our file-scope finalization pass and if - we should force out Dwarf descriptions of any and all file-scope - tagged types which are still incomplete types. */ - -static int finalizing = 0; - -/* A pointer to the base of a list of pending types which we haven't - generated DIEs for yet, but which we will have to come back to - later on. */ - -static tree *pending_types_list; - -/* Number of elements currently allocated for the pending_types_list. */ - -static unsigned pending_types_allocated; - -/* Number of elements of pending_types_list currently in use. */ - -static unsigned pending_types; - -/* Size (in elements) of increments by which we may expand the pending - types list. Actually, a single hunk of space of this size should - be enough for most typical programs. */ - -#define PENDING_TYPES_INCREMENT 64 - -/* Pointer to an artificial RECORD_TYPE which we create in dwarfout_init. - This is used in a hack to help us get the DIEs describing types of - formal parameters to come *after* all of the DIEs describing the formal - parameters themselves. That's necessary in order to be compatible - with what the brain-damaged svr4 SDB debugger requires. */ - -static tree fake_containing_scope; - -/* The number of the current function definition that we are generating - debugging information for. These numbers range from 1 up to the maximum - number of function definitions contained within the current compilation - unit. These numbers are used to create unique labels for various things - contained within various function definitions. */ - -static unsigned current_funcdef_number = 1; - -/* A pointer to the ..._DECL node which we have most recently been working - on. We keep this around just in case something about it looks screwy - and we want to tell the user what the source coordinates for the actual - declaration are. */ - -static tree dwarf_last_decl; - -/* A flag indicating that we are emitting the member declarations of a - class, so member functions and variables should not be entirely emitted. - This is a kludge to avoid passing a second argument to output_*_die. */ - -static int in_class; - -/* Forward declarations for functions defined in this file. */ - -static char *dwarf_tag_name PROTO((unsigned)); -static char *dwarf_attr_name PROTO((unsigned)); -static char *dwarf_stack_op_name PROTO((unsigned)); -static char *dwarf_typemod_name PROTO((unsigned)); -static char *dwarf_fmt_byte_name PROTO((unsigned)); -static char *dwarf_fund_type_name PROTO((unsigned)); -static tree decl_ultimate_origin PROTO((tree)); -static tree block_ultimate_origin PROTO((tree)); -static tree decl_class_context PROTO((tree)); -#if 0 -static void output_unsigned_leb128 PROTO((unsigned long)); -static void output_signed_leb128 PROTO((long)); -#endif -static inline int is_body_block PROTO((tree)); -static int fundamental_type_code PROTO((tree)); -static tree root_type_1 PROTO((tree, int)); -static tree root_type PROTO((tree)); -static void write_modifier_bytes_1 PROTO((tree, int, int, int)); -static void write_modifier_bytes PROTO((tree, int, int)); -static inline int type_is_fundamental PROTO((tree)); -static void equate_decl_number_to_die_number PROTO((tree)); -static inline void equate_type_number_to_die_number PROTO((tree)); -static void output_reg_number PROTO((rtx)); -static void output_mem_loc_descriptor PROTO((rtx)); -static void output_loc_descriptor PROTO((rtx)); -static void output_bound_representation PROTO((tree, unsigned, int)); -static void output_enumeral_list PROTO((tree)); -static inline unsigned ceiling PROTO((unsigned, unsigned)); -static inline tree field_type PROTO((tree)); -static inline unsigned simple_type_align_in_bits PROTO((tree)); -static inline unsigned simple_type_size_in_bits PROTO((tree)); -static unsigned field_byte_offset PROTO((tree)); -static inline void sibling_attribute PROTO((void)); -static void location_attribute PROTO((rtx)); -static void data_member_location_attribute PROTO((tree)); -static void const_value_attribute PROTO((rtx)); -static void location_or_const_value_attribute PROTO((tree)); -static inline void name_attribute PROTO((char *)); -static inline void fund_type_attribute PROTO((unsigned)); -static void mod_fund_type_attribute PROTO((tree, int, int)); -static inline void user_def_type_attribute PROTO((tree)); -static void mod_u_d_type_attribute PROTO((tree, int, int)); -#ifdef USE_ORDERING_ATTRIBUTE -static inline void ordering_attribute PROTO((unsigned)); -#endif /* defined(USE_ORDERING_ATTRIBUTE) */ -static void subscript_data_attribute PROTO((tree)); -static void byte_size_attribute PROTO((tree)); -static inline void bit_offset_attribute PROTO((tree)); -static inline void bit_size_attribute PROTO((tree)); -static inline void element_list_attribute PROTO((tree)); -static inline void stmt_list_attribute PROTO((char *)); -static inline void low_pc_attribute PROTO((char *)); -static inline void high_pc_attribute PROTO((char *)); -static inline void body_begin_attribute PROTO((char *)); -static inline void body_end_attribute PROTO((char *)); -static inline void language_attribute PROTO((unsigned)); -static inline void member_attribute PROTO((tree)); -#if 0 -static inline void string_length_attribute PROTO((tree)); -#endif -static inline void comp_dir_attribute PROTO((char *)); -static inline void sf_names_attribute PROTO((char *)); -static inline void src_info_attribute PROTO((char *)); -static inline void mac_info_attribute PROTO((char *)); -static inline void prototyped_attribute PROTO((tree)); -static inline void producer_attribute PROTO((char *)); -static inline void inline_attribute PROTO((tree)); -static inline void containing_type_attribute PROTO((tree)); -static inline void abstract_origin_attribute PROTO((tree)); -#ifdef DWARF_DECL_COORDINATES -static inline void src_coords_attribute PROTO((unsigned, unsigned)); -#endif /* defined(DWARF_DECL_COORDINATES) */ -static inline void pure_or_virtual_attribute PROTO((tree)); -static void name_and_src_coords_attributes PROTO((tree)); -static void type_attribute PROTO((tree, int, int)); -static char *type_tag PROTO((tree)); -static inline void dienum_push PROTO((void)); -static inline void dienum_pop PROTO((void)); -static inline tree member_declared_type PROTO((tree)); -static char *function_start_label PROTO((tree)); -static void output_array_type_die PROTO((void *)); -static void output_set_type_die PROTO((void *)); -#if 0 -static void output_entry_point_die PROTO((void *)); -#endif -static void output_inlined_enumeration_type_die PROTO((void *)); -static void output_inlined_structure_type_die PROTO((void *)); -static void output_inlined_union_type_die PROTO((void *)); -static void output_enumeration_type_die PROTO((void *)); -static void output_formal_parameter_die PROTO((void *)); -static void output_global_subroutine_die PROTO((void *)); -static void output_global_variable_die PROTO((void *)); -static void output_label_die PROTO((void *)); -static void output_lexical_block_die PROTO((void *)); -static void output_inlined_subroutine_die PROTO((void *)); -static void output_local_variable_die PROTO((void *)); -static void output_member_die PROTO((void *)); -#if 0 -static void output_pointer_type_die PROTO((void *)); -static void output_reference_type_die PROTO((void *)); -#endif -static void output_ptr_to_mbr_type_die PROTO((void *)); -static void output_compile_unit_die PROTO((void *)); -static void output_string_type_die PROTO((void *)); -static void output_inheritance_die PROTO((void *)); -static void output_structure_type_die PROTO((void *)); -static void output_local_subroutine_die PROTO((void *)); -static void output_subroutine_type_die PROTO((void *)); -static void output_typedef_die PROTO((void *)); -static void output_union_type_die PROTO((void *)); -static void output_unspecified_parameters_die PROTO((void *)); -static void output_padded_null_die PROTO((void *)); -static void output_die PROTO((void (*) PROTO((void *)), void *)); -static void end_sibling_chain PROTO((void)); -static void output_formal_types PROTO((tree)); -static void pend_type PROTO((tree)); -static int type_ok_for_scope PROTO((tree, tree)); -static void output_pending_types_for_scope PROTO((tree)); -static void output_type PROTO((tree, tree)); -static void output_tagged_type_instantiation PROTO((tree)); -static void output_block PROTO((tree, int)); -static void output_decls_for_scope PROTO((tree, int)); -static void output_decl PROTO((tree, tree)); -static void shuffle_filename_entry PROTO((filename_entry *)); -static void generate_new_sfname_entry PROTO((void)); -static unsigned lookup_filename PROTO((char *)); -static void generate_srcinfo_entry PROTO((unsigned, unsigned)); -static void generate_macinfo_entry PROTO((char *, char *)); -static int is_pseudo_reg PROTO((rtx)); -static tree type_main_variant PROTO((tree)); -static int is_tagged_type PROTO((tree)); -static int is_redundant_typedef PROTO((tree)); - -/* Definitions of defaults for assembler-dependent names of various - pseudo-ops and section names. - - Theses may be overridden in your tm.h file (if necessary) for your - particular assembler. The default values provided here correspond to - what is expected by "standard" AT&T System V.4 assemblers. */ - -#ifndef FILE_ASM_OP -#define FILE_ASM_OP ".file" -#endif -#ifndef VERSION_ASM_OP -#define VERSION_ASM_OP ".version" -#endif -#ifndef UNALIGNED_SHORT_ASM_OP -#define UNALIGNED_SHORT_ASM_OP ".2byte" -#endif -#ifndef UNALIGNED_INT_ASM_OP -#define UNALIGNED_INT_ASM_OP ".4byte" -#endif -#ifndef ASM_BYTE_OP -#define ASM_BYTE_OP ".byte" -#endif -#ifndef SET_ASM_OP -#define SET_ASM_OP ".set" -#endif - -/* Pseudo-ops for pushing the current section onto the section stack (and - simultaneously changing to a new section) and for poping back to the - section we were in immediately before this one. Note that most svr4 - assemblers only maintain a one level stack... you can push all the - sections you want, but you can only pop out one level. (The sparc - svr4 assembler is an exception to this general rule.) That's - OK because we only use at most one level of the section stack herein. */ - -#ifndef PUSHSECTION_ASM_OP -#define PUSHSECTION_ASM_OP ".section" -#endif -#ifndef POPSECTION_ASM_OP -#define POPSECTION_ASM_OP ".previous" -#endif - -/* The default format used by the ASM_OUTPUT_PUSH_SECTION macro (see below) - to print the PUSHSECTION_ASM_OP and the section name. The default here - works for almost all svr4 assemblers, except for the sparc, where the - section name must be enclosed in double quotes. (See sparcv4.h.) */ - -#ifndef PUSHSECTION_FORMAT -#define PUSHSECTION_FORMAT "\t%s\t%s\n" -#endif - -#ifndef DEBUG_SECTION -#define DEBUG_SECTION ".debug" -#endif -#ifndef LINE_SECTION -#define LINE_SECTION ".line" -#endif -#ifndef SFNAMES_SECTION -#define SFNAMES_SECTION ".debug_sfnames" -#endif -#ifndef SRCINFO_SECTION -#define SRCINFO_SECTION ".debug_srcinfo" -#endif -#ifndef MACINFO_SECTION -#define MACINFO_SECTION ".debug_macinfo" -#endif -#ifndef PUBNAMES_SECTION -#define PUBNAMES_SECTION ".debug_pubnames" -#endif -#ifndef ARANGES_SECTION -#define ARANGES_SECTION ".debug_aranges" -#endif -#ifndef TEXT_SECTION -#define TEXT_SECTION ".text" -#endif -#ifndef DATA_SECTION -#define DATA_SECTION ".data" -#endif -#ifndef DATA1_SECTION -#define DATA1_SECTION ".data1" -#endif -#ifndef RODATA_SECTION -#define RODATA_SECTION ".rodata" -#endif -#ifndef RODATA1_SECTION -#define RODATA1_SECTION ".rodata1" -#endif -#ifndef BSS_SECTION -#define BSS_SECTION ".bss" -#endif - -/* Definitions of defaults for formats and names of various special - (artificial) labels which may be generated within this file (when - the -g options is used and DWARF_DEBUGGING_INFO is in effect. - - If necessary, these may be overridden from within your tm.h file, - but typically, you should never need to override these. - - These labels have been hacked (temporarily) so that they all begin with - a `.L' sequence so as to appease the stock sparc/svr4 assembler and the - stock m88k/svr4 assembler, both of which need to see .L at the start of - a label in order to prevent that label from going into the linker symbol - table). When I get time, I'll have to fix this the right way so that we - will use ASM_GENERATE_INTERNAL_LABEL and ASM_OUTPUT_INTERNAL_LABEL herein, - but that will require a rather massive set of changes. For the moment, - the following definitions out to produce the right results for all svr4 - and svr3 assemblers. -- rfg -*/ - -#ifndef TEXT_BEGIN_LABEL -#define TEXT_BEGIN_LABEL "*.L_text_b" -#endif -#ifndef TEXT_END_LABEL -#define TEXT_END_LABEL "*.L_text_e" -#endif - -#ifndef DATA_BEGIN_LABEL -#define DATA_BEGIN_LABEL "*.L_data_b" -#endif -#ifndef DATA_END_LABEL -#define DATA_END_LABEL "*.L_data_e" -#endif - -#ifndef DATA1_BEGIN_LABEL -#define DATA1_BEGIN_LABEL "*.L_data1_b" -#endif -#ifndef DATA1_END_LABEL -#define DATA1_END_LABEL "*.L_data1_e" -#endif - -#ifndef RODATA_BEGIN_LABEL -#define RODATA_BEGIN_LABEL "*.L_rodata_b" -#endif -#ifndef RODATA_END_LABEL -#define RODATA_END_LABEL "*.L_rodata_e" -#endif - -#ifndef RODATA1_BEGIN_LABEL -#define RODATA1_BEGIN_LABEL "*.L_rodata1_b" -#endif -#ifndef RODATA1_END_LABEL -#define RODATA1_END_LABEL "*.L_rodata1_e" -#endif - -#ifndef BSS_BEGIN_LABEL -#define BSS_BEGIN_LABEL "*.L_bss_b" -#endif -#ifndef BSS_END_LABEL -#define BSS_END_LABEL "*.L_bss_e" -#endif - -#ifndef LINE_BEGIN_LABEL -#define LINE_BEGIN_LABEL "*.L_line_b" -#endif -#ifndef LINE_LAST_ENTRY_LABEL -#define LINE_LAST_ENTRY_LABEL "*.L_line_last" -#endif -#ifndef LINE_END_LABEL -#define LINE_END_LABEL "*.L_line_e" -#endif - -#ifndef DEBUG_BEGIN_LABEL -#define DEBUG_BEGIN_LABEL "*.L_debug_b" -#endif -#ifndef SFNAMES_BEGIN_LABEL -#define SFNAMES_BEGIN_LABEL "*.L_sfnames_b" -#endif -#ifndef SRCINFO_BEGIN_LABEL -#define SRCINFO_BEGIN_LABEL "*.L_srcinfo_b" -#endif -#ifndef MACINFO_BEGIN_LABEL -#define MACINFO_BEGIN_LABEL "*.L_macinfo_b" -#endif - -#ifndef DIE_BEGIN_LABEL_FMT -#define DIE_BEGIN_LABEL_FMT "*.L_D%u" -#endif -#ifndef DIE_END_LABEL_FMT -#define DIE_END_LABEL_FMT "*.L_D%u_e" -#endif -#ifndef PUB_DIE_LABEL_FMT -#define PUB_DIE_LABEL_FMT "*.L_P%u" -#endif -#ifndef INSN_LABEL_FMT -#define INSN_LABEL_FMT "*.L_I%u_%u" -#endif -#ifndef BLOCK_BEGIN_LABEL_FMT -#define BLOCK_BEGIN_LABEL_FMT "*.L_B%u" -#endif -#ifndef BLOCK_END_LABEL_FMT -#define BLOCK_END_LABEL_FMT "*.L_B%u_e" -#endif -#ifndef SS_BEGIN_LABEL_FMT -#define SS_BEGIN_LABEL_FMT "*.L_s%u" -#endif -#ifndef SS_END_LABEL_FMT -#define SS_END_LABEL_FMT "*.L_s%u_e" -#endif -#ifndef EE_BEGIN_LABEL_FMT -#define EE_BEGIN_LABEL_FMT "*.L_e%u" -#endif -#ifndef EE_END_LABEL_FMT -#define EE_END_LABEL_FMT "*.L_e%u_e" -#endif -#ifndef MT_BEGIN_LABEL_FMT -#define MT_BEGIN_LABEL_FMT "*.L_t%u" -#endif -#ifndef MT_END_LABEL_FMT -#define MT_END_LABEL_FMT "*.L_t%u_e" -#endif -#ifndef LOC_BEGIN_LABEL_FMT -#define LOC_BEGIN_LABEL_FMT "*.L_l%u" -#endif -#ifndef LOC_END_LABEL_FMT -#define LOC_END_LABEL_FMT "*.L_l%u_e" -#endif -#ifndef BOUND_BEGIN_LABEL_FMT -#define BOUND_BEGIN_LABEL_FMT "*.L_b%u_%u_%c" -#endif -#ifndef BOUND_END_LABEL_FMT -#define BOUND_END_LABEL_FMT "*.L_b%u_%u_%c_e" -#endif -#ifndef DERIV_BEGIN_LABEL_FMT -#define DERIV_BEGIN_LABEL_FMT "*.L_d%u" -#endif -#ifndef DERIV_END_LABEL_FMT -#define DERIV_END_LABEL_FMT "*.L_d%u_e" -#endif -#ifndef SL_BEGIN_LABEL_FMT -#define SL_BEGIN_LABEL_FMT "*.L_sl%u" -#endif -#ifndef SL_END_LABEL_FMT -#define SL_END_LABEL_FMT "*.L_sl%u_e" -#endif -#ifndef BODY_BEGIN_LABEL_FMT -#define BODY_BEGIN_LABEL_FMT "*.L_b%u" -#endif -#ifndef BODY_END_LABEL_FMT -#define BODY_END_LABEL_FMT "*.L_b%u_e" -#endif -#ifndef FUNC_END_LABEL_FMT -#define FUNC_END_LABEL_FMT "*.L_f%u_e" -#endif -#ifndef TYPE_NAME_FMT -#define TYPE_NAME_FMT "*.L_T%u" -#endif -#ifndef DECL_NAME_FMT -#define DECL_NAME_FMT "*.L_E%u" -#endif -#ifndef LINE_CODE_LABEL_FMT -#define LINE_CODE_LABEL_FMT "*.L_LC%u" -#endif -#ifndef SFNAMES_ENTRY_LABEL_FMT -#define SFNAMES_ENTRY_LABEL_FMT "*.L_F%u" -#endif -#ifndef LINE_ENTRY_LABEL_FMT -#define LINE_ENTRY_LABEL_FMT "*.L_LE%u" -#endif - -/* Definitions of defaults for various types of primitive assembly language - output operations. - - If necessary, these may be overridden from within your tm.h file, - but typically, you shouldn't need to override these. */ - -#ifndef ASM_OUTPUT_PUSH_SECTION -#define ASM_OUTPUT_PUSH_SECTION(FILE, SECTION) \ - fprintf ((FILE), PUSHSECTION_FORMAT, PUSHSECTION_ASM_OP, SECTION) -#endif - -#ifndef ASM_OUTPUT_POP_SECTION -#define ASM_OUTPUT_POP_SECTION(FILE) \ - fprintf ((FILE), "\t%s\n", POPSECTION_ASM_OP) -#endif - -#ifndef ASM_OUTPUT_DWARF_DELTA2 -#define ASM_OUTPUT_DWARF_DELTA2(FILE,LABEL1,LABEL2) \ - do { fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \ - assemble_name (FILE, LABEL1); \ - fprintf (FILE, "-"); \ - assemble_name (FILE, LABEL2); \ - fprintf (FILE, "\n"); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_DELTA4 -#define ASM_OUTPUT_DWARF_DELTA4(FILE,LABEL1,LABEL2) \ - do { fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \ - assemble_name (FILE, LABEL1); \ - fprintf (FILE, "-"); \ - assemble_name (FILE, LABEL2); \ - fprintf (FILE, "\n"); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_TAG -#define ASM_OUTPUT_DWARF_TAG(FILE,TAG) \ - do { \ - fprintf ((FILE), "\t%s\t0x%x", \ - UNALIGNED_SHORT_ASM_OP, (unsigned) TAG); \ - if (flag_debug_asm) \ - fprintf ((FILE), "\t%s %s", \ - ASM_COMMENT_START, dwarf_tag_name (TAG)); \ - fputc ('\n', (FILE)); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_ATTRIBUTE -#define ASM_OUTPUT_DWARF_ATTRIBUTE(FILE,ATTR) \ - do { \ - fprintf ((FILE), "\t%s\t0x%x", \ - UNALIGNED_SHORT_ASM_OP, (unsigned) ATTR); \ - if (flag_debug_asm) \ - fprintf ((FILE), "\t%s %s", \ - ASM_COMMENT_START, dwarf_attr_name (ATTR)); \ - fputc ('\n', (FILE)); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_STACK_OP -#define ASM_OUTPUT_DWARF_STACK_OP(FILE,OP) \ - do { \ - fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) OP); \ - if (flag_debug_asm) \ - fprintf ((FILE), "\t%s %s", \ - ASM_COMMENT_START, dwarf_stack_op_name (OP)); \ - fputc ('\n', (FILE)); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_FUND_TYPE -#define ASM_OUTPUT_DWARF_FUND_TYPE(FILE,FT) \ - do { \ - fprintf ((FILE), "\t%s\t0x%x", \ - UNALIGNED_SHORT_ASM_OP, (unsigned) FT); \ - if (flag_debug_asm) \ - fprintf ((FILE), "\t%s %s", \ - ASM_COMMENT_START, dwarf_fund_type_name (FT)); \ - fputc ('\n', (FILE)); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_FMT_BYTE -#define ASM_OUTPUT_DWARF_FMT_BYTE(FILE,FMT) \ - do { \ - fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) FMT); \ - if (flag_debug_asm) \ - fprintf ((FILE), "\t%s %s", \ - ASM_COMMENT_START, dwarf_fmt_byte_name (FMT)); \ - fputc ('\n', (FILE)); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_TYPE_MODIFIER -#define ASM_OUTPUT_DWARF_TYPE_MODIFIER(FILE,MOD) \ - do { \ - fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) MOD); \ - if (flag_debug_asm) \ - fprintf ((FILE), "\t%s %s", \ - ASM_COMMENT_START, dwarf_typemod_name (MOD)); \ - fputc ('\n', (FILE)); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_ADDR -#define ASM_OUTPUT_DWARF_ADDR(FILE,LABEL) \ - do { fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \ - assemble_name (FILE, LABEL); \ - fprintf (FILE, "\n"); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_ADDR_CONST -#define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,RTX) \ - do { \ - fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \ - output_addr_const ((FILE), (RTX)); \ - fputc ('\n', (FILE)); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_REF -#define ASM_OUTPUT_DWARF_REF(FILE,LABEL) \ - do { fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \ - assemble_name (FILE, LABEL); \ - fprintf (FILE, "\n"); \ - } while (0) -#endif - -#ifndef ASM_OUTPUT_DWARF_DATA1 -#define ASM_OUTPUT_DWARF_DATA1(FILE,VALUE) \ - fprintf ((FILE), "\t%s\t0x%x\n", ASM_BYTE_OP, VALUE) -#endif - -#ifndef ASM_OUTPUT_DWARF_DATA2 -#define ASM_OUTPUT_DWARF_DATA2(FILE,VALUE) \ - fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_SHORT_ASM_OP, (unsigned short) VALUE) -#endif - -#ifndef ASM_OUTPUT_DWARF_DATA4 -#define ASM_OUTPUT_DWARF_DATA4(FILE,VALUE) \ - fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, (unsigned) VALUE) -#endif - -#ifndef ASM_OUTPUT_DWARF_DATA8 -#define ASM_OUTPUT_DWARF_DATA8(FILE,HIGH_VALUE,LOW_VALUE) \ - do { \ - if (WORDS_BIG_ENDIAN) \ - { \ - fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, HIGH_VALUE); \ - fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, LOW_VALUE);\ - } \ - else \ - { \ - fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, LOW_VALUE);\ - fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, HIGH_VALUE); \ - } \ - } while (0) -#endif - -/* ASM_OUTPUT_DWARF_STRING is defined to output an ascii string, but to - NOT issue a trailing newline. We define ASM_OUTPUT_DWARF_STRING_NEWLINE - based on whether ASM_OUTPUT_DWARF_STRING is defined or not. If it is - defined, we call it, then issue the line feed. If not, we supply a - default defintion of calling ASM_OUTPUT_ASCII */ - -#ifndef ASM_OUTPUT_DWARF_STRING -#define ASM_OUTPUT_DWARF_STRING_NEWLINE(FILE,P) \ - ASM_OUTPUT_ASCII ((FILE), P, strlen (P)+1) -#else -#define ASM_OUTPUT_DWARF_STRING_NEWLINE(FILE,P) \ - ASM_OUTPUT_DWARF_STRING (FILE,P), ASM_OUTPUT_DWARF_STRING (FILE,"\n") -#endif - - -/************************ general utility functions **************************/ - -inline static int -is_pseudo_reg (rtl) - register rtx rtl; -{ - return (((GET_CODE (rtl) == REG) && (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)) - || ((GET_CODE (rtl) == SUBREG) - && (REGNO (XEXP (rtl, 0)) >= FIRST_PSEUDO_REGISTER))); -} - -inline static tree -type_main_variant (type) - register tree type; -{ - type = TYPE_MAIN_VARIANT (type); - - /* There really should be only one main variant among any group of variants - of a given type (and all of the MAIN_VARIANT values for all members of - the group should point to that one type) but sometimes the C front-end - messes this up for array types, so we work around that bug here. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - while (type != TYPE_MAIN_VARIANT (type)) - type = TYPE_MAIN_VARIANT (type); - } - - return type; -} - -/* Return non-zero if the given type node represents a tagged type. */ - -inline static int -is_tagged_type (type) - register tree type; -{ - register enum tree_code code = TREE_CODE (type); - - return (code == RECORD_TYPE || code == UNION_TYPE - || code == QUAL_UNION_TYPE || code == ENUMERAL_TYPE); -} - -static char * -dwarf_tag_name (tag) - register unsigned tag; -{ - switch (tag) - { - case TAG_padding: return "TAG_padding"; - case TAG_array_type: return "TAG_array_type"; - case TAG_class_type: return "TAG_class_type"; - case TAG_entry_point: return "TAG_entry_point"; - case TAG_enumeration_type: return "TAG_enumeration_type"; - case TAG_formal_parameter: return "TAG_formal_parameter"; - case TAG_global_subroutine: return "TAG_global_subroutine"; - case TAG_global_variable: return "TAG_global_variable"; - case TAG_label: return "TAG_label"; - case TAG_lexical_block: return "TAG_lexical_block"; - case TAG_local_variable: return "TAG_local_variable"; - case TAG_member: return "TAG_member"; - case TAG_pointer_type: return "TAG_pointer_type"; - case TAG_reference_type: return "TAG_reference_type"; - case TAG_compile_unit: return "TAG_compile_unit"; - case TAG_string_type: return "TAG_string_type"; - case TAG_structure_type: return "TAG_structure_type"; - case TAG_subroutine: return "TAG_subroutine"; - case TAG_subroutine_type: return "TAG_subroutine_type"; - case TAG_typedef: return "TAG_typedef"; - case TAG_union_type: return "TAG_union_type"; - case TAG_unspecified_parameters: return "TAG_unspecified_parameters"; - case TAG_variant: return "TAG_variant"; - case TAG_common_block: return "TAG_common_block"; - case TAG_common_inclusion: return "TAG_common_inclusion"; - case TAG_inheritance: return "TAG_inheritance"; - case TAG_inlined_subroutine: return "TAG_inlined_subroutine"; - case TAG_module: return "TAG_module"; - case TAG_ptr_to_member_type: return "TAG_ptr_to_member_type"; - case TAG_set_type: return "TAG_set_type"; - case TAG_subrange_type: return "TAG_subrange_type"; - case TAG_with_stmt: return "TAG_with_stmt"; - - /* GNU extensions. */ - - case TAG_format_label: return "TAG_format_label"; - case TAG_namelist: return "TAG_namelist"; - case TAG_function_template: return "TAG_function_template"; - case TAG_class_template: return "TAG_class_template"; - - default: return "TAG_<unknown>"; - } -} - -static char * -dwarf_attr_name (attr) - register unsigned attr; -{ - switch (attr) - { - case AT_sibling: return "AT_sibling"; - case AT_location: return "AT_location"; - case AT_name: return "AT_name"; - case AT_fund_type: return "AT_fund_type"; - case AT_mod_fund_type: return "AT_mod_fund_type"; - case AT_user_def_type: return "AT_user_def_type"; - case AT_mod_u_d_type: return "AT_mod_u_d_type"; - case AT_ordering: return "AT_ordering"; - case AT_subscr_data: return "AT_subscr_data"; - case AT_byte_size: return "AT_byte_size"; - case AT_bit_offset: return "AT_bit_offset"; - case AT_bit_size: return "AT_bit_size"; - case AT_element_list: return "AT_element_list"; - case AT_stmt_list: return "AT_stmt_list"; - case AT_low_pc: return "AT_low_pc"; - case AT_high_pc: return "AT_high_pc"; - case AT_language: return "AT_language"; - case AT_member: return "AT_member"; - case AT_discr: return "AT_discr"; - case AT_discr_value: return "AT_discr_value"; - case AT_string_length: return "AT_string_length"; - case AT_common_reference: return "AT_common_reference"; - case AT_comp_dir: return "AT_comp_dir"; - case AT_const_value_string: return "AT_const_value_string"; - case AT_const_value_data2: return "AT_const_value_data2"; - case AT_const_value_data4: return "AT_const_value_data4"; - case AT_const_value_data8: return "AT_const_value_data8"; - case AT_const_value_block2: return "AT_const_value_block2"; - case AT_const_value_block4: return "AT_const_value_block4"; - case AT_containing_type: return "AT_containing_type"; - case AT_default_value_addr: return "AT_default_value_addr"; - case AT_default_value_data2: return "AT_default_value_data2"; - case AT_default_value_data4: return "AT_default_value_data4"; - case AT_default_value_data8: return "AT_default_value_data8"; - case AT_default_value_string: return "AT_default_value_string"; - case AT_friends: return "AT_friends"; - case AT_inline: return "AT_inline"; - case AT_is_optional: return "AT_is_optional"; - case AT_lower_bound_ref: return "AT_lower_bound_ref"; - case AT_lower_bound_data2: return "AT_lower_bound_data2"; - case AT_lower_bound_data4: return "AT_lower_bound_data4"; - case AT_lower_bound_data8: return "AT_lower_bound_data8"; - case AT_private: return "AT_private"; - case AT_producer: return "AT_producer"; - case AT_program: return "AT_program"; - case AT_protected: return "AT_protected"; - case AT_prototyped: return "AT_prototyped"; - case AT_public: return "AT_public"; - case AT_pure_virtual: return "AT_pure_virtual"; - case AT_return_addr: return "AT_return_addr"; - case AT_abstract_origin: return "AT_abstract_origin"; - case AT_start_scope: return "AT_start_scope"; - case AT_stride_size: return "AT_stride_size"; - case AT_upper_bound_ref: return "AT_upper_bound_ref"; - case AT_upper_bound_data2: return "AT_upper_bound_data2"; - case AT_upper_bound_data4: return "AT_upper_bound_data4"; - case AT_upper_bound_data8: return "AT_upper_bound_data8"; - case AT_virtual: return "AT_virtual"; - - /* GNU extensions */ - - case AT_sf_names: return "AT_sf_names"; - case AT_src_info: return "AT_src_info"; - case AT_mac_info: return "AT_mac_info"; - case AT_src_coords: return "AT_src_coords"; - case AT_body_begin: return "AT_body_begin"; - case AT_body_end: return "AT_body_end"; - - default: return "AT_<unknown>"; - } -} - -static char * -dwarf_stack_op_name (op) - register unsigned op; -{ - switch (op) - { - case OP_REG: return "OP_REG"; - case OP_BASEREG: return "OP_BASEREG"; - case OP_ADDR: return "OP_ADDR"; - case OP_CONST: return "OP_CONST"; - case OP_DEREF2: return "OP_DEREF2"; - case OP_DEREF4: return "OP_DEREF4"; - case OP_ADD: return "OP_ADD"; - default: return "OP_<unknown>"; - } -} - -static char * -dwarf_typemod_name (mod) - register unsigned mod; -{ - switch (mod) - { - case MOD_pointer_to: return "MOD_pointer_to"; - case MOD_reference_to: return "MOD_reference_to"; - case MOD_const: return "MOD_const"; - case MOD_volatile: return "MOD_volatile"; - default: return "MOD_<unknown>"; - } -} - -static char * -dwarf_fmt_byte_name (fmt) - register unsigned fmt; -{ - switch (fmt) - { - case FMT_FT_C_C: return "FMT_FT_C_C"; - case FMT_FT_C_X: return "FMT_FT_C_X"; - case FMT_FT_X_C: return "FMT_FT_X_C"; - case FMT_FT_X_X: return "FMT_FT_X_X"; - case FMT_UT_C_C: return "FMT_UT_C_C"; - case FMT_UT_C_X: return "FMT_UT_C_X"; - case FMT_UT_X_C: return "FMT_UT_X_C"; - case FMT_UT_X_X: return "FMT_UT_X_X"; - case FMT_ET: return "FMT_ET"; - default: return "FMT_<unknown>"; - } -} - -static char * -dwarf_fund_type_name (ft) - register unsigned ft; -{ - switch (ft) - { - case FT_char: return "FT_char"; - case FT_signed_char: return "FT_signed_char"; - case FT_unsigned_char: return "FT_unsigned_char"; - case FT_short: return "FT_short"; - case FT_signed_short: return "FT_signed_short"; - case FT_unsigned_short: return "FT_unsigned_short"; - case FT_integer: return "FT_integer"; - case FT_signed_integer: return "FT_signed_integer"; - case FT_unsigned_integer: return "FT_unsigned_integer"; - case FT_long: return "FT_long"; - case FT_signed_long: return "FT_signed_long"; - case FT_unsigned_long: return "FT_unsigned_long"; - case FT_pointer: return "FT_pointer"; - case FT_float: return "FT_float"; - case FT_dbl_prec_float: return "FT_dbl_prec_float"; - case FT_ext_prec_float: return "FT_ext_prec_float"; - case FT_complex: return "FT_complex"; - case FT_dbl_prec_complex: return "FT_dbl_prec_complex"; - case FT_void: return "FT_void"; - case FT_boolean: return "FT_boolean"; - case FT_ext_prec_complex: return "FT_ext_prec_complex"; - case FT_label: return "FT_label"; - - /* GNU extensions. */ - - case FT_long_long: return "FT_long_long"; - case FT_signed_long_long: return "FT_signed_long_long"; - case FT_unsigned_long_long: return "FT_unsigned_long_long"; - - case FT_int8: return "FT_int8"; - case FT_signed_int8: return "FT_signed_int8"; - case FT_unsigned_int8: return "FT_unsigned_int8"; - case FT_int16: return "FT_int16"; - case FT_signed_int16: return "FT_signed_int16"; - case FT_unsigned_int16: return "FT_unsigned_int16"; - case FT_int32: return "FT_int32"; - case FT_signed_int32: return "FT_signed_int32"; - case FT_unsigned_int32: return "FT_unsigned_int32"; - case FT_int64: return "FT_int64"; - case FT_signed_int64: return "FT_signed_int64"; - case FT_unsigned_int64: return "FT_unsigned_int64"; - - case FT_real32: return "FT_real32"; - case FT_real64: return "FT_real64"; - case FT_real96: return "FT_real96"; - case FT_real128: return "FT_real128"; - - default: return "FT_<unknown>"; - } -} - -/* Determine the "ultimate origin" of a decl. The decl may be an - inlined instance of an inlined instance of a decl which is local - to an inline function, so we have to trace all of the way back - through the origin chain to find out what sort of node actually - served as the original seed for the given block. */ - -static tree -decl_ultimate_origin (decl) - register tree decl; -{ -#ifdef ENABLE_CHECKING - if (DECL_FROM_INLINE (DECL_ORIGIN (decl))) - /* Since the DECL_ABSTRACT_ORIGIN for a DECL is supposed to be the - most distant ancestor, this should never happen. */ - abort (); -#endif - - return DECL_ABSTRACT_ORIGIN (decl); -} - -/* Determine the "ultimate origin" of a block. The block may be an - inlined instance of an inlined instance of a block which is local - to an inline function, so we have to trace all of the way back - through the origin chain to find out what sort of node actually - served as the original seed for the given block. */ - -static tree -block_ultimate_origin (block) - register tree block; -{ - register tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block); - - if (immediate_origin == NULL) - return NULL; - else - { - register tree ret_val; - register tree lookahead = immediate_origin; - - do - { - ret_val = lookahead; - lookahead = (TREE_CODE (ret_val) == BLOCK) - ? BLOCK_ABSTRACT_ORIGIN (ret_val) - : NULL; - } - while (lookahead != NULL && lookahead != ret_val); - return ret_val; - } -} - -/* Get the class to which DECL belongs, if any. In g++, the DECL_CONTEXT - of a virtual function may refer to a base class, so we check the 'this' - parameter. */ - -static tree -decl_class_context (decl) - tree decl; -{ - tree context = NULL_TREE; - if (TREE_CODE (decl) != FUNCTION_DECL || ! DECL_VINDEX (decl)) - context = DECL_CONTEXT (decl); - else - context = TYPE_MAIN_VARIANT - (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))))); - - if (context && TREE_CODE_CLASS (TREE_CODE (context)) != 't') - context = NULL_TREE; - - return context; -} - -#if 0 -static void -output_unsigned_leb128 (value) - register unsigned long value; -{ - register unsigned long orig_value = value; - - do - { - register unsigned byte = (value & 0x7f); - - value >>= 7; - if (value != 0) /* more bytes to follow */ - byte |= 0x80; - fprintf (asm_out_file, "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) byte); - if (flag_debug_asm && value == 0) - fprintf (asm_out_file, "\t%s ULEB128 number - value = %lu", - ASM_COMMENT_START, orig_value); - fputc ('\n', asm_out_file); - } - while (value != 0); -} - -static void -output_signed_leb128 (value) - register long value; -{ - register long orig_value = value; - register int negative = (value < 0); - register int more; - - do - { - register unsigned byte = (value & 0x7f); - - value >>= 7; - if (negative) - value |= 0xfe000000; /* manually sign extend */ - if (((value == 0) && ((byte & 0x40) == 0)) - || ((value == -1) && ((byte & 0x40) == 1))) - more = 0; - else - { - byte |= 0x80; - more = 1; - } - fprintf (asm_out_file, "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) byte); - if (flag_debug_asm && more == 0) - fprintf (asm_out_file, "\t%s SLEB128 number - value = %ld", - ASM_COMMENT_START, orig_value); - fputc ('\n', asm_out_file); - } - while (more); -} -#endif - -/**************** utility functions for attribute functions ******************/ - -/* Given a pointer to a BLOCK node return non-zero if (and only if) the - node in question represents the outermost pair of curly braces (i.e. - the "body block") of a function or method. - - For any BLOCK node representing a "body block" of a function or method, - the BLOCK_SUPERCONTEXT of the node will point to another BLOCK node - which represents the outermost (function) scope for the function or - method (i.e. the one which includes the formal parameters). The - BLOCK_SUPERCONTEXT of *that* node in turn will point to the relevant - FUNCTION_DECL node. -*/ - -static inline int -is_body_block (stmt) - register tree stmt; -{ - if (TREE_CODE (stmt) == BLOCK) - { - register tree parent = BLOCK_SUPERCONTEXT (stmt); - - if (TREE_CODE (parent) == BLOCK) - { - register tree grandparent = BLOCK_SUPERCONTEXT (parent); - - if (TREE_CODE (grandparent) == FUNCTION_DECL) - return 1; - } - } - return 0; -} - -/* Given a pointer to a tree node for some type, return a Dwarf fundamental - type code for the given type. - - This routine must only be called for GCC type nodes that correspond to - Dwarf fundamental types. - - The current Dwarf draft specification calls for Dwarf fundamental types - to accurately reflect the fact that a given type was either a "plain" - integral type or an explicitly "signed" integral type. Unfortunately, - we can't always do this, because GCC may already have thrown away the - information about the precise way in which the type was originally - specified, as in: - - typedef signed int my_type; - - struct s { my_type f; }; - - Since we may be stuck here without enought information to do exactly - what is called for in the Dwarf draft specification, we do the best - that we can under the circumstances and always use the "plain" integral - fundamental type codes for int, short, and long types. That's probably - good enough. The additional accuracy called for in the current DWARF - draft specification is probably never even useful in practice. */ - -static int -fundamental_type_code (type) - register tree type; -{ - if (TREE_CODE (type) == ERROR_MARK) - return 0; - - switch (TREE_CODE (type)) - { - case ERROR_MARK: - return FT_void; - - case VOID_TYPE: - return FT_void; - - case INTEGER_TYPE: - /* Carefully distinguish all the standard types of C, - without messing up if the language is not C. - Note that we check only for the names that contain spaces; - other names might occur by coincidence in other languages. */ - if (TYPE_NAME (type) != 0 - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (type)) != 0 - && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) - { - char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - - if (!strcmp (name, "unsigned char")) - return FT_unsigned_char; - if (!strcmp (name, "signed char")) - return FT_signed_char; - if (!strcmp (name, "unsigned int")) - return FT_unsigned_integer; - if (!strcmp (name, "short int")) - return FT_short; - if (!strcmp (name, "short unsigned int")) - return FT_unsigned_short; - if (!strcmp (name, "long int")) - return FT_long; - if (!strcmp (name, "long unsigned int")) - return FT_unsigned_long; - if (!strcmp (name, "long long int")) - return FT_long_long; /* Not grok'ed by svr4 SDB */ - if (!strcmp (name, "long long unsigned int")) - return FT_unsigned_long_long; /* Not grok'ed by svr4 SDB */ - } - - /* Most integer types will be sorted out above, however, for the - sake of special `array index' integer types, the following code - is also provided. */ - - if (TYPE_PRECISION (type) == INT_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? FT_unsigned_integer : FT_integer); - - if (TYPE_PRECISION (type) == LONG_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? FT_unsigned_long : FT_long); - - if (TYPE_PRECISION (type) == LONG_LONG_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? FT_unsigned_long_long : FT_long_long); - - if (TYPE_PRECISION (type) == SHORT_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? FT_unsigned_short : FT_short); - - if (TYPE_PRECISION (type) == CHAR_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? FT_unsigned_char : FT_char); - - abort (); - - case REAL_TYPE: - /* Carefully distinguish all the standard types of C, - without messing up if the language is not C. */ - if (TYPE_NAME (type) != 0 - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (type)) != 0 - && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) - { - char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - - /* Note that here we can run afowl of a serious bug in "classic" - svr4 SDB debuggers. They don't seem to understand the - FT_ext_prec_float type (even though they should). */ - - if (!strcmp (name, "long double")) - return FT_ext_prec_float; - } - - if (TYPE_PRECISION (type) == DOUBLE_TYPE_SIZE) - { - /* On the SH, when compiling with -m3e or -m4-single-only, both - float and double are 32 bits. But since the debugger doesn't - know about the subtarget, it always thinks double is 64 bits. - So we have to tell the debugger that the type is float to - make the output of the 'print' command etc. readable. */ - if (DOUBLE_TYPE_SIZE == FLOAT_TYPE_SIZE && FLOAT_TYPE_SIZE == 32) - return FT_float; - return FT_dbl_prec_float; - } - if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE) - return FT_float; - - /* Note that here we can run afowl of a serious bug in "classic" - svr4 SDB debuggers. They don't seem to understand the - FT_ext_prec_float type (even though they should). */ - - if (TYPE_PRECISION (type) == LONG_DOUBLE_TYPE_SIZE) - return FT_ext_prec_float; - abort (); - - case COMPLEX_TYPE: - return FT_complex; /* GNU FORTRAN COMPLEX type. */ - - case CHAR_TYPE: - return FT_char; /* GNU Pascal CHAR type. Not used in C. */ - - case BOOLEAN_TYPE: - return FT_boolean; /* GNU FORTRAN BOOLEAN type. */ - - default: - abort (); /* No other TREE_CODEs are Dwarf fundamental types. */ - } - return 0; -} - -/* Given a pointer to an arbitrary ..._TYPE tree node, return a pointer to - the Dwarf "root" type for the given input type. The Dwarf "root" type - of a given type is generally the same as the given type, except that if - the given type is a pointer or reference type, then the root type of - the given type is the root type of the "basis" type for the pointer or - reference type. (This definition of the "root" type is recursive.) - Also, the root type of a `const' qualified type or a `volatile' - qualified type is the root type of the given type without the - qualifiers. */ - -static tree -root_type_1 (type, count) - register tree type; - register int count; -{ - /* Give up after searching 1000 levels, in case this is a recursive - pointer type. Such types are possible in Ada, but it is not possible - to represent them in DWARF1 debug info. */ - if (count > 1000) - return error_mark_node; - - switch (TREE_CODE (type)) - { - case ERROR_MARK: - return error_mark_node; - - case POINTER_TYPE: - case REFERENCE_TYPE: - return root_type_1 (TREE_TYPE (type), count+1); - - default: - return type; - } -} - -static tree -root_type (type) - register tree type; -{ - type = root_type_1 (type, 0); - if (type != error_mark_node) - type = type_main_variant (type); - return type; -} - -/* Given a pointer to an arbitrary ..._TYPE tree node, write out a sequence - of zero or more Dwarf "type-modifier" bytes applicable to the type. */ - -static void -write_modifier_bytes_1 (type, decl_const, decl_volatile, count) - register tree type; - register int decl_const; - register int decl_volatile; - register int count; -{ - if (TREE_CODE (type) == ERROR_MARK) - return; - - /* Give up after searching 1000 levels, in case this is a recursive - pointer type. Such types are possible in Ada, but it is not possible - to represent them in DWARF1 debug info. */ - if (count > 1000) - return; - - if (TYPE_READONLY (type) || decl_const) - ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_const); - if (TYPE_VOLATILE (type) || decl_volatile) - ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_volatile); - switch (TREE_CODE (type)) - { - case POINTER_TYPE: - ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_pointer_to); - write_modifier_bytes_1 (TREE_TYPE (type), 0, 0, count+1); - return; - - case REFERENCE_TYPE: - ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_reference_to); - write_modifier_bytes_1 (TREE_TYPE (type), 0, 0, count+1); - return; - - case ERROR_MARK: - default: - return; - } -} - -static void -write_modifier_bytes (type, decl_const, decl_volatile) - register tree type; - register int decl_const; - register int decl_volatile; -{ - write_modifier_bytes_1 (type, decl_const, decl_volatile, 0); -} - -/* Given a pointer to an arbitrary ..._TYPE tree node, return non-zero if the - given input type is a Dwarf "fundamental" type. Otherwise return zero. */ - -static inline int -type_is_fundamental (type) - register tree type; -{ - switch (TREE_CODE (type)) - { - case ERROR_MARK: - case VOID_TYPE: - case INTEGER_TYPE: - case REAL_TYPE: - case COMPLEX_TYPE: - case BOOLEAN_TYPE: - case CHAR_TYPE: - return 1; - - case SET_TYPE: - case ARRAY_TYPE: - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - case ENUMERAL_TYPE: - case FUNCTION_TYPE: - case METHOD_TYPE: - case POINTER_TYPE: - case REFERENCE_TYPE: - case FILE_TYPE: - case OFFSET_TYPE: - case LANG_TYPE: - return 0; - - default: - abort (); - } - return 0; -} - -/* Given a pointer to some ..._DECL tree node, generate an assembly language - equate directive which will associate a symbolic name with the current DIE. - - The name used is an artificial label generated from the DECL_UID number - associated with the given decl node. The name it gets equated to is the - symbolic label that we (previously) output at the start of the DIE that - we are currently generating. - - Calling this function while generating some "decl related" form of DIE - makes it possible to later refer to the DIE which represents the given - decl simply by re-generating the symbolic name from the ..._DECL node's - UID number. */ - -static void -equate_decl_number_to_die_number (decl) - register tree decl; -{ - /* In the case where we are generating a DIE for some ..._DECL node - which represents either some inline function declaration or some - entity declared within an inline function declaration/definition, - setup a symbolic name for the current DIE so that we have a name - for this DIE that we can easily refer to later on within - AT_abstract_origin attributes. */ - - char decl_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char die_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - sprintf (decl_label, DECL_NAME_FMT, DECL_UID (decl)); - sprintf (die_label, DIE_BEGIN_LABEL_FMT, current_dienum); - ASM_OUTPUT_DEF (asm_out_file, decl_label, die_label); -} - -/* Given a pointer to some ..._TYPE tree node, generate an assembly language - equate directive which will associate a symbolic name with the current DIE. - - The name used is an artificial label generated from the TYPE_UID number - associated with the given type node. The name it gets equated to is the - symbolic label that we (previously) output at the start of the DIE that - we are currently generating. - - Calling this function while generating some "type related" form of DIE - makes it easy to later refer to the DIE which represents the given type - simply by re-generating the alternative name from the ..._TYPE node's - UID number. */ - -static inline void -equate_type_number_to_die_number (type) - register tree type; -{ - char type_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char die_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - /* We are generating a DIE to represent the main variant of this type - (i.e the type without any const or volatile qualifiers) so in order - to get the equate to come out right, we need to get the main variant - itself here. */ - - type = type_main_variant (type); - - sprintf (type_label, TYPE_NAME_FMT, TYPE_UID (type)); - sprintf (die_label, DIE_BEGIN_LABEL_FMT, current_dienum); - ASM_OUTPUT_DEF (asm_out_file, type_label, die_label); -} - -static void -output_reg_number (rtl) - register rtx rtl; -{ - register unsigned regno = REGNO (rtl); - - if (regno >= FIRST_PSEUDO_REGISTER) - { - warning_with_decl (dwarf_last_decl, "internal regno botch: regno = %d\n", - regno); - regno = 0; - } - fprintf (asm_out_file, "\t%s\t0x%x", - UNALIGNED_INT_ASM_OP, DBX_REGISTER_NUMBER (regno)); - if (flag_debug_asm) - { - fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); - PRINT_REG (rtl, 0, asm_out_file); - } - fputc ('\n', asm_out_file); -} - -/* The following routine is a nice and simple transducer. It converts the - RTL for a variable or parameter (resident in memory) into an equivalent - Dwarf representation of a mechanism for getting the address of that same - variable onto the top of a hypothetical "address evaluation" stack. - - When creating memory location descriptors, we are effectively trans- - forming the RTL for a memory-resident object into its Dwarf postfix - expression equivalent. This routine just recursively descends an - RTL tree, turning it into Dwarf postfix code as it goes. */ - -static void -output_mem_loc_descriptor (rtl) - register rtx rtl; -{ - /* Note that for a dynamically sized array, the location we will - generate a description of here will be the lowest numbered location - which is actually within the array. That's *not* necessarily the - same as the zeroth element of the array. */ - - switch (GET_CODE (rtl)) - { - case SUBREG: - - /* The case of a subreg may arise when we have a local (register) - variable or a formal (register) parameter which doesn't quite - fill up an entire register. For now, just assume that it is - legitimate to make the Dwarf info refer to the whole register - which contains the given subreg. */ - - rtl = XEXP (rtl, 0); - /* Drop thru. */ - - case REG: - - /* Whenever a register number forms a part of the description of - the method for calculating the (dynamic) address of a memory - resident object, DWARF rules require the register number to - be referred to as a "base register". This distinction is not - based in any way upon what category of register the hardware - believes the given register belongs to. This is strictly - DWARF terminology we're dealing with here. - - Note that in cases where the location of a memory-resident data - object could be expressed as: - - OP_ADD (OP_BASEREG (basereg), OP_CONST (0)) - - the actual DWARF location descriptor that we generate may just - be OP_BASEREG (basereg). This may look deceptively like the - object in question was allocated to a register (rather than - in memory) so DWARF consumers need to be aware of the subtle - distinction between OP_REG and OP_BASEREG. */ - - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_BASEREG); - output_reg_number (rtl); - break; - - case MEM: - output_mem_loc_descriptor (XEXP (rtl, 0)); - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_DEREF4); - break; - - case CONST: - case SYMBOL_REF: - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADDR); - ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, rtl); - break; - - case PLUS: - output_mem_loc_descriptor (XEXP (rtl, 0)); - output_mem_loc_descriptor (XEXP (rtl, 1)); - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADD); - break; - - case CONST_INT: - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_CONST); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, INTVAL (rtl)); - break; - - case MULT: - /* If a pseudo-reg is optimized away, it is possible for it to - be replaced with a MEM containing a multiply. Use a GNU extension - to describe it. */ - output_mem_loc_descriptor (XEXP (rtl, 0)); - output_mem_loc_descriptor (XEXP (rtl, 1)); - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_MULT); - break; - - default: - abort (); - } -} - -/* Output a proper Dwarf location descriptor for a variable or parameter - which is either allocated in a register or in a memory location. For - a register, we just generate an OP_REG and the register number. For a - memory location we provide a Dwarf postfix expression describing how to - generate the (dynamic) address of the object onto the address stack. */ - -static void -output_loc_descriptor (rtl) - register rtx rtl; -{ - switch (GET_CODE (rtl)) - { - case SUBREG: - - /* The case of a subreg may arise when we have a local (register) - variable or a formal (register) parameter which doesn't quite - fill up an entire register. For now, just assume that it is - legitimate to make the Dwarf info refer to the whole register - which contains the given subreg. */ - - rtl = XEXP (rtl, 0); - /* Drop thru. */ - - case REG: - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_REG); - output_reg_number (rtl); - break; - - case MEM: - output_mem_loc_descriptor (XEXP (rtl, 0)); - break; - - default: - abort (); /* Should never happen */ - } -} - -/* Given a tree node describing an array bound (either lower or upper) - output a representation for that bound. */ - -static void -output_bound_representation (bound, dim_num, u_or_l) - register tree bound; - register unsigned dim_num; /* For multi-dimensional arrays. */ - register char u_or_l; /* Designates upper or lower bound. */ -{ - switch (TREE_CODE (bound)) - { - - case ERROR_MARK: - return; - - /* All fixed-bounds are represented by INTEGER_CST nodes. */ - - case INTEGER_CST: - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, - (unsigned) TREE_INT_CST_LOW (bound)); - break; - - default: - - /* Dynamic bounds may be represented by NOP_EXPR nodes containing - SAVE_EXPR nodes, in which case we can do something, or as - an expression, which we cannot represent. */ - { - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - sprintf (begin_label, BOUND_BEGIN_LABEL_FMT, - current_dienum, dim_num, u_or_l); - - sprintf (end_label, BOUND_END_LABEL_FMT, - current_dienum, dim_num, u_or_l); - - ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - - /* If optimization is turned on, the SAVE_EXPRs that describe - how to access the upper bound values are essentially bogus. - They only describe (at best) how to get at these values at - the points in the generated code right after they have just - been computed. Worse yet, in the typical case, the upper - bound values will not even *be* computed in the optimized - code, so these SAVE_EXPRs are entirely bogus. - - In order to compensate for this fact, we check here to see - if optimization is enabled, and if so, we effectively create - an empty location description for the (unknown and unknowable) - upper bound. - - This should not cause too much trouble for existing (stupid?) - debuggers because they have to deal with empty upper bounds - location descriptions anyway in order to be able to deal with - incomplete array types. - - Of course an intelligent debugger (GDB?) should be able to - comprehend that a missing upper bound specification in a - array type used for a storage class `auto' local array variable - indicates that the upper bound is both unknown (at compile- - time) and unknowable (at run-time) due to optimization. */ - - if (! optimize) - { - while (TREE_CODE (bound) == NOP_EXPR - || TREE_CODE (bound) == CONVERT_EXPR) - bound = TREE_OPERAND (bound, 0); - - if (TREE_CODE (bound) == SAVE_EXPR) - output_loc_descriptor - (eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX)); - } - - ASM_OUTPUT_LABEL (asm_out_file, end_label); - } - break; - - } -} - -/* Recursive function to output a sequence of value/name pairs for - enumeration constants in reversed order. This is called from - enumeration_type_die. */ - -static void -output_enumeral_list (link) - register tree link; -{ - if (link) - { - output_enumeral_list (TREE_CHAIN (link)); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, - (unsigned) TREE_INT_CST_LOW (TREE_VALUE (link))); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, - IDENTIFIER_POINTER (TREE_PURPOSE (link))); - } -} - -/* Given an unsigned value, round it up to the lowest multiple of `boundary' - which is not less than the value itself. */ - -static inline unsigned -ceiling (value, boundary) - register unsigned value; - register unsigned boundary; -{ - return (((value + boundary - 1) / boundary) * boundary); -} - -/* Given a pointer to what is assumed to be a FIELD_DECL node, return a - pointer to the declared type for the relevant field variable, or return - `integer_type_node' if the given node turns out to be an ERROR_MARK node. */ - -static inline tree -field_type (decl) - register tree decl; -{ - register tree type; - - if (TREE_CODE (decl) == ERROR_MARK) - return integer_type_node; - - type = DECL_BIT_FIELD_TYPE (decl); - if (type == NULL) - type = TREE_TYPE (decl); - return type; -} - -/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE - node, return the alignment in bits for the type, or else return - BITS_PER_WORD if the node actually turns out to be an ERROR_MARK node. */ - -static inline unsigned -simple_type_align_in_bits (type) - register tree type; -{ - return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD; -} - -/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE - node, return the size in bits for the type if it is a constant, or - else return the alignment for the type if the type's size is not - constant, or else return BITS_PER_WORD if the type actually turns out - to be an ERROR_MARK node. */ - -static inline unsigned -simple_type_size_in_bits (type) - register tree type; -{ - if (TREE_CODE (type) == ERROR_MARK) - return BITS_PER_WORD; - else - { - register tree type_size_tree = TYPE_SIZE (type); - - if (TREE_CODE (type_size_tree) != INTEGER_CST) - return TYPE_ALIGN (type); - - return (unsigned) TREE_INT_CST_LOW (type_size_tree); - } -} - -/* Given a pointer to what is assumed to be a FIELD_DECL node, compute and - return the byte offset of the lowest addressed byte of the "containing - object" for the given FIELD_DECL, or return 0 if we are unable to deter- - mine what that offset is, either because the argument turns out to be a - pointer to an ERROR_MARK node, or because the offset is actually variable. - (We can't handle the latter case just yet.) */ - -static unsigned -field_byte_offset (decl) - register tree decl; -{ - register unsigned type_align_in_bytes; - register unsigned type_align_in_bits; - register unsigned type_size_in_bits; - register unsigned object_offset_in_align_units; - register unsigned object_offset_in_bits; - register unsigned object_offset_in_bytes; - register tree type; - register tree bitpos_tree; - register tree field_size_tree; - register unsigned bitpos_int; - register unsigned deepest_bitpos; - register unsigned field_size_in_bits; - - if (TREE_CODE (decl) == ERROR_MARK) - return 0; - - if (TREE_CODE (decl) != FIELD_DECL) - abort (); - - type = field_type (decl); - - bitpos_tree = DECL_FIELD_BITPOS (decl); - field_size_tree = DECL_SIZE (decl); - - /* We cannot yet cope with fields whose positions or sizes are variable, - so for now, when we see such things, we simply return 0. Someday, - we may be able to handle such cases, but it will be damn difficult. */ - - if (TREE_CODE (bitpos_tree) != INTEGER_CST) - return 0; - bitpos_int = (unsigned) TREE_INT_CST_LOW (bitpos_tree); - - if (TREE_CODE (field_size_tree) != INTEGER_CST) - return 0; - field_size_in_bits = (unsigned) TREE_INT_CST_LOW (field_size_tree); - - type_size_in_bits = simple_type_size_in_bits (type); - - type_align_in_bits = simple_type_align_in_bits (type); - type_align_in_bytes = type_align_in_bits / BITS_PER_UNIT; - - /* Note that the GCC front-end doesn't make any attempt to keep track - of the starting bit offset (relative to the start of the containing - structure type) of the hypothetical "containing object" for a bit- - field. Thus, when computing the byte offset value for the start of - the "containing object" of a bit-field, we must deduce this infor- - mation on our own. - - This can be rather tricky to do in some cases. For example, handling - the following structure type definition when compiling for an i386/i486 - target (which only aligns long long's to 32-bit boundaries) can be very - tricky: - - struct S { - int field1; - long long field2:31; - }; - - Fortunately, there is a simple rule-of-thumb which can be used in such - cases. When compiling for an i386/i486, GCC will allocate 8 bytes for - the structure shown above. It decides to do this based upon one simple - rule for bit-field allocation. Quite simply, GCC allocates each "con- - taining object" for each bit-field at the first (i.e. lowest addressed) - legitimate alignment boundary (based upon the required minimum alignment - for the declared type of the field) which it can possibly use, subject - to the condition that there is still enough available space remaining - in the containing object (when allocated at the selected point) to - fully accommodate all of the bits of the bit-field itself. - - This simple rule makes it obvious why GCC allocates 8 bytes for each - object of the structure type shown above. When looking for a place to - allocate the "containing object" for `field2', the compiler simply tries - to allocate a 64-bit "containing object" at each successive 32-bit - boundary (starting at zero) until it finds a place to allocate that 64- - bit field such that at least 31 contiguous (and previously unallocated) - bits remain within that selected 64 bit field. (As it turns out, for - the example above, the compiler finds that it is OK to allocate the - "containing object" 64-bit field at bit-offset zero within the - structure type.) - - Here we attempt to work backwards from the limited set of facts we're - given, and we try to deduce from those facts, where GCC must have - believed that the containing object started (within the structure type). - - The value we deduce is then used (by the callers of this routine) to - generate AT_location and AT_bit_offset attributes for fields (both - bit-fields and, in the case of AT_location, regular fields as well). - */ - - /* Figure out the bit-distance from the start of the structure to the - "deepest" bit of the bit-field. */ - deepest_bitpos = bitpos_int + field_size_in_bits; - - /* This is the tricky part. Use some fancy footwork to deduce where the - lowest addressed bit of the containing object must be. */ - object_offset_in_bits - = ceiling (deepest_bitpos, type_align_in_bits) - type_size_in_bits; - - /* Compute the offset of the containing object in "alignment units". */ - object_offset_in_align_units = object_offset_in_bits / type_align_in_bits; - - /* Compute the offset of the containing object in bytes. */ - object_offset_in_bytes = object_offset_in_align_units * type_align_in_bytes; - - /* The above code assumes that the field does not cross an alignment - boundary. This can happen if PCC_BITFIELD_TYPE_MATTERS is not defined, - or if the structure is packed. If this happens, then we get an object - which starts after the bitfield, which means that the bit offset is - negative. Gdb fails when given negative bit offsets. We avoid this - by recomputing using the first bit of the bitfield. This will give - us an object which does not completely contain the bitfield, but it - will be aligned, and it will contain the first bit of the bitfield. */ - if (object_offset_in_bits > bitpos_int) - { - deepest_bitpos = bitpos_int + 1; - object_offset_in_bits - = ceiling (deepest_bitpos, type_align_in_bits) - type_size_in_bits; - object_offset_in_align_units = (object_offset_in_bits - / type_align_in_bits); - object_offset_in_bytes = (object_offset_in_align_units - * type_align_in_bytes); - } - - return object_offset_in_bytes; -} - -/****************************** attributes *********************************/ - -/* The following routines are responsible for writing out the various types - of Dwarf attributes (and any following data bytes associated with them). - These routines are listed in order based on the numerical codes of their - associated attributes. */ - -/* Generate an AT_sibling attribute. */ - -static inline void -sibling_attribute () -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_sibling); - sprintf (label, DIE_BEGIN_LABEL_FMT, NEXT_DIE_NUM); - ASM_OUTPUT_DWARF_REF (asm_out_file, label); -} - -/* Output the form of location attributes suitable for whole variables and - whole parameters. Note that the location attributes for struct fields - are generated by the routine `data_member_location_attribute' below. */ - -static void -location_attribute (rtl) - register rtx rtl; -{ - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_location); - sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, LOC_END_LABEL_FMT, current_dienum); - ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - - /* Handle a special case. If we are about to output a location descriptor - for a variable or parameter which has been optimized out of existence, - don't do that. Instead we output a zero-length location descriptor - value as part of the location attribute. - - A variable which has been optimized out of existence will have a - DECL_RTL value which denotes a pseudo-reg. - - Currently, in some rare cases, variables can have DECL_RTL values - which look like (MEM (REG pseudo-reg#)). These cases are due to - bugs elsewhere in the compiler. We treat such cases - as if the variable(s) in question had been optimized out of existence. - - Note that in all cases where we wish to express the fact that a - variable has been optimized out of existence, we do not simply - suppress the generation of the entire location attribute because - the absence of a location attribute in certain kinds of DIEs is - used to indicate something else entirely... i.e. that the DIE - represents an object declaration, but not a definition. So saith - the PLSIG. - */ - - if (! is_pseudo_reg (rtl) - && (GET_CODE (rtl) != MEM || ! is_pseudo_reg (XEXP (rtl, 0)))) - output_loc_descriptor (rtl); - - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} - -/* Output the specialized form of location attribute used for data members - of struct and union types. - - In the special case of a FIELD_DECL node which represents a bit-field, - the "offset" part of this special location descriptor must indicate the - distance in bytes from the lowest-addressed byte of the containing - struct or union type to the lowest-addressed byte of the "containing - object" for the bit-field. (See the `field_byte_offset' function above.) - - For any given bit-field, the "containing object" is a hypothetical - object (of some integral or enum type) within which the given bit-field - lives. The type of this hypothetical "containing object" is always the - same as the declared type of the individual bit-field itself (for GCC - anyway... the DWARF spec doesn't actually mandate this). - - Note that it is the size (in bytes) of the hypothetical "containing - object" which will be given in the AT_byte_size attribute for this - bit-field. (See the `byte_size_attribute' function below.) It is - also used when calculating the value of the AT_bit_offset attribute. - (See the `bit_offset_attribute' function below.) */ - -static void -data_member_location_attribute (t) - register tree t; -{ - register unsigned object_offset_in_bytes; - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - if (TREE_CODE (t) == TREE_VEC) - object_offset_in_bytes = TREE_INT_CST_LOW (BINFO_OFFSET (t)); - else - object_offset_in_bytes = field_byte_offset (t); - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_location); - sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, LOC_END_LABEL_FMT, current_dienum); - ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_CONST); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, object_offset_in_bytes); - ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADD); - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} - -/* Output an AT_const_value attribute for a variable or a parameter which - does not have a "location" either in memory or in a register. These - things can arise in GNU C when a constant is passed as an actual - parameter to an inlined function. They can also arise in C++ where - declared constants do not necessarily get memory "homes". */ - -static void -const_value_attribute (rtl) - register rtx rtl; -{ - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_const_value_block4); - sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, LOC_END_LABEL_FMT, current_dienum); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - - switch (GET_CODE (rtl)) - { - case CONST_INT: - /* Note that a CONST_INT rtx could represent either an integer or - a floating-point constant. A CONST_INT is used whenever the - constant will fit into a single word. In all such cases, the - original mode of the constant value is wiped out, and the - CONST_INT rtx is assigned VOIDmode. Since we no longer have - precise mode information for these constants, we always just - output them using 4 bytes. */ - - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, (unsigned) INTVAL (rtl)); - break; - - case CONST_DOUBLE: - /* Note that a CONST_DOUBLE rtx could represent either an integer - or a floating-point constant. A CONST_DOUBLE is used whenever - the constant requires more than one word in order to be adequately - represented. In all such cases, the original mode of the constant - value is preserved as the mode of the CONST_DOUBLE rtx, but for - simplicity we always just output CONST_DOUBLEs using 8 bytes. */ - - ASM_OUTPUT_DWARF_DATA8 (asm_out_file, - (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (rtl), - (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (rtl)); - break; - - case CONST_STRING: - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, XSTR (rtl, 0)); - break; - - case SYMBOL_REF: - case LABEL_REF: - case CONST: - ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, rtl); - break; - - case PLUS: - /* In cases where an inlined instance of an inline function is passed - the address of an `auto' variable (which is local to the caller) - we can get a situation where the DECL_RTL of the artificial - local variable (for the inlining) which acts as a stand-in for - the corresponding formal parameter (of the inline function) - will look like (plus:SI (reg:SI FRAME_PTR) (const_int ...)). - This is not exactly a compile-time constant expression, but it - isn't the address of the (artificial) local variable either. - Rather, it represents the *value* which the artificial local - variable always has during its lifetime. We currently have no - way to represent such quasi-constant values in Dwarf, so for now - we just punt and generate an AT_const_value attribute with form - FORM_BLOCK4 and a length of zero. */ - break; - - default: - abort (); /* No other kinds of rtx should be possible here. */ - } - - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} - -/* Generate *either* an AT_location attribute or else an AT_const_value - data attribute for a variable or a parameter. We generate the - AT_const_value attribute only in those cases where the given - variable or parameter does not have a true "location" either in - memory or in a register. This can happen (for example) when a - constant is passed as an actual argument in a call to an inline - function. (It's possible that these things can crop up in other - ways also.) Note that one type of constant value which can be - passed into an inlined function is a constant pointer. This can - happen for example if an actual argument in an inlined function - call evaluates to a compile-time constant address. */ - -static void -location_or_const_value_attribute (decl) - register tree decl; -{ - register rtx rtl; - - if (TREE_CODE (decl) == ERROR_MARK) - return; - - if ((TREE_CODE (decl) != VAR_DECL) && (TREE_CODE (decl) != PARM_DECL)) - { - /* Should never happen. */ - abort (); - return; - } - - /* Here we have to decide where we are going to say the parameter "lives" - (as far as the debugger is concerned). We only have a couple of choices. - GCC provides us with DECL_RTL and with DECL_INCOMING_RTL. DECL_RTL - normally indicates where the parameter lives during most of the activa- - tion of the function. If optimization is enabled however, this could - be either NULL or else a pseudo-reg. Both of those cases indicate that - the parameter doesn't really live anywhere (as far as the code generation - parts of GCC are concerned) during most of the function's activation. - That will happen (for example) if the parameter is never referenced - within the function. - - We could just generate a location descriptor here for all non-NULL - non-pseudo values of DECL_RTL and ignore all of the rest, but we can - be a little nicer than that if we also consider DECL_INCOMING_RTL in - cases where DECL_RTL is NULL or is a pseudo-reg. - - Note however that we can only get away with using DECL_INCOMING_RTL as - a backup substitute for DECL_RTL in certain limited cases. In cases - where DECL_ARG_TYPE(decl) indicates the same type as TREE_TYPE(decl) - we can be sure that the parameter was passed using the same type as it - is declared to have within the function, and that its DECL_INCOMING_RTL - points us to a place where a value of that type is passed. In cases - where DECL_ARG_TYPE(decl) and TREE_TYPE(decl) are different types - however, we cannot (in general) use DECL_INCOMING_RTL as a backup - substitute for DECL_RTL because in these cases, DECL_INCOMING_RTL - points us to a value of some type which is *different* from the type - of the parameter itself. Thus, if we tried to use DECL_INCOMING_RTL - to generate a location attribute in such cases, the debugger would - end up (for example) trying to fetch a `float' from a place which - actually contains the first part of a `double'. That would lead to - really incorrect and confusing output at debug-time, and we don't - want that now do we? - - So in general, we DO NOT use DECL_INCOMING_RTL as a backup for DECL_RTL - in cases where DECL_ARG_TYPE(decl) != TREE_TYPE(decl). There are a - couple of cute exceptions however. On little-endian machines we can - get away with using DECL_INCOMING_RTL even when DECL_ARG_TYPE(decl) is - not the same as TREE_TYPE(decl) but only when DECL_ARG_TYPE(decl) is - an integral type which is smaller than TREE_TYPE(decl). These cases - arise when (on a little-endian machine) a non-prototyped function has - a parameter declared to be of type `short' or `char'. In such cases, - TREE_TYPE(decl) will be `short' or `char', DECL_ARG_TYPE(decl) will be - `int', and DECL_INCOMING_RTL will point to the lowest-order byte of the - passed `int' value. If the debugger then uses that address to fetch a - `short' or a `char' (on a little-endian machine) the result will be the - correct data, so we allow for such exceptional cases below. - - Note that our goal here is to describe the place where the given formal - parameter lives during most of the function's activation (i.e. between - the end of the prologue and the start of the epilogue). We'll do that - as best as we can. Note however that if the given formal parameter is - modified sometime during the execution of the function, then a stack - backtrace (at debug-time) will show the function as having been called - with the *new* value rather than the value which was originally passed - in. This happens rarely enough that it is not a major problem, but it - *is* a problem, and I'd like to fix it. A future version of dwarfout.c - may generate two additional attributes for any given TAG_formal_parameter - DIE which will describe the "passed type" and the "passed location" for - the given formal parameter in addition to the attributes we now generate - to indicate the "declared type" and the "active location" for each - parameter. This additional set of attributes could be used by debuggers - for stack backtraces. - - Separately, note that sometimes DECL_RTL can be NULL and DECL_INCOMING_RTL - can be NULL also. This happens (for example) for inlined-instances of - inline function formal parameters which are never referenced. This really - shouldn't be happening. All PARM_DECL nodes should get valid non-NULL - DECL_INCOMING_RTL values, but integrate.c doesn't currently generate - these values for inlined instances of inline function parameters, so - when we see such cases, we are just out-of-luck for the time - being (until integrate.c gets fixed). - */ - - /* Use DECL_RTL as the "location" unless we find something better. */ - rtl = DECL_RTL (decl); - - if (TREE_CODE (decl) == PARM_DECL) - if (rtl == NULL_RTX || is_pseudo_reg (rtl)) - { - /* This decl represents a formal parameter which was optimized out. */ - register tree declared_type = type_main_variant (TREE_TYPE (decl)); - register tree passed_type = type_main_variant (DECL_ARG_TYPE (decl)); - - /* Note that DECL_INCOMING_RTL may be NULL in here, but we handle - *all* cases where (rtl == NULL_RTX) just below. */ - - if (declared_type == passed_type) - rtl = DECL_INCOMING_RTL (decl); - else if (! BYTES_BIG_ENDIAN) - if (TREE_CODE (declared_type) == INTEGER_TYPE) - if (TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type)) - rtl = DECL_INCOMING_RTL (decl); - } - - if (rtl == NULL_RTX) - return; - - rtl = eliminate_regs (rtl, 0, NULL_RTX); -#ifdef LEAF_REG_REMAP - if (leaf_function) - leaf_renumber_regs_insn (rtl); -#endif - - switch (GET_CODE (rtl)) - { - case ADDRESSOF: - /* The address of a variable that was optimized away; don't emit - anything. */ - break; - - case CONST_INT: - case CONST_DOUBLE: - case CONST_STRING: - case SYMBOL_REF: - case LABEL_REF: - case CONST: - case PLUS: /* DECL_RTL could be (plus (reg ...) (const_int ...)) */ - const_value_attribute (rtl); - break; - - case MEM: - case REG: - case SUBREG: - location_attribute (rtl); - break; - - case CONCAT: - /* ??? CONCAT is used for complex variables, which may have the real - part stored in one place and the imag part stored somewhere else. - DWARF1 has no way to describe a variable that lives in two different - places, so we just describe where the first part lives, and hope that - the second part is stored after it. */ - location_attribute (XEXP (rtl, 0)); - break; - - default: - abort (); /* Should never happen. */ - } -} - -/* Generate an AT_name attribute given some string value to be included as - the value of the attribute. */ - -static inline void -name_attribute (name_string) - register char *name_string; -{ - if (name_string && *name_string) - { - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_name); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, name_string); - } -} - -static inline void -fund_type_attribute (ft_code) - register unsigned ft_code; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_fund_type); - ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, ft_code); -} - -static void -mod_fund_type_attribute (type, decl_const, decl_volatile) - register tree type; - register int decl_const; - register int decl_volatile; -{ - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mod_fund_type); - sprintf (begin_label, MT_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, MT_END_LABEL_FMT, current_dienum); - ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - write_modifier_bytes (type, decl_const, decl_volatile); - ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, - fundamental_type_code (root_type (type))); - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} - -static inline void -user_def_type_attribute (type) - register tree type; -{ - char ud_type_name[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_user_def_type); - sprintf (ud_type_name, TYPE_NAME_FMT, TYPE_UID (type)); - ASM_OUTPUT_DWARF_REF (asm_out_file, ud_type_name); -} - -static void -mod_u_d_type_attribute (type, decl_const, decl_volatile) - register tree type; - register int decl_const; - register int decl_volatile; -{ - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char ud_type_name[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mod_u_d_type); - sprintf (begin_label, MT_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, MT_END_LABEL_FMT, current_dienum); - ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - write_modifier_bytes (type, decl_const, decl_volatile); - sprintf (ud_type_name, TYPE_NAME_FMT, TYPE_UID (root_type (type))); - ASM_OUTPUT_DWARF_REF (asm_out_file, ud_type_name); - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} - -#ifdef USE_ORDERING_ATTRIBUTE -static inline void -ordering_attribute (ordering) - register unsigned ordering; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_ordering); - ASM_OUTPUT_DWARF_DATA2 (asm_out_file, ordering); -} -#endif /* defined(USE_ORDERING_ATTRIBUTE) */ - -/* Note that the block of subscript information for an array type also - includes information about the element type of type given array type. */ - -static void -subscript_data_attribute (type) - register tree type; -{ - register unsigned dimension_number; - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_subscr_data); - sprintf (begin_label, SS_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, SS_END_LABEL_FMT, current_dienum); - ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - - /* The GNU compilers represent multidimensional array types as sequences - of one dimensional array types whose element types are themselves array - types. Here we squish that down, so that each multidimensional array - type gets only one array_type DIE in the Dwarf debugging info. The - draft Dwarf specification say that we are allowed to do this kind - of compression in C (because there is no difference between an - array or arrays and a multidimensional array in C) but for other - source languages (e.g. Ada) we probably shouldn't do this. */ - - for (dimension_number = 0; - TREE_CODE (type) == ARRAY_TYPE; - type = TREE_TYPE (type), dimension_number++) - { - register tree domain = TYPE_DOMAIN (type); - - /* Arrays come in three flavors. Unspecified bounds, fixed - bounds, and (in GNU C only) variable bounds. Handle all - three forms here. */ - - if (domain) - { - /* We have an array type with specified bounds. */ - - register tree lower = TYPE_MIN_VALUE (domain); - register tree upper = TYPE_MAX_VALUE (domain); - - /* Handle only fundamental types as index types for now. */ - - if (! type_is_fundamental (domain)) - abort (); - - /* Output the representation format byte for this dimension. */ - - ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, - FMT_CODE (1, TREE_CODE (lower) == INTEGER_CST, - (upper && TREE_CODE (upper) == INTEGER_CST))); - - /* Output the index type for this dimension. */ - - ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, - fundamental_type_code (domain)); - - /* Output the representation for the lower bound. */ - - output_bound_representation (lower, dimension_number, 'l'); - - /* Output the representation for the upper bound. */ - - output_bound_representation (upper, dimension_number, 'u'); - } - else - { - /* We have an array type with an unspecified length. For C and - C++ we can assume that this really means that (a) the index - type is an integral type, and (b) the lower bound is zero. - Note that Dwarf defines the representation of an unspecified - (upper) bound as being a zero-length location description. */ - - /* Output the array-bounds format byte. */ - - ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, FMT_FT_C_X); - - /* Output the (assumed) index type. */ - - ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, FT_integer); - - /* Output the (assumed) lower bound (constant) value. */ - - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); - - /* Output the (empty) location description for the upper bound. */ - - ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0); - } - } - - /* Output the prefix byte that says that the element type is coming up. */ - - ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, FMT_ET); - - /* Output a representation of the type of the elements of this array type. */ - - type_attribute (type, 0, 0); - - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} - -static void -byte_size_attribute (tree_node) - register tree tree_node; -{ - register unsigned size; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_byte_size); - switch (TREE_CODE (tree_node)) - { - case ERROR_MARK: - size = 0; - break; - - case ENUMERAL_TYPE: - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - case ARRAY_TYPE: - size = int_size_in_bytes (tree_node); - break; - - case FIELD_DECL: - /* For a data member of a struct or union, the AT_byte_size is - generally given as the number of bytes normally allocated for - an object of the *declared* type of the member itself. This - is true even for bit-fields. */ - size = simple_type_size_in_bits (field_type (tree_node)) - / BITS_PER_UNIT; - break; - - default: - abort (); - } - - /* Note that `size' might be -1 when we get to this point. If it - is, that indicates that the byte size of the entity in question - is variable. We have no good way of expressing this fact in Dwarf - at the present time, so just let the -1 pass on through. */ - - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, size); -} - -/* For a FIELD_DECL node which represents a bit-field, output an attribute - which specifies the distance in bits from the highest order bit of the - "containing object" for the bit-field to the highest order bit of the - bit-field itself. - - For any given bit-field, the "containing object" is a hypothetical - object (of some integral or enum type) within which the given bit-field - lives. The type of this hypothetical "containing object" is always the - same as the declared type of the individual bit-field itself. - - The determination of the exact location of the "containing object" for - a bit-field is rather complicated. It's handled by the `field_byte_offset' - function (above). - - Note that it is the size (in bytes) of the hypothetical "containing - object" which will be given in the AT_byte_size attribute for this - bit-field. (See `byte_size_attribute' above.) */ - -static inline void -bit_offset_attribute (decl) - register tree decl; -{ - register unsigned object_offset_in_bytes = field_byte_offset (decl); - register tree type = DECL_BIT_FIELD_TYPE (decl); - register tree bitpos_tree = DECL_FIELD_BITPOS (decl); - register unsigned bitpos_int; - register unsigned highest_order_object_bit_offset; - register unsigned highest_order_field_bit_offset; - register unsigned bit_offset; - - /* Must be a bit field. */ - if (!type - || TREE_CODE (decl) != FIELD_DECL) - abort (); - - /* We can't yet handle bit-fields whose offsets are variable, so if we - encounter such things, just return without generating any attribute - whatsoever. */ - - if (TREE_CODE (bitpos_tree) != INTEGER_CST) - return; - bitpos_int = (unsigned) TREE_INT_CST_LOW (bitpos_tree); - - /* Note that the bit offset is always the distance (in bits) from the - highest-order bit of the "containing object" to the highest-order - bit of the bit-field itself. Since the "high-order end" of any - object or field is different on big-endian and little-endian machines, - the computation below must take account of these differences. */ - - highest_order_object_bit_offset = object_offset_in_bytes * BITS_PER_UNIT; - highest_order_field_bit_offset = bitpos_int; - - if (! BYTES_BIG_ENDIAN) - { - highest_order_field_bit_offset - += (unsigned) TREE_INT_CST_LOW (DECL_SIZE (decl)); - - highest_order_object_bit_offset += simple_type_size_in_bits (type); - } - - bit_offset = - (! BYTES_BIG_ENDIAN - ? highest_order_object_bit_offset - highest_order_field_bit_offset - : highest_order_field_bit_offset - highest_order_object_bit_offset); - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_bit_offset); - ASM_OUTPUT_DWARF_DATA2 (asm_out_file, bit_offset); -} - -/* For a FIELD_DECL node which represents a bit field, output an attribute - which specifies the length in bits of the given field. */ - -static inline void -bit_size_attribute (decl) - register tree decl; -{ - /* Must be a field and a bit field. */ - if (TREE_CODE (decl) != FIELD_DECL - || ! DECL_BIT_FIELD_TYPE (decl)) - abort (); - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_bit_size); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, - (unsigned) TREE_INT_CST_LOW (DECL_SIZE (decl))); -} - -/* The following routine outputs the `element_list' attribute for enumeration - type DIEs. The element_lits attribute includes the names and values of - all of the enumeration constants associated with the given enumeration - type. */ - -static inline void -element_list_attribute (element) - register tree element; -{ - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_element_list); - sprintf (begin_label, EE_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, EE_END_LABEL_FMT, current_dienum); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - - /* Here we output a list of value/name pairs for each enumeration constant - defined for this enumeration type (as required), but we do it in REVERSE - order. The order is the one required by the draft #5 Dwarf specification - published by the UI/PLSIG. */ - - output_enumeral_list (element); /* Recursively output the whole list. */ - - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} - -/* Generate an AT_stmt_list attribute. These are normally present only in - DIEs with a TAG_compile_unit tag. */ - -static inline void -stmt_list_attribute (label) - register char *label; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_stmt_list); - /* Don't use ASM_OUTPUT_DWARF_DATA4 here. */ - ASM_OUTPUT_DWARF_ADDR (asm_out_file, label); -} - -/* Generate an AT_low_pc attribute for a label DIE, a lexical_block DIE or - for a subroutine DIE. */ - -static inline void -low_pc_attribute (asm_low_label) - register char *asm_low_label; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_low_pc); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_low_label); -} - -/* Generate an AT_high_pc attribute for a lexical_block DIE or for a - subroutine DIE. */ - -static inline void -high_pc_attribute (asm_high_label) - register char *asm_high_label; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_high_pc); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_high_label); -} - -/* Generate an AT_body_begin attribute for a subroutine DIE. */ - -static inline void -body_begin_attribute (asm_begin_label) - register char *asm_begin_label; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_body_begin); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_begin_label); -} - -/* Generate an AT_body_end attribute for a subroutine DIE. */ - -static inline void -body_end_attribute (asm_end_label) - register char *asm_end_label; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_body_end); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_end_label); -} - -/* Generate an AT_language attribute given a LANG value. These attributes - are used only within TAG_compile_unit DIEs. */ - -static inline void -language_attribute (language_code) - register unsigned language_code; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_language); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, language_code); -} - -static inline void -member_attribute (context) - register tree context; -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - /* Generate this attribute only for members in C++. */ - - if (context != NULL && is_tagged_type (context)) - { - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_member); - sprintf (label, TYPE_NAME_FMT, TYPE_UID (context)); - ASM_OUTPUT_DWARF_REF (asm_out_file, label); - } -} - -#if 0 -static inline void -string_length_attribute (upper_bound) - register tree upper_bound; -{ - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_string_length); - sprintf (begin_label, SL_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, SL_END_LABEL_FMT, current_dienum); - ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - output_bound_representation (upper_bound, 0, 'u'); - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} -#endif - -static inline void -comp_dir_attribute (dirname) - register char *dirname; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_comp_dir); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, dirname); -} - -static inline void -sf_names_attribute (sf_names_start_label) - register char *sf_names_start_label; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_sf_names); - /* Don't use ASM_OUTPUT_DWARF_DATA4 here. */ - ASM_OUTPUT_DWARF_ADDR (asm_out_file, sf_names_start_label); -} - -static inline void -src_info_attribute (src_info_start_label) - register char *src_info_start_label; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_src_info); - /* Don't use ASM_OUTPUT_DWARF_DATA4 here. */ - ASM_OUTPUT_DWARF_ADDR (asm_out_file, src_info_start_label); -} - -static inline void -mac_info_attribute (mac_info_start_label) - register char *mac_info_start_label; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mac_info); - /* Don't use ASM_OUTPUT_DWARF_DATA4 here. */ - ASM_OUTPUT_DWARF_ADDR (asm_out_file, mac_info_start_label); -} - -static inline void -prototyped_attribute (func_type) - register tree func_type; -{ - if ((strcmp (language_string, "GNU C") == 0) - && (TYPE_ARG_TYPES (func_type) != NULL)) - { - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_prototyped); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); - } -} - -static inline void -producer_attribute (producer) - register char *producer; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_producer); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, producer); -} - -static inline void -inline_attribute (decl) - register tree decl; -{ - if (DECL_INLINE (decl)) - { - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_inline); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); - } -} - -static inline void -containing_type_attribute (containing_type) - register tree containing_type; -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_containing_type); - sprintf (label, TYPE_NAME_FMT, TYPE_UID (containing_type)); - ASM_OUTPUT_DWARF_REF (asm_out_file, label); -} - -static inline void -abstract_origin_attribute (origin) - register tree origin; -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_abstract_origin); - switch (TREE_CODE_CLASS (TREE_CODE (origin))) - { - case 'd': - sprintf (label, DECL_NAME_FMT, DECL_UID (origin)); - break; - - case 't': - sprintf (label, TYPE_NAME_FMT, TYPE_UID (origin)); - break; - - default: - abort (); /* Should never happen. */ - - } - ASM_OUTPUT_DWARF_REF (asm_out_file, label); -} - -#ifdef DWARF_DECL_COORDINATES -static inline void -src_coords_attribute (src_fileno, src_lineno) - register unsigned src_fileno; - register unsigned src_lineno; -{ - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_src_coords); - ASM_OUTPUT_DWARF_DATA2 (asm_out_file, src_fileno); - ASM_OUTPUT_DWARF_DATA2 (asm_out_file, src_lineno); -} -#endif /* defined(DWARF_DECL_COORDINATES) */ - -static inline void -pure_or_virtual_attribute (func_decl) - register tree func_decl; -{ - if (DECL_VIRTUAL_P (func_decl)) - { -#if 0 /* DECL_ABSTRACT_VIRTUAL_P is C++-specific. */ - if (DECL_ABSTRACT_VIRTUAL_P (func_decl)) - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_pure_virtual); - else -#endif - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_virtual); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); - } -} - -/************************* end of attributes *****************************/ - -/********************* utility routines for DIEs *************************/ - -/* Output an AT_name attribute and an AT_src_coords attribute for the - given decl, but only if it actually has a name. */ - -static void -name_and_src_coords_attributes (decl) - register tree decl; -{ - register tree decl_name = DECL_NAME (decl); - - if (decl_name && IDENTIFIER_POINTER (decl_name)) - { - name_attribute (IDENTIFIER_POINTER (decl_name)); -#ifdef DWARF_DECL_COORDINATES - { - register unsigned file_index; - - /* This is annoying, but we have to pop out of the .debug section - for a moment while we call `lookup_filename' because calling it - may cause a temporary switch into the .debug_sfnames section and - most svr4 assemblers are not smart enough to be able to nest - section switches to any depth greater than one. Note that we - also can't skirt this issue by delaying all output to the - .debug_sfnames section unit the end of compilation because that - would cause us to have inter-section forward references and - Fred Fish sez that m68k/svr4 assemblers botch those. */ - - ASM_OUTPUT_POP_SECTION (asm_out_file); - file_index = lookup_filename (DECL_SOURCE_FILE (decl)); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION); - - src_coords_attribute (file_index, DECL_SOURCE_LINE (decl)); - } -#endif /* defined(DWARF_DECL_COORDINATES) */ - } -} - -/* Many forms of DIEs contain a "type description" part. The following - routine writes out these "type descriptor" parts. */ - -static void -type_attribute (type, decl_const, decl_volatile) - register tree type; - register int decl_const; - register int decl_volatile; -{ - register enum tree_code code = TREE_CODE (type); - register int root_type_modified; - - if (code == ERROR_MARK) - return; - - /* Handle a special case. For functions whose return type is void, - we generate *no* type attribute. (Note that no object may have - type `void', so this only applies to function return types. */ - - if (code == VOID_TYPE) - return; - - /* If this is a subtype, find the underlying type. Eventually, - this should write out the appropriate subtype info. */ - while ((code == INTEGER_TYPE || code == REAL_TYPE) - && TREE_TYPE (type) != 0) - type = TREE_TYPE (type), code = TREE_CODE (type); - - root_type_modified = (code == POINTER_TYPE || code == REFERENCE_TYPE - || decl_const || decl_volatile - || TYPE_READONLY (type) || TYPE_VOLATILE (type)); - - if (type_is_fundamental (root_type (type))) - { - if (root_type_modified) - mod_fund_type_attribute (type, decl_const, decl_volatile); - else - fund_type_attribute (fundamental_type_code (type)); - } - else - { - if (root_type_modified) - mod_u_d_type_attribute (type, decl_const, decl_volatile); - else - /* We have to get the type_main_variant here (and pass that to the - `user_def_type_attribute' routine) because the ..._TYPE node we - have might simply be a *copy* of some original type node (where - the copy was created to help us keep track of typedef names) - and that copy might have a different TYPE_UID from the original - ..._TYPE node. (Note that when `equate_type_number_to_die_number' - is labeling a given type DIE for future reference, it always and - only creates labels for DIEs representing *main variants*, and it - never even knows about non-main-variants.) */ - user_def_type_attribute (type_main_variant (type)); - } -} - -/* Given a tree pointer to a struct, class, union, or enum type node, return - a pointer to the (string) tag name for the given type, or zero if the - type was declared without a tag. */ - -static char * -type_tag (type) - register tree type; -{ - register char *name = 0; - - if (TYPE_NAME (type) != 0) - { - register tree t = 0; - - /* Find the IDENTIFIER_NODE for the type name. */ - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - t = TYPE_NAME (type); - - /* The g++ front end makes the TYPE_NAME of *each* tagged type point to - a TYPE_DECL node, regardless of whether or not a `typedef' was - involved. */ - else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && ! DECL_IGNORED_P (TYPE_NAME (type))) - t = DECL_NAME (TYPE_NAME (type)); - - /* Now get the name as a string, or invent one. */ - if (t != 0) - name = IDENTIFIER_POINTER (t); - } - - return (name == 0 || *name == '\0') ? 0 : name; -} - -static inline void -dienum_push () -{ - /* Start by checking if the pending_sibling_stack needs to be expanded. - If necessary, expand it. */ - - if (pending_siblings == pending_siblings_allocated) - { - pending_siblings_allocated += PENDING_SIBLINGS_INCREMENT; - pending_sibling_stack - = (unsigned *) xrealloc (pending_sibling_stack, - pending_siblings_allocated * sizeof(unsigned)); - } - - pending_siblings++; - NEXT_DIE_NUM = next_unused_dienum++; -} - -/* Pop the sibling stack so that the most recently pushed DIEnum becomes the - NEXT_DIE_NUM. */ - -static inline void -dienum_pop () -{ - pending_siblings--; -} - -static inline tree -member_declared_type (member) - register tree member; -{ - return (DECL_BIT_FIELD_TYPE (member)) - ? DECL_BIT_FIELD_TYPE (member) - : TREE_TYPE (member); -} - -/* Get the function's label, as described by its RTL. - This may be different from the DECL_NAME name used - in the source file. */ - -static char * -function_start_label (decl) - register tree decl; -{ - rtx x; - char *fnname; - - x = DECL_RTL (decl); - if (GET_CODE (x) != MEM) - abort (); - x = XEXP (x, 0); - if (GET_CODE (x) != SYMBOL_REF) - abort (); - fnname = XSTR (x, 0); - return fnname; -} - - -/******************************* DIEs ************************************/ - -/* Output routines for individual types of DIEs. */ - -/* Note that every type of DIE (except a null DIE) gets a sibling. */ - -static void -output_array_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_array_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - member_attribute (TYPE_CONTEXT (type)); - - /* I believe that we can default the array ordering. SDB will probably - do the right things even if AT_ordering is not present. It's not - even an issue until we start to get into multidimensional arrays - anyway. If SDB is ever caught doing the Wrong Thing for multi- - dimensional arrays, then we'll have to put the AT_ordering attribute - back in. (But if and when we find out that we need to put these in, - we will only do so for multidimensional arrays. After all, we don't - want to waste space in the .debug section now do we?) */ - -#ifdef USE_ORDERING_ATTRIBUTE - ordering_attribute (ORD_row_major); -#endif /* defined(USE_ORDERING_ATTRIBUTE) */ - - subscript_data_attribute (type); -} - -static void -output_set_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_set_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - member_attribute (TYPE_CONTEXT (type)); - type_attribute (TREE_TYPE (type), 0, 0); -} - -#if 0 -/* Implement this when there is a GNU FORTRAN or GNU Ada front end. */ - -static void -output_entry_point_die (arg) - register void *arg; -{ - register tree decl = arg; - register tree origin = decl_ultimate_origin (decl); - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_entry_point); - sibling_attribute (); - dienum_push (); - if (origin != NULL) - abstract_origin_attribute (origin); - else - { - name_and_src_coords_attributes (decl); - member_attribute (DECL_CONTEXT (decl)); - type_attribute (TREE_TYPE (TREE_TYPE (decl)), 0, 0); - } - if (DECL_ABSTRACT (decl)) - equate_decl_number_to_die_number (decl); - else - low_pc_attribute (function_start_label (decl)); -} -#endif - -/* Output a DIE to represent an inlined instance of an enumeration type. */ - -static void -output_inlined_enumeration_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_enumeration_type); - sibling_attribute (); - if (!TREE_ASM_WRITTEN (type)) - abort (); - abstract_origin_attribute (type); -} - -/* Output a DIE to represent an inlined instance of a structure type. */ - -static void -output_inlined_structure_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_structure_type); - sibling_attribute (); - if (!TREE_ASM_WRITTEN (type)) - abort (); - abstract_origin_attribute (type); -} - -/* Output a DIE to represent an inlined instance of a union type. */ - -static void -output_inlined_union_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_union_type); - sibling_attribute (); - if (!TREE_ASM_WRITTEN (type)) - abort (); - abstract_origin_attribute (type); -} - -/* Output a DIE to represent an enumeration type. Note that these DIEs - include all of the information about the enumeration values also. - This information is encoded into the element_list attribute. */ - -static void -output_enumeration_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_enumeration_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - name_attribute (type_tag (type)); - member_attribute (TYPE_CONTEXT (type)); - - /* Handle a GNU C/C++ extension, i.e. incomplete enum types. If the - given enum type is incomplete, do not generate the AT_byte_size - attribute or the AT_element_list attribute. */ - - if (TYPE_SIZE (type)) - { - byte_size_attribute (type); - element_list_attribute (TYPE_FIELDS (type)); - } -} - -/* Output a DIE to represent either a real live formal parameter decl or - to represent just the type of some formal parameter position in some - function type. - - Note that this routine is a bit unusual because its argument may be - a ..._DECL node (i.e. either a PARM_DECL or perhaps a VAR_DECL which - represents an inlining of some PARM_DECL) or else some sort of a - ..._TYPE node. If it's the former then this function is being called - to output a DIE to represent a formal parameter object (or some inlining - thereof). If it's the latter, then this function is only being called - to output a TAG_formal_parameter DIE to stand as a placeholder for some - formal argument type of some subprogram type. */ - -static void -output_formal_parameter_die (arg) - register void *arg; -{ - register tree node = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_formal_parameter); - sibling_attribute (); - - switch (TREE_CODE_CLASS (TREE_CODE (node))) - { - case 'd': /* We were called with some kind of a ..._DECL node. */ - { - register tree origin = decl_ultimate_origin (node); - - if (origin != NULL) - abstract_origin_attribute (origin); - else - { - name_and_src_coords_attributes (node); - type_attribute (TREE_TYPE (node), - TREE_READONLY (node), TREE_THIS_VOLATILE (node)); - } - if (DECL_ABSTRACT (node)) - equate_decl_number_to_die_number (node); - else - location_or_const_value_attribute (node); - } - break; - - case 't': /* We were called with some kind of a ..._TYPE node. */ - type_attribute (node, 0, 0); - break; - - default: - abort (); /* Should never happen. */ - } -} - -/* Output a DIE to represent a declared function (either file-scope - or block-local) which has "external linkage" (according to ANSI-C). */ - -static void -output_global_subroutine_die (arg) - register void *arg; -{ - register tree decl = arg; - register tree origin = decl_ultimate_origin (decl); - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_global_subroutine); - sibling_attribute (); - dienum_push (); - if (origin != NULL) - abstract_origin_attribute (origin); - else - { - register tree type = TREE_TYPE (decl); - - name_and_src_coords_attributes (decl); - inline_attribute (decl); - prototyped_attribute (type); - member_attribute (DECL_CONTEXT (decl)); - type_attribute (TREE_TYPE (type), 0, 0); - pure_or_virtual_attribute (decl); - } - if (DECL_ABSTRACT (decl)) - equate_decl_number_to_die_number (decl); - else - { - if (! DECL_EXTERNAL (decl) && ! in_class - && decl == current_function_decl) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - low_pc_attribute (function_start_label (decl)); - sprintf (label, FUNC_END_LABEL_FMT, current_funcdef_number); - high_pc_attribute (label); - if (use_gnu_debug_info_extensions) - { - sprintf (label, BODY_BEGIN_LABEL_FMT, current_funcdef_number); - body_begin_attribute (label); - sprintf (label, BODY_END_LABEL_FMT, current_funcdef_number); - body_end_attribute (label); - } - } - } -} - -/* Output a DIE to represent a declared data object (either file-scope - or block-local) which has "external linkage" (according to ANSI-C). */ - -static void -output_global_variable_die (arg) - register void *arg; -{ - register tree decl = arg; - register tree origin = decl_ultimate_origin (decl); - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_global_variable); - sibling_attribute (); - if (origin != NULL) - abstract_origin_attribute (origin); - else - { - name_and_src_coords_attributes (decl); - member_attribute (DECL_CONTEXT (decl)); - type_attribute (TREE_TYPE (decl), - TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); - } - if (DECL_ABSTRACT (decl)) - equate_decl_number_to_die_number (decl); - else - { - if (! DECL_EXTERNAL (decl) && ! in_class - && current_function_decl == decl_function_context (decl)) - location_or_const_value_attribute (decl); - } -} - -static void -output_label_die (arg) - register void *arg; -{ - register tree decl = arg; - register tree origin = decl_ultimate_origin (decl); - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_label); - sibling_attribute (); - if (origin != NULL) - abstract_origin_attribute (origin); - else - name_and_src_coords_attributes (decl); - if (DECL_ABSTRACT (decl)) - equate_decl_number_to_die_number (decl); - else - { - register rtx insn = DECL_RTL (decl); - - if (GET_CODE (insn) == CODE_LABEL) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - /* When optimization is enabled (via -O) some parts of the compiler - (e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which - represent source-level labels which were explicitly declared by - the user. This really shouldn't be happening though, so catch - it if it ever does happen. */ - - if (INSN_DELETED_P (insn)) - abort (); /* Should never happen. */ - - sprintf (label, INSN_LABEL_FMT, current_funcdef_number, - (unsigned) INSN_UID (insn)); - low_pc_attribute (label); - } - } -} - -static void -output_lexical_block_die (arg) - register void *arg; -{ - register tree stmt = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_lexical_block); - sibling_attribute (); - dienum_push (); - if (! BLOCK_ABSTRACT (stmt)) - { - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, next_block_number); - low_pc_attribute (begin_label); - sprintf (end_label, BLOCK_END_LABEL_FMT, next_block_number); - high_pc_attribute (end_label); - } -} - -static void -output_inlined_subroutine_die (arg) - register void *arg; -{ - register tree stmt = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_inlined_subroutine); - sibling_attribute (); - dienum_push (); - abstract_origin_attribute (block_ultimate_origin (stmt)); - if (! BLOCK_ABSTRACT (stmt)) - { - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, next_block_number); - low_pc_attribute (begin_label); - sprintf (end_label, BLOCK_END_LABEL_FMT, next_block_number); - high_pc_attribute (end_label); - } -} - -/* Output a DIE to represent a declared data object (either file-scope - or block-local) which has "internal linkage" (according to ANSI-C). */ - -static void -output_local_variable_die (arg) - register void *arg; -{ - register tree decl = arg; - register tree origin = decl_ultimate_origin (decl); - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_local_variable); - sibling_attribute (); - if (origin != NULL) - abstract_origin_attribute (origin); - else - { - name_and_src_coords_attributes (decl); - member_attribute (DECL_CONTEXT (decl)); - type_attribute (TREE_TYPE (decl), - TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); - } - if (DECL_ABSTRACT (decl)) - equate_decl_number_to_die_number (decl); - else - location_or_const_value_attribute (decl); -} - -static void -output_member_die (arg) - register void *arg; -{ - register tree decl = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_member); - sibling_attribute (); - name_and_src_coords_attributes (decl); - member_attribute (DECL_CONTEXT (decl)); - type_attribute (member_declared_type (decl), - TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); - if (DECL_BIT_FIELD_TYPE (decl)) /* If this is a bit field... */ - { - byte_size_attribute (decl); - bit_size_attribute (decl); - bit_offset_attribute (decl); - } - data_member_location_attribute (decl); -} - -#if 0 -/* Don't generate either pointer_type DIEs or reference_type DIEs. Use - modified types instead. - - We keep this code here just in case these types of DIEs may be - needed to represent certain things in other languages (e.g. Pascal) - someday. */ - -static void -output_pointer_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_pointer_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - member_attribute (TYPE_CONTEXT (type)); - type_attribute (TREE_TYPE (type), 0, 0); -} - -static void -output_reference_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_reference_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - member_attribute (TYPE_CONTEXT (type)); - type_attribute (TREE_TYPE (type), 0, 0); -} -#endif - -static void -output_ptr_to_mbr_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_ptr_to_member_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - member_attribute (TYPE_CONTEXT (type)); - containing_type_attribute (TYPE_OFFSET_BASETYPE (type)); - type_attribute (TREE_TYPE (type), 0, 0); -} - -static void -output_compile_unit_die (arg) - register void *arg; -{ - register char *main_input_filename = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_compile_unit); - sibling_attribute (); - dienum_push (); - name_attribute (main_input_filename); - - { - char producer[250]; - - sprintf (producer, "%s %s", language_string, version_string); - producer_attribute (producer); - } - - if (strcmp (language_string, "GNU C++") == 0) - language_attribute (LANG_C_PLUS_PLUS); - else if (strcmp (language_string, "GNU Ada") == 0) - language_attribute (LANG_ADA83); - else if (strcmp (language_string, "GNU F77") == 0) - language_attribute (LANG_FORTRAN77); - else if (strcmp (language_string, "GNU Pascal") == 0) - language_attribute (LANG_PASCAL83); - else if (flag_traditional) - language_attribute (LANG_C); - else - language_attribute (LANG_C89); - low_pc_attribute (TEXT_BEGIN_LABEL); - high_pc_attribute (TEXT_END_LABEL); - if (debug_info_level >= DINFO_LEVEL_NORMAL) - stmt_list_attribute (LINE_BEGIN_LABEL); - last_filename = xstrdup (main_input_filename); - - { - char *wd = getpwd (); - if (wd) - comp_dir_attribute (wd); - } - - if (debug_info_level >= DINFO_LEVEL_NORMAL && use_gnu_debug_info_extensions) - { - sf_names_attribute (SFNAMES_BEGIN_LABEL); - src_info_attribute (SRCINFO_BEGIN_LABEL); - if (debug_info_level >= DINFO_LEVEL_VERBOSE) - mac_info_attribute (MACINFO_BEGIN_LABEL); - } -} - -static void -output_string_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_string_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - member_attribute (TYPE_CONTEXT (type)); - /* this is a fixed length string */ - byte_size_attribute (type); -} - -static void -output_inheritance_die (arg) - register void *arg; -{ - register tree binfo = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_inheritance); - sibling_attribute (); - type_attribute (BINFO_TYPE (binfo), 0, 0); - data_member_location_attribute (binfo); - if (TREE_VIA_VIRTUAL (binfo)) - { - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_virtual); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); - } - if (TREE_VIA_PUBLIC (binfo)) - { - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_public); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); - } - else if (TREE_VIA_PROTECTED (binfo)) - { - ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_protected); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); - } -} - -static void -output_structure_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_structure_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - name_attribute (type_tag (type)); - member_attribute (TYPE_CONTEXT (type)); - - /* If this type has been completed, then give it a byte_size attribute - and prepare to give a list of members. Otherwise, don't do either of - these things. In the latter case, we will not be generating a list - of members (since we don't have any idea what they might be for an - incomplete type). */ - - if (TYPE_SIZE (type)) - { - dienum_push (); - byte_size_attribute (type); - } -} - -/* Output a DIE to represent a declared function (either file-scope - or block-local) which has "internal linkage" (according to ANSI-C). */ - -static void -output_local_subroutine_die (arg) - register void *arg; -{ - register tree decl = arg; - register tree origin = decl_ultimate_origin (decl); - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_subroutine); - sibling_attribute (); - dienum_push (); - if (origin != NULL) - abstract_origin_attribute (origin); - else - { - register tree type = TREE_TYPE (decl); - - name_and_src_coords_attributes (decl); - inline_attribute (decl); - prototyped_attribute (type); - member_attribute (DECL_CONTEXT (decl)); - type_attribute (TREE_TYPE (type), 0, 0); - pure_or_virtual_attribute (decl); - } - if (DECL_ABSTRACT (decl)) - equate_decl_number_to_die_number (decl); - else - { - /* Avoid getting screwed up in cases where a function was declared - static but where no definition was ever given for it. */ - - if (TREE_ASM_WRITTEN (decl)) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - low_pc_attribute (function_start_label (decl)); - sprintf (label, FUNC_END_LABEL_FMT, current_funcdef_number); - high_pc_attribute (label); - if (use_gnu_debug_info_extensions) - { - sprintf (label, BODY_BEGIN_LABEL_FMT, current_funcdef_number); - body_begin_attribute (label); - sprintf (label, BODY_END_LABEL_FMT, current_funcdef_number); - body_end_attribute (label); - } - } - } -} - -static void -output_subroutine_type_die (arg) - register void *arg; -{ - register tree type = arg; - register tree return_type = TREE_TYPE (type); - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_subroutine_type); - sibling_attribute (); - dienum_push (); - equate_type_number_to_die_number (type); - prototyped_attribute (type); - member_attribute (TYPE_CONTEXT (type)); - type_attribute (return_type, 0, 0); -} - -static void -output_typedef_die (arg) - register void *arg; -{ - register tree decl = arg; - register tree origin = decl_ultimate_origin (decl); - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_typedef); - sibling_attribute (); - if (origin != NULL) - abstract_origin_attribute (origin); - else - { - name_and_src_coords_attributes (decl); - member_attribute (DECL_CONTEXT (decl)); - type_attribute (TREE_TYPE (decl), - TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); - } - if (DECL_ABSTRACT (decl)) - equate_decl_number_to_die_number (decl); -} - -static void -output_union_type_die (arg) - register void *arg; -{ - register tree type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_union_type); - sibling_attribute (); - equate_type_number_to_die_number (type); - name_attribute (type_tag (type)); - member_attribute (TYPE_CONTEXT (type)); - - /* If this type has been completed, then give it a byte_size attribute - and prepare to give a list of members. Otherwise, don't do either of - these things. In the latter case, we will not be generating a list - of members (since we don't have any idea what they might be for an - incomplete type). */ - - if (TYPE_SIZE (type)) - { - dienum_push (); - byte_size_attribute (type); - } -} - -/* Generate a special type of DIE used as a stand-in for a trailing ellipsis - at the end of an (ANSI prototyped) formal parameters list. */ - -static void -output_unspecified_parameters_die (arg) - register void *arg; -{ - register tree decl_or_type = arg; - - ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_unspecified_parameters); - sibling_attribute (); - - /* This kludge is here only for the sake of being compatible with what - the USL CI5 C compiler does. The specification of Dwarf Version 1 - doesn't say that TAG_unspecified_parameters DIEs should contain any - attributes other than the AT_sibling attribute, but they are certainly - allowed to contain additional attributes, and the CI5 compiler - generates AT_name, AT_fund_type, and AT_location attributes within - TAG_unspecified_parameters DIEs which appear in the child lists for - DIEs representing function definitions, so we do likewise here. */ - - if (TREE_CODE (decl_or_type) == FUNCTION_DECL && DECL_INITIAL (decl_or_type)) - { - name_attribute ("..."); - fund_type_attribute (FT_pointer); - /* location_attribute (?); */ - } -} - -static void -output_padded_null_die (arg) - register void *arg ATTRIBUTE_UNUSED; -{ - ASM_OUTPUT_ALIGN (asm_out_file, 2); /* 2**2 == 4 */ -} - -/*************************** end of DIEs *********************************/ - -/* Generate some type of DIE. This routine generates the generic outer - wrapper stuff which goes around all types of DIE's (regardless of their - TAGs. All forms of DIEs start with a DIE-specific label, followed by a - DIE-length word, followed by the guts of the DIE itself. After the guts - of the DIE, there must always be a terminator label for the DIE. */ - -static void -output_die (die_specific_output_function, param) - register void (*die_specific_output_function) PROTO ((void *)); - register void *param; -{ - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - current_dienum = NEXT_DIE_NUM; - NEXT_DIE_NUM = next_unused_dienum; - - sprintf (begin_label, DIE_BEGIN_LABEL_FMT, current_dienum); - sprintf (end_label, DIE_END_LABEL_FMT, current_dienum); - - /* Write a label which will act as the name for the start of this DIE. */ - - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - - /* Write the DIE-length word. */ - - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label); - - /* Fill in the guts of the DIE. */ - - next_unused_dienum++; - die_specific_output_function (param); - - /* Write a label which will act as the name for the end of this DIE. */ - - ASM_OUTPUT_LABEL (asm_out_file, end_label); -} - -static void -end_sibling_chain () -{ - char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - current_dienum = NEXT_DIE_NUM; - NEXT_DIE_NUM = next_unused_dienum; - - sprintf (begin_label, DIE_BEGIN_LABEL_FMT, current_dienum); - - /* Write a label which will act as the name for the start of this DIE. */ - - ASM_OUTPUT_LABEL (asm_out_file, begin_label); - - /* Write the DIE-length word. */ - - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 4); - - dienum_pop (); -} - -/* Generate a list of nameless TAG_formal_parameter DIEs (and perhaps a - TAG_unspecified_parameters DIE) to represent the types of the formal - parameters as specified in some function type specification (except - for those which appear as part of a function *definition*). - - Note that we must be careful here to output all of the parameter - DIEs *before* we output any DIEs needed to represent the types of - the formal parameters. This keeps svr4 SDB happy because it - (incorrectly) thinks that the first non-parameter DIE it sees ends - the formal parameter list. */ - -static void -output_formal_types (function_or_method_type) - register tree function_or_method_type; -{ - register tree link; - register tree formal_type = NULL; - register tree first_parm_type = TYPE_ARG_TYPES (function_or_method_type); - - /* Set TREE_ASM_WRITTEN while processing the parameters, lest we - get bogus recursion when outputting tagged types local to a - function declaration. */ - int save_asm_written = TREE_ASM_WRITTEN (function_or_method_type); - TREE_ASM_WRITTEN (function_or_method_type) = 1; - - /* In the case where we are generating a formal types list for a C++ - non-static member function type, skip over the first thing on the - TYPE_ARG_TYPES list because it only represents the type of the - hidden `this pointer'. The debugger should be able to figure - out (without being explicitly told) that this non-static member - function type takes a `this pointer' and should be able to figure - what the type of that hidden parameter is from the AT_member - attribute of the parent TAG_subroutine_type DIE. */ - - if (TREE_CODE (function_or_method_type) == METHOD_TYPE) - first_parm_type = TREE_CHAIN (first_parm_type); - - /* Make our first pass over the list of formal parameter types and output - a TAG_formal_parameter DIE for each one. */ - - for (link = first_parm_type; link; link = TREE_CHAIN (link)) - { - formal_type = TREE_VALUE (link); - if (formal_type == void_type_node) - break; - - /* Output a (nameless) DIE to represent the formal parameter itself. */ - - output_die (output_formal_parameter_die, formal_type); - } - - /* If this function type has an ellipsis, add a TAG_unspecified_parameters - DIE to the end of the parameter list. */ - - if (formal_type != void_type_node) - output_die (output_unspecified_parameters_die, function_or_method_type); - - /* Make our second (and final) pass over the list of formal parameter types - and output DIEs to represent those types (as necessary). */ - - for (link = TYPE_ARG_TYPES (function_or_method_type); - link; - link = TREE_CHAIN (link)) - { - formal_type = TREE_VALUE (link); - if (formal_type == void_type_node) - break; - - output_type (formal_type, function_or_method_type); - } - - TREE_ASM_WRITTEN (function_or_method_type) = save_asm_written; -} - -/* Remember a type in the pending_types_list. */ - -static void -pend_type (type) - register tree type; -{ - if (pending_types == pending_types_allocated) - { - pending_types_allocated += PENDING_TYPES_INCREMENT; - pending_types_list - = (tree *) xrealloc (pending_types_list, - sizeof (tree) * pending_types_allocated); - } - pending_types_list[pending_types++] = type; - - /* Mark the pending type as having been output already (even though - it hasn't been). This prevents the type from being added to the - pending_types_list more than once. */ - - TREE_ASM_WRITTEN (type) = 1; -} - -/* Return non-zero if it is legitimate to output DIEs to represent a - given type while we are generating the list of child DIEs for some - DIE (e.g. a function or lexical block DIE) associated with a given scope. - - See the comments within the function for a description of when it is - considered legitimate to output DIEs for various kinds of types. - - Note that TYPE_CONTEXT(type) may be NULL (to indicate global scope) - or it may point to a BLOCK node (for types local to a block), or to a - FUNCTION_DECL node (for types local to the heading of some function - definition), or to a FUNCTION_TYPE node (for types local to the - prototyped parameter list of a function type specification), or to a - RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node - (in the case of C++ nested types). - - The `scope' parameter should likewise be NULL or should point to a - BLOCK node, a FUNCTION_DECL node, a FUNCTION_TYPE node, a RECORD_TYPE - node, a UNION_TYPE node, or a QUAL_UNION_TYPE node. - - This function is used only for deciding when to "pend" and when to - "un-pend" types to/from the pending_types_list. - - Note that we sometimes make use of this "type pending" feature in a - rather twisted way to temporarily delay the production of DIEs for the - types of formal parameters. (We do this just to make svr4 SDB happy.) - It order to delay the production of DIEs representing types of formal - parameters, callers of this function supply `fake_containing_scope' as - the `scope' parameter to this function. Given that fake_containing_scope - is a tagged type which is *not* the containing scope for *any* other type, - the desired effect is achieved, i.e. output of DIEs representing types - is temporarily suspended, and any type DIEs which would have otherwise - been output are instead placed onto the pending_types_list. Later on, - we force these (temporarily pended) types to be output simply by calling - `output_pending_types_for_scope' with an actual argument equal to the - true scope of the types we temporarily pended. */ - -static inline int -type_ok_for_scope (type, scope) - register tree type; - register tree scope; -{ - /* Tagged types (i.e. struct, union, and enum types) must always be - output only in the scopes where they actually belong (or else the - scoping of their own tag names and the scoping of their member - names will be incorrect). Non-tagged-types on the other hand can - generally be output anywhere, except that svr4 SDB really doesn't - want to see them nested within struct or union types, so here we - say it is always OK to immediately output any such a (non-tagged) - type, so long as we are not within such a context. Note that the - only kinds of non-tagged types which we will be dealing with here - (for C and C++ anyway) will be array types and function types. */ - - return is_tagged_type (type) - ? (TYPE_CONTEXT (type) == scope - /* Ignore namespaces for the moment. */ - || (scope == NULL_TREE - && TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL) - || (scope == NULL_TREE && is_tagged_type (TYPE_CONTEXT (type)) - && TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))) - : (scope == NULL_TREE || ! is_tagged_type (scope)); -} - -/* Output any pending types (from the pending_types list) which we can output - now (taking into account the scope that we are working on now). - - For each type output, remove the given type from the pending_types_list - *before* we try to output it. - - Note that we have to process the list in beginning-to-end order, - because the call made here to output_type may cause yet more types - to be added to the end of the list, and we may have to output some - of them too. */ - -static void -output_pending_types_for_scope (containing_scope) - register tree containing_scope; -{ - register unsigned i; - - for (i = 0; i < pending_types; ) - { - register tree type = pending_types_list[i]; - - if (type_ok_for_scope (type, containing_scope)) - { - register tree *mover; - register tree *limit; - - pending_types--; - limit = &pending_types_list[pending_types]; - for (mover = &pending_types_list[i]; mover < limit; mover++) - *mover = *(mover+1); - - /* Un-mark the type as having been output already (because it - hasn't been, really). Then call output_type to generate a - Dwarf representation of it. */ - - TREE_ASM_WRITTEN (type) = 0; - output_type (type, containing_scope); - - /* Don't increment the loop counter in this case because we - have shifted all of the subsequent pending types down one - element in the pending_types_list array. */ - } - else - i++; - } -} - -static void -output_type (type, containing_scope) - register tree type; - register tree containing_scope; -{ - if (type == 0 || type == error_mark_node) - return; - - /* We are going to output a DIE to represent the unqualified version of - this type (i.e. without any const or volatile qualifiers) so get - the main variant (i.e. the unqualified version) of this type now. */ - - type = type_main_variant (type); - - if (TREE_ASM_WRITTEN (type)) - { - if (finalizing && AGGREGATE_TYPE_P (type)) - { - register tree member; - - /* Some of our nested types might not have been defined when we - were written out before; force them out now. */ - - for (member = TYPE_FIELDS (type); member; - member = TREE_CHAIN (member)) - if (TREE_CODE (member) == TYPE_DECL - && ! TREE_ASM_WRITTEN (TREE_TYPE (member))) - output_type (TREE_TYPE (member), containing_scope); - } - return; - } - - /* If this is a nested type whose containing class hasn't been - written out yet, writing it out will cover this one, too. */ - - if (TYPE_CONTEXT (type) - && TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't' - && ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type))) - { - output_type (TYPE_CONTEXT (type), containing_scope); - return; - } - - /* Don't generate any DIEs for this type now unless it is OK to do so - (based upon what `type_ok_for_scope' tells us). */ - - if (! type_ok_for_scope (type, containing_scope)) - { - pend_type (type); - return; - } - - switch (TREE_CODE (type)) - { - case ERROR_MARK: - break; - - case POINTER_TYPE: - case REFERENCE_TYPE: - /* Prevent infinite recursion in cases where this is a recursive - type. Recursive types are possible in Ada. */ - TREE_ASM_WRITTEN (type) = 1; - /* For these types, all that is required is that we output a DIE - (or a set of DIEs) to represent the "basis" type. */ - output_type (TREE_TYPE (type), containing_scope); - break; - - case OFFSET_TYPE: - /* This code is used for C++ pointer-to-data-member types. */ - /* Output a description of the relevant class type. */ - output_type (TYPE_OFFSET_BASETYPE (type), containing_scope); - /* Output a description of the type of the object pointed to. */ - output_type (TREE_TYPE (type), containing_scope); - /* Now output a DIE to represent this pointer-to-data-member type - itself. */ - output_die (output_ptr_to_mbr_type_die, type); - break; - - case SET_TYPE: - output_type (TYPE_DOMAIN (type), containing_scope); - output_die (output_set_type_die, type); - break; - - case FILE_TYPE: - output_type (TREE_TYPE (type), containing_scope); - abort (); /* No way to represent these in Dwarf yet! */ - break; - - case FUNCTION_TYPE: - /* Force out return type (in case it wasn't forced out already). */ - output_type (TREE_TYPE (type), containing_scope); - output_die (output_subroutine_type_die, type); - output_formal_types (type); - end_sibling_chain (); - break; - - case METHOD_TYPE: - /* Force out return type (in case it wasn't forced out already). */ - output_type (TREE_TYPE (type), containing_scope); - output_die (output_subroutine_type_die, type); - output_formal_types (type); - end_sibling_chain (); - break; - - case ARRAY_TYPE: - if (TYPE_STRING_FLAG (type) && TREE_CODE(TREE_TYPE(type)) == CHAR_TYPE) - { - output_type (TREE_TYPE (type), containing_scope); - output_die (output_string_type_die, type); - } - else - { - register tree element_type; - - element_type = TREE_TYPE (type); - while (TREE_CODE (element_type) == ARRAY_TYPE) - element_type = TREE_TYPE (element_type); - - output_type (element_type, containing_scope); - output_die (output_array_type_die, type); - } - break; - - case ENUMERAL_TYPE: - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - - /* For a non-file-scope tagged type, we can always go ahead and - output a Dwarf description of this type right now, even if - the type in question is still incomplete, because if this - local type *was* ever completed anywhere within its scope, - that complete definition would already have been attached to - this RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE or ENUMERAL_TYPE - node by the time we reach this point. That's true because of the - way the front-end does its processing of file-scope declarations (of - functions and class types) within which other types might be - nested. The C and C++ front-ends always gobble up such "local - scope" things en-mass before they try to output *any* debugging - information for any of the stuff contained inside them and thus, - we get the benefit here of what is (in effect) a pre-resolution - of forward references to tagged types in local scopes. - - Note however that for file-scope tagged types we cannot assume - that such pre-resolution of forward references has taken place. - A given file-scope tagged type may appear to be incomplete when - we reach this point, but it may yet be given a full definition - (at file-scope) later on during compilation. In order to avoid - generating a premature (and possibly incorrect) set of Dwarf - DIEs for such (as yet incomplete) file-scope tagged types, we - generate nothing at all for as-yet incomplete file-scope tagged - types here unless we are making our special "finalization" pass - for file-scope things at the very end of compilation. At that - time, we will certainly know as much about each file-scope tagged - type as we are ever going to know, so at that point in time, we - can safely generate correct Dwarf descriptions for these file- - scope tagged types. */ - - if (TYPE_SIZE (type) == 0 - && (TYPE_CONTEXT (type) == NULL - || (TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't' - && TREE_CODE (TYPE_CONTEXT (type)) != FUNCTION_TYPE - && TREE_CODE (TYPE_CONTEXT (type)) != METHOD_TYPE)) - && !finalizing) - return; /* EARLY EXIT! Avoid setting TREE_ASM_WRITTEN. */ - - /* Prevent infinite recursion in cases where the type of some - member of this type is expressed in terms of this type itself. */ - - TREE_ASM_WRITTEN (type) = 1; - - /* Output a DIE to represent the tagged type itself. */ - - switch (TREE_CODE (type)) - { - case ENUMERAL_TYPE: - output_die (output_enumeration_type_die, type); - return; /* a special case -- nothing left to do so just return */ - - case RECORD_TYPE: - output_die (output_structure_type_die, type); - break; - - case UNION_TYPE: - case QUAL_UNION_TYPE: - output_die (output_union_type_die, type); - break; - - default: - abort (); /* Should never happen. */ - } - - /* If this is not an incomplete type, output descriptions of - each of its members. - - Note that as we output the DIEs necessary to represent the - members of this record or union type, we will also be trying - to output DIEs to represent the *types* of those members. - However the `output_type' function (above) will specifically - avoid generating type DIEs for member types *within* the list - of member DIEs for this (containing) type execpt for those - types (of members) which are explicitly marked as also being - members of this (containing) type themselves. The g++ front- - end can force any given type to be treated as a member of some - other (containing) type by setting the TYPE_CONTEXT of the - given (member) type to point to the TREE node representing the - appropriate (containing) type. - */ - - if (TYPE_SIZE (type)) - { - /* First output info about the base classes. */ - if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type)) - { - register tree bases = TYPE_BINFO_BASETYPES (type); - register int n_bases = TREE_VEC_LENGTH (bases); - register int i; - - for (i = 0; i < n_bases; i++) - output_die (output_inheritance_die, TREE_VEC_ELT (bases, i)); - } - - ++in_class; - - { - register tree normal_member; - - /* Now output info about the data members and type members. */ - - for (normal_member = TYPE_FIELDS (type); - normal_member; - normal_member = TREE_CHAIN (normal_member)) - output_decl (normal_member, type); - } - - { - register tree func_member; - - /* Now output info about the function members (if any). */ - - for (func_member = TYPE_METHODS (type); - func_member; - func_member = TREE_CHAIN (func_member)) - output_decl (func_member, type); - } - - --in_class; - - /* RECORD_TYPEs, UNION_TYPEs, and QUAL_UNION_TYPEs are themselves - scopes (at least in C++) so we must now output any nested - pending types which are local just to this type. */ - - output_pending_types_for_scope (type); - - end_sibling_chain (); /* Terminate member chain. */ - } - - break; - - case VOID_TYPE: - case INTEGER_TYPE: - case REAL_TYPE: - case COMPLEX_TYPE: - case BOOLEAN_TYPE: - case CHAR_TYPE: - break; /* No DIEs needed for fundamental types. */ - - case LANG_TYPE: /* No Dwarf representation currently defined. */ - break; - - default: - abort (); - } - - TREE_ASM_WRITTEN (type) = 1; -} - -static void -output_tagged_type_instantiation (type) - register tree type; -{ - if (type == 0 || type == error_mark_node) - return; - - /* We are going to output a DIE to represent the unqualified version of - this type (i.e. without any const or volatile qualifiers) so make - sure that we have the main variant (i.e. the unqualified version) of - this type now. */ - - if (type != type_main_variant (type)) - abort (); - - if (!TREE_ASM_WRITTEN (type)) - abort (); - - switch (TREE_CODE (type)) - { - case ERROR_MARK: - break; - - case ENUMERAL_TYPE: - output_die (output_inlined_enumeration_type_die, type); - break; - - case RECORD_TYPE: - output_die (output_inlined_structure_type_die, type); - break; - - case UNION_TYPE: - case QUAL_UNION_TYPE: - output_die (output_inlined_union_type_die, type); - break; - - default: - abort (); /* Should never happen. */ - } -} - -/* Output a TAG_lexical_block DIE followed by DIEs to represent all of - the things which are local to the given block. */ - -static void -output_block (stmt, depth) - register tree stmt; - int depth; -{ - register int must_output_die = 0; - register tree origin; - register enum tree_code origin_code; - - /* Ignore blocks never really used to make RTL. */ - - if (! stmt || ! TREE_USED (stmt)) - return; - - /* Determine the "ultimate origin" of this block. This block may be an - inlined instance of an inlined instance of inline function, so we - have to trace all of the way back through the origin chain to find - out what sort of node actually served as the original seed for the - creation of the current block. */ - - origin = block_ultimate_origin (stmt); - origin_code = (origin != NULL) ? TREE_CODE (origin) : ERROR_MARK; - - /* Determine if we need to output any Dwarf DIEs at all to represent this - block. */ - - if (origin_code == FUNCTION_DECL) - /* The outer scopes for inlinings *must* always be represented. We - generate TAG_inlined_subroutine DIEs for them. (See below.) */ - must_output_die = 1; - else - { - /* In the case where the current block represents an inlining of the - "body block" of an inline function, we must *NOT* output any DIE - for this block because we have already output a DIE to represent - the whole inlined function scope and the "body block" of any - function doesn't really represent a different scope according to - ANSI C rules. So we check here to make sure that this block does - not represent a "body block inlining" before trying to set the - `must_output_die' flag. */ - - if (! is_body_block (origin ? origin : stmt)) - { - /* Determine if this block directly contains any "significant" - local declarations which we will need to output DIEs for. */ - - if (debug_info_level > DINFO_LEVEL_TERSE) - /* We are not in terse mode so *any* local declaration counts - as being a "significant" one. */ - must_output_die = (BLOCK_VARS (stmt) != NULL); - else - { - register tree decl; - - /* We are in terse mode, so only local (nested) function - definitions count as "significant" local declarations. */ - - for (decl = BLOCK_VARS (stmt); decl; decl = TREE_CHAIN (decl)) - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) - { - must_output_die = 1; - break; - } - } - } - } - - /* It would be a waste of space to generate a Dwarf TAG_lexical_block - DIE for any block which contains no significant local declarations - at all. Rather, in such cases we just call `output_decls_for_scope' - so that any needed Dwarf info for any sub-blocks will get properly - generated. Note that in terse mode, our definition of what constitutes - a "significant" local declaration gets restricted to include only - inlined function instances and local (nested) function definitions. */ - - if (origin_code == FUNCTION_DECL && BLOCK_ABSTRACT (stmt)) - /* We don't care about an abstract inlined subroutine. */; - else if (must_output_die) - { - output_die ((origin_code == FUNCTION_DECL) - ? output_inlined_subroutine_die - : output_lexical_block_die, - stmt); - output_decls_for_scope (stmt, depth); - end_sibling_chain (); - } - else - output_decls_for_scope (stmt, depth); -} - -/* Output all of the decls declared within a given scope (also called - a `binding contour') and (recursively) all of it's sub-blocks. */ - -static void -output_decls_for_scope (stmt, depth) - register tree stmt; - int depth; -{ - /* Ignore blocks never really used to make RTL. */ - - if (! stmt || ! TREE_USED (stmt)) - return; - - if (! BLOCK_ABSTRACT (stmt) && depth > 0) - next_block_number++; - - /* Output the DIEs to represent all of the data objects, functions, - typedefs, and tagged types declared directly within this block - but not within any nested sub-blocks. */ - - { - register tree decl; - - for (decl = BLOCK_VARS (stmt); decl; decl = TREE_CHAIN (decl)) - output_decl (decl, stmt); - } - - output_pending_types_for_scope (stmt); - - /* Output the DIEs to represent all sub-blocks (and the items declared - therein) of this block. */ - - { - register tree subblocks; - - for (subblocks = BLOCK_SUBBLOCKS (stmt); - subblocks; - subblocks = BLOCK_CHAIN (subblocks)) - output_block (subblocks, depth + 1); - } -} - -/* Is this a typedef we can avoid emitting? */ - -inline static int -is_redundant_typedef (decl) - register tree decl; -{ - if (TYPE_DECL_IS_STUB (decl)) - return 1; - if (DECL_ARTIFICIAL (decl) - && DECL_CONTEXT (decl) - && is_tagged_type (DECL_CONTEXT (decl)) - && TREE_CODE (TYPE_NAME (DECL_CONTEXT (decl))) == TYPE_DECL - && DECL_NAME (decl) == DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))) - /* Also ignore the artificial member typedef for the class name. */ - return 1; - return 0; -} - -/* Output Dwarf .debug information for a decl described by DECL. */ - -static void -output_decl (decl, containing_scope) - register tree decl; - register tree containing_scope; -{ - /* Make a note of the decl node we are going to be working on. We may - need to give the user the source coordinates of where it appeared in - case we notice (later on) that something about it looks screwy. */ - - dwarf_last_decl = decl; - - if (TREE_CODE (decl) == ERROR_MARK) - return; - - /* If a structure is declared within an initialization, e.g. as the - operand of a sizeof, then it will not have a name. We don't want - to output a DIE for it, as the tree nodes are in the temporary obstack */ - - if ((TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE - || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE) - && ((DECL_NAME (decl) == 0 && TYPE_NAME (TREE_TYPE (decl)) == 0) - || (TYPE_FIELDS (TREE_TYPE (decl)) - && (TREE_CODE (TYPE_FIELDS (TREE_TYPE (decl))) == ERROR_MARK)))) - return; - - /* If this ..._DECL node is marked to be ignored, then ignore it. - But don't ignore a function definition, since that would screw - up our count of blocks, and that it turn will completely screw up the - labels we will reference in subsequent AT_low_pc and AT_high_pc - attributes (for subsequent blocks). */ - - if (DECL_IGNORED_P (decl) && TREE_CODE (decl) != FUNCTION_DECL) - return; - - switch (TREE_CODE (decl)) - { - case CONST_DECL: - /* The individual enumerators of an enum type get output when we - output the Dwarf representation of the relevant enum type itself. */ - break; - - case FUNCTION_DECL: - /* If we are in terse mode, don't output any DIEs to represent - mere function declarations. Also, if we are conforming - to the DWARF version 1 specification, don't output DIEs for - mere function declarations. */ - - if (DECL_INITIAL (decl) == NULL_TREE) -#if (DWARF_VERSION > 1) - if (debug_info_level <= DINFO_LEVEL_TERSE) -#endif - break; - - /* Before we describe the FUNCTION_DECL itself, make sure that we - have described its return type. */ - - output_type (TREE_TYPE (TREE_TYPE (decl)), containing_scope); - - { - /* And its containing type. */ - register tree origin = decl_class_context (decl); - if (origin) - output_type (origin, containing_scope); - } - - /* If the following DIE will represent a function definition for a - function with "extern" linkage, output a special "pubnames" DIE - label just ahead of the actual DIE. A reference to this label - was already generated in the .debug_pubnames section sub-entry - for this function definition. */ - - if (TREE_PUBLIC (decl)) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number++); - ASM_OUTPUT_LABEL (asm_out_file, label); - } - - /* Now output a DIE to represent the function itself. */ - - output_die (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl) - ? output_global_subroutine_die - : output_local_subroutine_die, - decl); - - /* Now output descriptions of the arguments for this function. - This gets (unnecessarily?) complex because of the fact that - the DECL_ARGUMENT list for a FUNCTION_DECL doesn't indicate - cases where there was a trailing `...' at the end of the formal - parameter list. In order to find out if there was a trailing - ellipsis or not, we must instead look at the type associated - with the FUNCTION_DECL. This will be a node of type FUNCTION_TYPE. - If the chain of type nodes hanging off of this FUNCTION_TYPE node - ends with a void_type_node then there should *not* be an ellipsis - at the end. */ - - /* In the case where we are describing a mere function declaration, all - we need to do here (and all we *can* do here) is to describe - the *types* of its formal parameters. */ - - if (decl != current_function_decl || in_class) - output_formal_types (TREE_TYPE (decl)); - else - { - /* Generate DIEs to represent all known formal parameters */ - - register tree arg_decls = DECL_ARGUMENTS (decl); - register tree parm; - - /* WARNING! Kludge zone ahead! Here we have a special - hack for svr4 SDB compatibility. Instead of passing the - current FUNCTION_DECL node as the second parameter (i.e. - the `containing_scope' parameter) to `output_decl' (as - we ought to) we instead pass a pointer to our own private - fake_containing_scope node. That node is a RECORD_TYPE - node which NO OTHER TYPE may ever actually be a member of. - - This pointer will ultimately get passed into `output_type' - as its `containing_scope' parameter. `Output_type' will - then perform its part in the hack... i.e. it will pend - the type of the formal parameter onto the pending_types - list. Later on, when we are done generating the whole - sequence of formal parameter DIEs for this function - definition, we will un-pend all previously pended types - of formal parameters for this function definition. - - This whole kludge prevents any type DIEs from being - mixed in with the formal parameter DIEs. That's good - because svr4 SDB believes that the list of formal - parameter DIEs for a function ends wherever the first - non-formal-parameter DIE appears. Thus, we have to - keep the formal parameter DIEs segregated. They must - all appear (consecutively) at the start of the list of - children for the DIE representing the function definition. - Then (and only then) may we output any additional DIEs - needed to represent the types of these formal parameters. - */ - - /* - When generating DIEs, generate the unspecified_parameters - DIE instead if we come across the arg "__builtin_va_alist" - */ - - for (parm = arg_decls; parm; parm = TREE_CHAIN (parm)) - if (TREE_CODE (parm) == PARM_DECL) - { - if (DECL_NAME(parm) && - !strcmp(IDENTIFIER_POINTER(DECL_NAME(parm)), - "__builtin_va_alist") ) - output_die (output_unspecified_parameters_die, decl); - else - output_decl (parm, fake_containing_scope); - } - - /* - Now that we have finished generating all of the DIEs to - represent the formal parameters themselves, force out - any DIEs needed to represent their types. We do this - simply by un-pending all previously pended types which - can legitimately go into the chain of children DIEs for - the current FUNCTION_DECL. - */ - - output_pending_types_for_scope (decl); - - /* - Decide whether we need a unspecified_parameters DIE at the end. - There are 2 more cases to do this for: - 1) the ansi ... declaration - this is detectable when the end - of the arg list is not a void_type_node - 2) an unprototyped function declaration (not a definition). This - just means that we have no info about the parameters at all. - */ - - { - register tree fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); - - if (fn_arg_types) - { - /* this is the prototyped case, check for ... */ - if (TREE_VALUE (tree_last (fn_arg_types)) != void_type_node) - output_die (output_unspecified_parameters_die, decl); - } - else - { - /* this is unprototyped, check for undefined (just declaration) */ - if (!DECL_INITIAL (decl)) - output_die (output_unspecified_parameters_die, decl); - } - } - - /* Output Dwarf info for all of the stuff within the body of the - function (if it has one - it may be just a declaration). */ - - { - register tree outer_scope = DECL_INITIAL (decl); - - if (outer_scope && TREE_CODE (outer_scope) != ERROR_MARK) - { - /* Note that here, `outer_scope' is a pointer to the outermost - BLOCK node created to represent a function. - This outermost BLOCK actually represents the outermost - binding contour for the function, i.e. the contour in which - the function's formal parameters and labels get declared. - - Curiously, it appears that the front end doesn't actually - put the PARM_DECL nodes for the current function onto the - BLOCK_VARS list for this outer scope. (They are strung - off of the DECL_ARGUMENTS list for the function instead.) - The BLOCK_VARS list for the `outer_scope' does provide us - with a list of the LABEL_DECL nodes for the function however, - and we output DWARF info for those here. - - Just within the `outer_scope' there will be a BLOCK node - representing the function's outermost pair of curly braces, - and any blocks used for the base and member initializers of - a C++ constructor function. */ - - output_decls_for_scope (outer_scope, 0); - - /* Finally, force out any pending types which are local to the - outermost block of this function definition. These will - all have a TYPE_CONTEXT which points to the FUNCTION_DECL - node itself. */ - - output_pending_types_for_scope (decl); - } - } - } - - /* Generate a terminator for the list of stuff `owned' by this - function. */ - - end_sibling_chain (); - - break; - - case TYPE_DECL: - /* If we are in terse mode, don't generate any DIEs to represent - any actual typedefs. Note that even when we are in terse mode, - we must still output DIEs to represent those tagged types which - are used (directly or indirectly) in the specification of either - a return type or a formal parameter type of some function. */ - - if (debug_info_level <= DINFO_LEVEL_TERSE) - if (! TYPE_DECL_IS_STUB (decl) - || (! TYPE_USED_FOR_FUNCTION (TREE_TYPE (decl)) && ! in_class)) - return; - - /* In the special case of a TYPE_DECL node representing - the declaration of some type tag, if the given TYPE_DECL is - marked as having been instantiated from some other (original) - TYPE_DECL node (e.g. one which was generated within the original - definition of an inline function) we have to generate a special - (abbreviated) TAG_structure_type, TAG_union_type, or - TAG_enumeration-type DIE here. */ - - if (TYPE_DECL_IS_STUB (decl) && DECL_ABSTRACT_ORIGIN (decl)) - { - output_tagged_type_instantiation (TREE_TYPE (decl)); - return; - } - - output_type (TREE_TYPE (decl), containing_scope); - - if (! is_redundant_typedef (decl)) - /* Output a DIE to represent the typedef itself. */ - output_die (output_typedef_die, decl); - break; - - case LABEL_DECL: - if (debug_info_level >= DINFO_LEVEL_NORMAL) - output_die (output_label_die, decl); - break; - - case VAR_DECL: - /* If we are conforming to the DWARF version 1 specification, don't - generated any DIEs to represent mere external object declarations. */ - -#if (DWARF_VERSION <= 1) - if (DECL_EXTERNAL (decl) && ! TREE_PUBLIC (decl)) - break; -#endif - - /* If we are in terse mode, don't generate any DIEs to represent - any variable declarations or definitions. */ - - if (debug_info_level <= DINFO_LEVEL_TERSE) - break; - - /* Output any DIEs that are needed to specify the type of this data - object. */ - - output_type (TREE_TYPE (decl), containing_scope); - - { - /* And its containing type. */ - register tree origin = decl_class_context (decl); - if (origin) - output_type (origin, containing_scope); - } - - /* If the following DIE will represent a data object definition for a - data object with "extern" linkage, output a special "pubnames" DIE - label just ahead of the actual DIE. A reference to this label - was already generated in the .debug_pubnames section sub-entry - for this data object definition. */ - - if (TREE_PUBLIC (decl) && ! DECL_ABSTRACT (decl)) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number++); - ASM_OUTPUT_LABEL (asm_out_file, label); - } - - /* Now output the DIE to represent the data object itself. This gets - complicated because of the possibility that the VAR_DECL really - represents an inlined instance of a formal parameter for an inline - function. */ - - { - register void (*func) PROTO((void *)); - register tree origin = decl_ultimate_origin (decl); - - if (origin != NULL && TREE_CODE (origin) == PARM_DECL) - func = output_formal_parameter_die; - else - { - if (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) - func = output_global_variable_die; - else - func = output_local_variable_die; - } - output_die (func, decl); - } - break; - - case FIELD_DECL: - /* Ignore the nameless fields that are used to skip bits. */ - if (DECL_NAME (decl) != 0) - { - output_type (member_declared_type (decl), containing_scope); - output_die (output_member_die, decl); - } - break; - - case PARM_DECL: - /* Force out the type of this formal, if it was not forced out yet. - Note that here we can run afowl of a bug in "classic" svr4 SDB. - It should be able to grok the presence of type DIEs within a list - of TAG_formal_parameter DIEs, but it doesn't. */ - - output_type (TREE_TYPE (decl), containing_scope); - output_die (output_formal_parameter_die, decl); - break; - - default: - abort (); - } -} - -void -dwarfout_file_scope_decl (decl, set_finalizing) - register tree decl; - register int set_finalizing; -{ - if (TREE_CODE (decl) == ERROR_MARK) - return; - - /* If this ..._DECL node is marked to be ignored, then ignore it. We - gotta hope that the node in question doesn't represent a function - definition. If it does, then totally ignoring it is bound to screw - up our count of blocks, and that it turn will completely screw up the - labels we will reference in subsequent AT_low_pc and AT_high_pc - attributes (for subsequent blocks). (It's too bad that BLOCK nodes - don't carry their own sequence numbers with them!) */ - - if (DECL_IGNORED_P (decl)) - { - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) != NULL) - abort (); - return; - } - - switch (TREE_CODE (decl)) - { - case FUNCTION_DECL: - - /* Ignore this FUNCTION_DECL if it refers to a builtin declaration of - a builtin function. Explicit programmer-supplied declarations of - these same functions should NOT be ignored however. */ - - if (DECL_EXTERNAL (decl) && DECL_FUNCTION_CODE (decl)) - return; - - /* What we would really like to do here is to filter out all mere - file-scope declarations of file-scope functions which are never - referenced later within this translation unit (and keep all of - ones that *are* referenced later on) but we aren't clairvoyant, - so we have no idea which functions will be referenced in the - future (i.e. later on within the current translation unit). - So here we just ignore all file-scope function declarations - which are not also definitions. If and when the debugger needs - to know something about these functions, it wil have to hunt - around and find the DWARF information associated with the - *definition* of the function. - - Note that we can't just check `DECL_EXTERNAL' to find out which - FUNCTION_DECL nodes represent definitions and which ones represent - mere declarations. We have to check `DECL_INITIAL' instead. That's - because the C front-end supports some weird semantics for "extern - inline" function definitions. These can get inlined within the - current translation unit (an thus, we need to generate DWARF info - for their abstract instances so that the DWARF info for the - concrete inlined instances can have something to refer to) but - the compiler never generates any out-of-lines instances of such - things (despite the fact that they *are* definitions). The - important point is that the C front-end marks these "extern inline" - functions as DECL_EXTERNAL, but we need to generate DWARF for them - anyway. - - Note that the C++ front-end also plays some similar games for inline - function definitions appearing within include files which also - contain `#pragma interface' pragmas. */ - - if (DECL_INITIAL (decl) == NULL_TREE) - return; - - if (TREE_PUBLIC (decl) - && ! DECL_EXTERNAL (decl) - && ! DECL_ABSTRACT (decl)) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - /* Output a .debug_pubnames entry for a public function - defined in this compilation unit. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION); - sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, label); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, - IDENTIFIER_POINTER (DECL_NAME (decl))); - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - break; - - case VAR_DECL: - - /* Ignore this VAR_DECL if it refers to a file-scope extern data - object declaration and if the declaration was never even - referenced from within this entire compilation unit. We - suppress these DIEs in order to save space in the .debug section - (by eliminating entries which are probably useless). Note that - we must not suppress block-local extern declarations (whether - used or not) because that would screw-up the debugger's name - lookup mechanism and cause it to miss things which really ought - to be in scope at a given point. */ - - if (DECL_EXTERNAL (decl) && !TREE_USED (decl)) - return; - - if (TREE_PUBLIC (decl) - && ! DECL_EXTERNAL (decl) - && GET_CODE (DECL_RTL (decl)) == MEM - && ! DECL_ABSTRACT (decl)) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - if (debug_info_level >= DINFO_LEVEL_NORMAL) - { - /* Output a .debug_pubnames entry for a public variable - defined in this compilation unit. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION); - sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, label); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, - IDENTIFIER_POINTER (DECL_NAME (decl))); - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - if (DECL_INITIAL (decl) == NULL) - { - /* Output a .debug_aranges entry for a public variable - which is tentatively defined in this compilation unit. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, - (unsigned) int_size_in_bytes (TREE_TYPE (decl))); - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - } - - /* If we are in terse mode, don't generate any DIEs to represent - any variable declarations or definitions. */ - - if (debug_info_level <= DINFO_LEVEL_TERSE) - return; - - break; - - case TYPE_DECL: - /* Don't bother trying to generate any DIEs to represent any of the - normal built-in types for the language we are compiling, except - in cases where the types in question are *not* DWARF fundamental - types. We make an exception in the case of non-fundamental types - for the sake of objective C (and perhaps C++) because the GNU - front-ends for these languages may in fact create certain "built-in" - types which are (for example) RECORD_TYPEs. In such cases, we - really need to output these (non-fundamental) types because other - DIEs may contain references to them. */ - - /* Also ignore language dependent types here, because they are probably - also built-in types. If we didn't ignore them, then we would get - references to undefined labels because output_type doesn't support - them. So, for now, we need to ignore them to avoid assembler - errors. */ - - /* ??? This code is different than the equivalent code in dwarf2out.c. - The dwarf2out.c code is probably more correct. */ - - if (DECL_SOURCE_LINE (decl) == 0 - && (type_is_fundamental (TREE_TYPE (decl)) - || TREE_CODE (TREE_TYPE (decl)) == LANG_TYPE)) - return; - - /* If we are in terse mode, don't generate any DIEs to represent - any actual typedefs. Note that even when we are in terse mode, - we must still output DIEs to represent those tagged types which - are used (directly or indirectly) in the specification of either - a return type or a formal parameter type of some function. */ - - if (debug_info_level <= DINFO_LEVEL_TERSE) - if (! TYPE_DECL_IS_STUB (decl) - || ! TYPE_USED_FOR_FUNCTION (TREE_TYPE (decl))) - return; - - break; - - default: - return; - } - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION); - finalizing = set_finalizing; - output_decl (decl, NULL_TREE); - - /* NOTE: The call above to `output_decl' may have caused one or more - file-scope named types (i.e. tagged types) to be placed onto the - pending_types_list. We have to get those types off of that list - at some point, and this is the perfect time to do it. If we didn't - take them off now, they might still be on the list when cc1 finally - exits. That might be OK if it weren't for the fact that when we put - types onto the pending_types_list, we set the TREE_ASM_WRITTEN flag - for these types, and that causes them never to be output unless - `output_pending_types_for_scope' takes them off of the list and un-sets - their TREE_ASM_WRITTEN flags. */ - - output_pending_types_for_scope (NULL_TREE); - - /* The above call should have totally emptied the pending_types_list - if this is not a nested function or class. If this is a nested type, - then the remaining pending_types will be emitted when the containing type - is handled. */ - - if (! DECL_CONTEXT (decl)) - { - if (pending_types != 0) - abort (); - } - - ASM_OUTPUT_POP_SECTION (asm_out_file); - - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) != NULL) - current_funcdef_number++; -} - -/* Output a marker (i.e. a label) for the beginning of the generated code - for a lexical block. */ - -void -dwarfout_begin_block (blocknum) - register unsigned blocknum; -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - function_section (current_function_decl); - sprintf (label, BLOCK_BEGIN_LABEL_FMT, blocknum); - ASM_OUTPUT_LABEL (asm_out_file, label); -} - -/* Output a marker (i.e. a label) for the end of the generated code - for a lexical block. */ - -void -dwarfout_end_block (blocknum) - register unsigned blocknum; -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - function_section (current_function_decl); - sprintf (label, BLOCK_END_LABEL_FMT, blocknum); - ASM_OUTPUT_LABEL (asm_out_file, label); -} - -/* Output a marker (i.e. a label) at a point in the assembly code which - corresponds to a given source level label. */ - -void -dwarfout_label (insn) - register rtx insn; -{ - if (debug_info_level >= DINFO_LEVEL_NORMAL) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - function_section (current_function_decl); - sprintf (label, INSN_LABEL_FMT, current_funcdef_number, - (unsigned) INSN_UID (insn)); - ASM_OUTPUT_LABEL (asm_out_file, label); - } -} - -/* Output a marker (i.e. a label) for the point in the generated code where - the real body of the function begins (after parameters have been moved - to their home locations). */ - -void -dwarfout_begin_function () -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - if (! use_gnu_debug_info_extensions) - return; - function_section (current_function_decl); - sprintf (label, BODY_BEGIN_LABEL_FMT, current_funcdef_number); - ASM_OUTPUT_LABEL (asm_out_file, label); -} - -/* Output a marker (i.e. a label) for the point in the generated code where - the real body of the function ends (just before the epilogue code). */ - -void -dwarfout_end_function () -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - if (! use_gnu_debug_info_extensions) - return; - function_section (current_function_decl); - sprintf (label, BODY_END_LABEL_FMT, current_funcdef_number); - ASM_OUTPUT_LABEL (asm_out_file, label); -} - -/* Output a marker (i.e. a label) for the absolute end of the generated code - for a function definition. This gets called *after* the epilogue code - has been generated. */ - -void -dwarfout_end_epilogue () -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - /* Output a label to mark the endpoint of the code generated for this - function. */ - - sprintf (label, FUNC_END_LABEL_FMT, current_funcdef_number); - ASM_OUTPUT_LABEL (asm_out_file, label); -} - -static void -shuffle_filename_entry (new_zeroth) - register filename_entry *new_zeroth; -{ - filename_entry temp_entry; - register filename_entry *limit_p; - register filename_entry *move_p; - - if (new_zeroth == &filename_table[0]) - return; - - temp_entry = *new_zeroth; - - /* Shift entries up in the table to make room at [0]. */ - - limit_p = &filename_table[0]; - for (move_p = new_zeroth; move_p > limit_p; move_p--) - *move_p = *(move_p-1); - - /* Install the found entry at [0]. */ - - filename_table[0] = temp_entry; -} - -/* Create a new (string) entry for the .debug_sfnames section. */ - -static void -generate_new_sfname_entry () -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, SFNAMES_SECTION); - sprintf (label, SFNAMES_ENTRY_LABEL_FMT, filename_table[0].number); - ASM_OUTPUT_LABEL (asm_out_file, label); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, - filename_table[0].name - ? filename_table[0].name - : ""); - ASM_OUTPUT_POP_SECTION (asm_out_file); -} - -/* Lookup a filename (in the list of filenames that we know about here in - dwarfout.c) and return its "index". The index of each (known) filename - is just a unique number which is associated with only that one filename. - We need such numbers for the sake of generating labels (in the - .debug_sfnames section) and references to those unique labels (in the - .debug_srcinfo and .debug_macinfo sections). - - If the filename given as an argument is not found in our current list, - add it to the list and assign it the next available unique index number. - - Whatever we do (i.e. whether we find a pre-existing filename or add a new - one), we shuffle the filename found (or added) up to the zeroth entry of - our list of filenames (which is always searched linearly). We do this so - as to optimize the most common case for these filename lookups within - dwarfout.c. The most common case by far is the case where we call - lookup_filename to lookup the very same filename that we did a lookup - on the last time we called lookup_filename. We make sure that this - common case is fast because such cases will constitute 99.9% of the - lookups we ever do (in practice). - - If we add a new filename entry to our table, we go ahead and generate - the corresponding entry in the .debug_sfnames section right away. - Doing so allows us to avoid tickling an assembler bug (present in some - m68k assemblers) which yields assembly-time errors in cases where the - difference of two label addresses is taken and where the two labels - are in a section *other* than the one where the difference is being - calculated, and where at least one of the two symbol references is a - forward reference. (This bug could be tickled by our .debug_srcinfo - entries if we don't output their corresponding .debug_sfnames entries - before them.) */ - -static unsigned -lookup_filename (file_name) - char *file_name; -{ - register filename_entry *search_p; - register filename_entry *limit_p = &filename_table[ft_entries]; - - for (search_p = filename_table; search_p < limit_p; search_p++) - if (!strcmp (file_name, search_p->name)) - { - /* When we get here, we have found the filename that we were - looking for in the filename_table. Now we want to make sure - that it gets moved to the zero'th entry in the table (if it - is not already there) so that subsequent attempts to find the - same filename will find it as quickly as possible. */ - - shuffle_filename_entry (search_p); - return filename_table[0].number; - } - - /* We come here whenever we have a new filename which is not registered - in the current table. Here we add it to the table. */ - - /* Prepare to add a new table entry by making sure there is enough space - in the table to do so. If not, expand the current table. */ - - if (ft_entries == ft_entries_allocated) - { - ft_entries_allocated += FT_ENTRIES_INCREMENT; - filename_table - = (filename_entry *) - xrealloc (filename_table, - ft_entries_allocated * sizeof (filename_entry)); - } - - /* Initially, add the new entry at the end of the filename table. */ - - filename_table[ft_entries].number = ft_entries; - filename_table[ft_entries].name = xstrdup (file_name); - - /* Shuffle the new entry into filename_table[0]. */ - - shuffle_filename_entry (&filename_table[ft_entries]); - - if (debug_info_level >= DINFO_LEVEL_NORMAL) - generate_new_sfname_entry (); - - ft_entries++; - return filename_table[0].number; -} - -static void -generate_srcinfo_entry (line_entry_num, files_entry_num) - unsigned line_entry_num; - unsigned files_entry_num; -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION); - sprintf (label, LINE_ENTRY_LABEL_FMT, line_entry_num); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, LINE_BEGIN_LABEL); - sprintf (label, SFNAMES_ENTRY_LABEL_FMT, files_entry_num); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, SFNAMES_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); -} - -void -dwarfout_line (filename, line) - register char *filename; - register unsigned line; -{ - if (debug_info_level >= DINFO_LEVEL_NORMAL - /* We can't emit line number info for functions in separate sections, - because the assembler can't subtract labels in different sections. */ - && DECL_SECTION_NAME (current_function_decl) == NULL_TREE) - { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - static unsigned last_line_entry_num = 0; - static unsigned prev_file_entry_num = (unsigned) -1; - register unsigned this_file_entry_num; - - function_section (current_function_decl); - sprintf (label, LINE_CODE_LABEL_FMT, ++last_line_entry_num); - ASM_OUTPUT_LABEL (asm_out_file, label); - - fputc ('\n', asm_out_file); - - if (use_gnu_debug_info_extensions) - this_file_entry_num = lookup_filename (filename); - else - this_file_entry_num = (unsigned) -1; - - ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION); - if (this_file_entry_num != prev_file_entry_num) - { - char line_entry_label[MAX_ARTIFICIAL_LABEL_BYTES]; - - sprintf (line_entry_label, LINE_ENTRY_LABEL_FMT, last_line_entry_num); - ASM_OUTPUT_LABEL (asm_out_file, line_entry_label); - } - - { - register char *tail = rindex (filename, '/'); - - if (tail != NULL) - filename = tail; - } - - fprintf (asm_out_file, "\t%s\t%u\t%s %s:%u\n", - UNALIGNED_INT_ASM_OP, line, ASM_COMMENT_START, - filename, line); - ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0xffff); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, TEXT_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - if (this_file_entry_num != prev_file_entry_num) - generate_srcinfo_entry (last_line_entry_num, this_file_entry_num); - prev_file_entry_num = this_file_entry_num; - } -} - -/* Generate an entry in the .debug_macinfo section. */ - -static void -generate_macinfo_entry (type_and_offset, string) - register char *type_and_offset; - register char *string; -{ - if (! use_gnu_debug_info_extensions) - return; - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION); - fprintf (asm_out_file, "\t%s\t%s\n", UNALIGNED_INT_ASM_OP, type_and_offset); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, string); - ASM_OUTPUT_POP_SECTION (asm_out_file); -} - -void -dwarfout_start_new_source_file (filename) - register char *filename; -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*3]; - - sprintf (label, SFNAMES_ENTRY_LABEL_FMT, lookup_filename (filename)); - sprintf (type_and_offset, "0x%08x+%s-%s", - ((unsigned) MACINFO_start << 24), - /* Hack: skip leading '*' . */ - (*label == '*') + label, - (*SFNAMES_BEGIN_LABEL == '*') + SFNAMES_BEGIN_LABEL); - generate_macinfo_entry (type_and_offset, ""); -} - -void -dwarfout_resume_previous_source_file (lineno) - register unsigned lineno; -{ - char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2]; - - sprintf (type_and_offset, "0x%08x+%u", - ((unsigned) MACINFO_resume << 24), lineno); - generate_macinfo_entry (type_and_offset, ""); -} - -/* Called from check_newline in c-parse.y. The `buffer' parameter - contains the tail part of the directive line, i.e. the part which - is past the initial whitespace, #, whitespace, directive-name, - whitespace part. */ - -void -dwarfout_define (lineno, buffer) - register unsigned lineno; - register char *buffer; -{ - static int initialized = 0; - char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2]; - - if (!initialized) - { - dwarfout_start_new_source_file (primary_filename); - initialized = 1; - } - sprintf (type_and_offset, "0x%08x+%u", - ((unsigned) MACINFO_define << 24), lineno); - generate_macinfo_entry (type_and_offset, buffer); -} - -/* Called from check_newline in c-parse.y. The `buffer' parameter - contains the tail part of the directive line, i.e. the part which - is past the initial whitespace, #, whitespace, directive-name, - whitespace part. */ - -void -dwarfout_undef (lineno, buffer) - register unsigned lineno; - register char *buffer; -{ - char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2]; - - sprintf (type_and_offset, "0x%08x+%u", - ((unsigned) MACINFO_undef << 24), lineno); - generate_macinfo_entry (type_and_offset, buffer); -} - -/* Set up for Dwarf output at the start of compilation. */ - -void -dwarfout_init (asm_out_file, main_input_filename) - register FILE *asm_out_file; - register char *main_input_filename; -{ - /* Remember the name of the primary input file. */ - - primary_filename = main_input_filename; - - /* Allocate the initial hunk of the pending_sibling_stack. */ - - pending_sibling_stack - = (unsigned *) - xmalloc (PENDING_SIBLINGS_INCREMENT * sizeof (unsigned)); - pending_siblings_allocated = PENDING_SIBLINGS_INCREMENT; - pending_siblings = 1; - - /* Allocate the initial hunk of the filename_table. */ - - filename_table - = (filename_entry *) - xmalloc (FT_ENTRIES_INCREMENT * sizeof (filename_entry)); - ft_entries_allocated = FT_ENTRIES_INCREMENT; - ft_entries = 0; - - /* Allocate the initial hunk of the pending_types_list. */ - - pending_types_list - = (tree *) xmalloc (PENDING_TYPES_INCREMENT * sizeof (tree)); - pending_types_allocated = PENDING_TYPES_INCREMENT; - pending_types = 0; - - /* Create an artificial RECORD_TYPE node which we can use in our hack - to get the DIEs representing types of formal parameters to come out - only *after* the DIEs for the formal parameters themselves. */ - - fake_containing_scope = make_node (RECORD_TYPE); - - /* Output a starting label for the .text section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, TEXT_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, TEXT_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - /* Output a starting label for the .data section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, DATA_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - -#if 0 /* GNU C doesn't currently use .data1. */ - /* Output a starting label for the .data1 section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA1_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, DATA1_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); -#endif - - /* Output a starting label for the .rodata section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, RODATA_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - -#if 0 /* GNU C doesn't currently use .rodata1. */ - /* Output a starting label for the .rodata1 section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA1_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, RODATA1_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); -#endif - - /* Output a starting label for the .bss section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, BSS_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, BSS_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - if (debug_info_level >= DINFO_LEVEL_NORMAL) - { - if (use_gnu_debug_info_extensions) - { - /* Output a starting label and an initial (compilation directory) - entry for the .debug_sfnames section. The starting label will be - referenced by the initial entry in the .debug_srcinfo section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, SFNAMES_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, SFNAMES_BEGIN_LABEL); - { - register char *pwd; - register unsigned len; - register char *dirname; - - pwd = getpwd (); - if (!pwd) - pfatal_with_name ("getpwd"); - len = strlen (pwd); - dirname = (char *) xmalloc (len + 2); - - strcpy (dirname, pwd); - strcpy (dirname + len, "/"); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, dirname); - free (dirname); - } - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - if (debug_info_level >= DINFO_LEVEL_VERBOSE - && use_gnu_debug_info_extensions) - { - /* Output a starting label for the .debug_macinfo section. This - label will be referenced by the AT_mac_info attribute in the - TAG_compile_unit DIE. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, MACINFO_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - /* Generate the initial entry for the .line section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, LINE_BEGIN_LABEL); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, LINE_END_LABEL, LINE_BEGIN_LABEL); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - if (use_gnu_debug_info_extensions) - { - /* Generate the initial entry for the .debug_srcinfo section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, SRCINFO_BEGIN_LABEL); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, LINE_BEGIN_LABEL); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, SFNAMES_BEGIN_LABEL); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_END_LABEL); -#ifdef DWARF_TIMESTAMPS - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, time (NULL)); -#else - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, -1); -#endif - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - /* Generate the initial entry for the .debug_pubnames section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, DEBUG_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - /* Generate the initial entry for the .debug_aranges section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION); - ASM_OUTPUT_DWARF_ADDR (asm_out_file, DEBUG_BEGIN_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - /* Setup first DIE number == 1. */ - NEXT_DIE_NUM = next_unused_dienum++; - - /* Generate the initial DIE for the .debug section. Note that the - (string) value given in the AT_name attribute of the TAG_compile_unit - DIE will (typically) be a relative pathname and that this pathname - should be taken as being relative to the directory from which the - compiler was invoked when the given (base) source file was compiled. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, DEBUG_BEGIN_LABEL); - output_die (output_compile_unit_die, main_input_filename); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - fputc ('\n', asm_out_file); -} - -/* Output stuff that dwarf requires at the end of every file. */ - -void -dwarfout_finish () -{ - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION); - - /* Mark the end of the chain of siblings which represent all file-scope - declarations in this compilation unit. */ - - /* The (null) DIE which represents the terminator for the (sibling linked) - list of file-scope items is *special*. Normally, we would just call - end_sibling_chain at this point in order to output a word with the - value `4' and that word would act as the terminator for the list of - DIEs describing file-scope items. Unfortunately, if we were to simply - do that, the label that would follow this DIE in the .debug section - (i.e. `..D2') would *not* be properly aligned (as it must be on some - machines) to a 4 byte boundary. - - In order to force the label `..D2' to get aligned to a 4 byte boundary, - the trick used is to insert extra (otherwise useless) padding bytes - into the (null) DIE that we know must precede the ..D2 label in the - .debug section. The amount of padding required can be anywhere between - 0 and 3 bytes. The length word at the start of this DIE (i.e. the one - with the padding) would normally contain the value 4, but now it will - also have to include the padding bytes, so it will instead have some - value in the range 4..7. - - Fortunately, the rules of Dwarf say that any DIE whose length word - contains *any* value less than 8 should be treated as a null DIE, so - this trick works out nicely. Clever, eh? Don't give me any credit - (or blame). I didn't think of this scheme. I just conformed to it. - */ - - output_die (output_padded_null_die, (void *) 0); - dienum_pop (); - - sprintf (label, DIE_BEGIN_LABEL_FMT, NEXT_DIE_NUM); - ASM_OUTPUT_LABEL (asm_out_file, label); /* should be ..D2 */ - ASM_OUTPUT_POP_SECTION (asm_out_file); - - /* Output a terminator label for the .text section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, TEXT_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, TEXT_END_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - /* Output a terminator label for the .data section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, DATA_END_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - -#if 0 /* GNU C doesn't currently use .data1. */ - /* Output a terminator label for the .data1 section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA1_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, DATA1_END_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); -#endif - - /* Output a terminator label for the .rodata section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, RODATA_END_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - -#if 0 /* GNU C doesn't currently use .rodata1. */ - /* Output a terminator label for the .rodata1 section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA1_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, RODATA1_END_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); -#endif - - /* Output a terminator label for the .bss section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, BSS_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, BSS_END_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - if (debug_info_level >= DINFO_LEVEL_NORMAL) - { - /* Output a terminating entry for the .line section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION); - ASM_OUTPUT_LABEL (asm_out_file, LINE_LAST_ENTRY_LABEL); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); - ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0xffff); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, TEXT_END_LABEL, TEXT_BEGIN_LABEL); - ASM_OUTPUT_LABEL (asm_out_file, LINE_END_LABEL); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - if (use_gnu_debug_info_extensions) - { - /* Output a terminating entry for the .debug_srcinfo section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, - LINE_LAST_ENTRY_LABEL, LINE_BEGIN_LABEL); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, -1); - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - if (debug_info_level >= DINFO_LEVEL_VERBOSE) - { - /* Output terminating entries for the .debug_macinfo section. */ - - dwarfout_resume_previous_source_file (0); - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - /* Generate the terminating entry for the .debug_pubnames section. */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); - ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); - ASM_OUTPUT_POP_SECTION (asm_out_file); - - /* Generate the terminating entries for the .debug_aranges section. - - Note that we want to do this only *after* we have output the end - labels (for the various program sections) which we are going to - refer to here. This allows us to work around a bug in the m68k - svr4 assembler. That assembler gives bogus assembly-time errors - if (within any given section) you try to take the difference of - two relocatable symbols, both of which are located within some - other section, and if one (or both?) of the symbols involved is - being forward-referenced. By generating the .debug_aranges - entries at this late point in the assembly output, we skirt the - issue simply by avoiding forward-references. - */ - - fputc ('\n', asm_out_file); - ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION); - - ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, TEXT_END_LABEL, TEXT_BEGIN_LABEL); - - ASM_OUTPUT_DWARF_ADDR (asm_out_file, DATA_BEGIN_LABEL); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, DATA_END_LABEL, DATA_BEGIN_LABEL); - -#if 0 /* GNU C doesn't currently use .data1. */ - ASM_OUTPUT_DWARF_ADDR (asm_out_file, DATA1_BEGIN_LABEL); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, DATA1_END_LABEL, - DATA1_BEGIN_LABEL); -#endif - - ASM_OUTPUT_DWARF_ADDR (asm_out_file, RODATA_BEGIN_LABEL); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, RODATA_END_LABEL, - RODATA_BEGIN_LABEL); - -#if 0 /* GNU C doesn't currently use .rodata1. */ - ASM_OUTPUT_DWARF_ADDR (asm_out_file, RODATA1_BEGIN_LABEL); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, RODATA1_END_LABEL, - RODATA1_BEGIN_LABEL); -#endif - - ASM_OUTPUT_DWARF_ADDR (asm_out_file, BSS_BEGIN_LABEL); - ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, BSS_END_LABEL, BSS_BEGIN_LABEL); - - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); - ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); - - ASM_OUTPUT_POP_SECTION (asm_out_file); - } - - /* There should not be any pending types left at the end. We need - this now because it may not have been checked on the last call to - dwarfout_file_scope_decl. */ - if (pending_types != 0) - abort (); -} - -#endif /* DWARF_DEBUGGING_INFO */ diff --git a/gcc/dwarfout.h b/gcc/dwarfout.h deleted file mode 100755 index 29c8dd3..0000000 --- a/gcc/dwarfout.h +++ /dev/null @@ -1,42 +0,0 @@ -/* dwarfout.h - Various declarations for functions found in dwarfout.c - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -extern void dwarfout_init PROTO ((FILE *asm_out_file, - char *main_input_filename)); -extern void dwarfout_finish PROTO ((void)); - -extern void dwarfout_define PROTO ((unsigned, char *)); -extern void dwarfout_undef PROTO ((unsigned, char *)); -extern void dwarfout_file_scope_decl PROTO ((tree , int)); -extern void dwarfout_start_new_source_file PROTO ((char *)); -extern void dwarfout_resume_previous_source_file PROTO((unsigned)); - -extern void dwarfout_begin_function PROTO ((void)); -extern void dwarfout_end_function PROTO ((void)); -extern void dwarfout_begin_epilogue PROTO ((void)); -extern void dwarfout_end_epilogue PROTO ((void)); -extern void dwarfout_begin_block PROTO ((unsigned)); -extern void dwarfout_end_block PROTO ((unsigned)); - -#ifdef RTX_CODE -extern void dwarfout_label PROTO ((rtx)); -#endif -extern void dwarfout_line PROTO ((char *, unsigned)); - diff --git a/gcc/final.c b/gcc/final.c index 7e3e8e5..2f54102 100755 --- a/gcc/final.c +++ b/gcc/final.c @@ -73,28 +73,10 @@ Boston, MA 02111-1307, USA. */ extern struct obstack *rtl_obstack; /* END CYGNUS LOCAL */ -/* Get N_SLINE and N_SOL from stab.h if we can expect the file to exist. */ - - -#ifdef DWARF_DEBUGGING_INFO -#include "dwarfout.h" -#endif - #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) #include "dwarf2out.h" #endif - -/* .stabd code for line number. */ -#ifndef N_SLINE -#define N_SLINE 0x44 -#endif - -/* .stabs code for included file name. */ -#ifndef N_SOL -#define N_SOL 0x84 -#endif - #ifndef INT_TYPE_SIZE #define INT_TYPE_SIZE BITS_PER_WORD #endif @@ -1392,10 +1374,6 @@ final_end_function (first, file, optimize) app_on = 0; } -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - dwarfout_end_function (); -#endif #ifdef FUNCTION_EPILOGUE /* Finally, output the function epilogue: @@ -1403,10 +1381,6 @@ final_end_function (first, file, optimize) FUNCTION_EPILOGUE (file, get_frame_size ()); #endif -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - dwarfout_end_epilogue (); -#endif #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) if (dwarf2out_do_frame ()) @@ -1609,12 +1583,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) break; if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG) { -#ifdef DWARF_DEBUGGING_INFO - /* This outputs a marker where the function body starts, so it - must be after the prologue. */ - if (write_symbols == DWARF_DEBUG) - dwarfout_begin_function (); -#endif break; } if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED) @@ -1653,10 +1621,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) /* Output debugging info about the symbol-block beginning. */ -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - dwarfout_begin_block (next_block_index); -#endif #ifdef DWARF2_DEBUGGING_INFO if (write_symbols == DWARF2_DEBUG) dwarf2out_begin_block (next_block_index); @@ -1678,10 +1642,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) abort (); /* CYGNUS LOCAL LRS */ -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - dwarfout_end_block (pending_blocks[block_depth].number); -#endif #ifdef DWARF2_DEBUGGING_INFO if (write_symbols == DWARF2_DEBUG) dwarf2out_end_block (pending_blocks[block_depth].number); @@ -1692,10 +1652,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) && (debug_info_level == DINFO_LEVEL_NORMAL || debug_info_level == DINFO_LEVEL_VERBOSE)) { -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - dwarfout_label (insn); -#endif #ifdef DWARF2_DEBUGGING_INFO if (write_symbols == DWARF2_DEBUG) dwarf2out_label (insn); @@ -1808,10 +1764,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) FINAL_PRESCAN_INSN (insn, NULL_PTR, 0); #endif -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG && LABEL_NAME (insn)) - dwarfout_label (insn); -#endif #ifdef DWARF2_DEBUGGING_INFO if (write_symbols == DWARF2_DEBUG && LABEL_NAME (insn)) dwarf2out_label (insn); @@ -2416,10 +2368,6 @@ output_source_line (file, insn) -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - dwarfout_line (filename, NOTE_LINE_NUMBER (insn)); -#endif #ifdef DWARF2_DEBUGGING_INFO if (write_symbols == DWARF2_DEBUG) diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h deleted file mode 100755 index d2605fe..0000000 --- a/gcc/gcov-io.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Machine-independent I/O routines for gcov. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Bob Manson <manson@cygnus.com>. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef GCOV_IO_H -#define GCOV_IO_H -#include <stdio.h> -#include <sys/types.h> - -static int __fetch_long PROTO ((long *, char *, size_t)); -static int __store_long PROTO ((long, char *, size_t)); -static int __read_long PROTO ((long *, FILE *, size_t)); -static int __write_long PROTO ((long, FILE *, size_t)); - -/* These routines only work for signed values. */ - -/* Store a portable representation of VALUE in DEST using BYTES*8-1 bits. - Return a non-zero value if VALUE requires more than BYTES*8-1 bits - to store. */ - -static int -__store_long (value, dest, bytes) - long value; - char *dest; - size_t bytes; -{ - int upper_bit = (value < 0 ? 128 : 0); - size_t i; - - if (value < 0) - { - long oldvalue = value; - value = -value; - if (oldvalue != -value) - return 1; - } - - for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) { - dest[i] = value & (i == (bytes - 1) ? 127 : 255); - value = value / 256; - } - - if (value && value != -1) - return 1; - - for(; i < bytes ; i++) - dest[i] = 0; - dest[bytes - 1] |= upper_bit; - return 0; -} - -/* Retrieve a quantity containing BYTES*8-1 bits from SOURCE and store - the result in DEST. Returns a non-zero value if the value in SOURCE - will not fit in DEST. */ - -static int -__fetch_long (dest, source, bytes) - long *dest; - char *source; - size_t bytes; -{ - long value = 0; - int i; - - for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--) - if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 )) - return 1; - - for (; i >= 0; i--) - value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255)); - - if ((source[bytes - 1] & 128) && (value > 0)) - value = - value; - - *dest = value; - return 0; -} - -/* Write a BYTES*8-bit quantity to FILE, portably. Returns a non-zero - value if the write fails, or if VALUE can't be stored in BYTES*8 - bits. - - Note that VALUE may not actually be large enough to hold BYTES*8 - bits, but BYTES characters will be written anyway. - - BYTES may be a maximum of 10. */ - -static int -__write_long (value, file, bytes) - long value; - FILE *file; - size_t bytes; -{ - char c[10]; - - if (bytes > 10 || __store_long (value, c, bytes)) - return 1; - else - return fwrite(c, 1, bytes, file) != bytes; -} - -/* Read a quantity containing BYTES bytes from FILE, portably. Return - a non-zero value if the read fails or if the value will not fit - in DEST. - - Note that DEST may not be large enough to hold all of the requested - data, but the function will read BYTES characters anyway. - - BYTES may be a maximum of 10. */ - -static int -__read_long (dest, file, bytes) - long *dest; - FILE *file; - size_t bytes; -{ - char c[10]; - - if (bytes > 10 || fread(c, 1, bytes, file) != bytes) - return 1; - else - return __fetch_long (dest, c, bytes); -} - -#endif diff --git a/gcc/gstab.h b/gcc/gstab.h deleted file mode 100755 index 80bd594..0000000 --- a/gcc/gstab.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __GNU_STAB__ - -/* Indicate the GNU stab.h is in use. */ - -#define __GNU_STAB__ - -#define __define_stab(NAME, CODE, STRING) NAME=CODE, - -enum __stab_debug_code -{ -#include "stab.def" -LAST_UNUSED_STAB_CODE -}; - -#undef __define_stab - -#endif /* __GNU_STAB_ */ diff --git a/gcc/gsyms.h b/gcc/gsyms.h deleted file mode 100755 index 03bde93..0000000 --- a/gcc/gsyms.h +++ /dev/null @@ -1,86 +0,0 @@ -/* For cross compilation, use the portable definitions from the COFF - documentation. */ - -#define __GNU_SYMS__ - -enum sdb_storage_class -{ - C_EFCN = -1, - C_NULL = 0, - C_AUTO = 1, - C_EXT = 2, - C_STAT = 3, - C_REG = 4, - C_EXTDEF = 5, - C_LABEL = 6, - C_ULABEL = 7, - C_MOS = 8, - C_ARG = 9, - C_STRTAG = 10, - C_MOU = 11, - C_UNTAG = 12, - C_TPDEF = 13, - C_USTATIC = 14, - C_ENTAG = 15, - C_MOE = 16, - C_REGPARM = 17, - C_FIELD = 18, - - C_BLOCK = 100, - C_FCN = 101, - C_EOS = 102, - C_FILE = 103, - C_LINE = 104, - C_ALIAS = 105, - C_HIDDEN = 106 -}; - -enum sdb_type -{ - T_NULL = 0, - T_ARG = 1, - T_VOID = 1, - T_CHAR = 2, - T_SHORT = 3, - T_INT = 4, - T_LONG = 5, - T_FLOAT = 6, - T_DOUBLE = 7, - T_STRUCT = 8, - T_UNION = 9, - T_ENUM = 10, - T_MOE = 11, - T_UCHAR = 12, - T_USHORT = 13, - T_UINT = 14, - T_ULONG = 15 -#ifdef EXTENDED_SDB_BASIC_TYPES - , T_LNGDBL = 16 -#endif -}; - -enum sdb_type_class -{ - DT_NON = 0, - DT_PTR = 1, - DT_FCN = 2, - DT_ARY = 3 -}; - -enum sdb_masks -{ -#ifdef EXTENDED_SDB_BASIC_TYPES - N_BTMASK = 0x1f, - N_TMASK = 0x60, - N_TMASK1 = 0x300, - N_TMASK2 = 0x360, - N_BTSHFT = 5, -#else - N_BTMASK = 017, - N_TMASK = 060, - N_TMASK1 = 0300, - N_TMASK2 = 0360, - N_BTSHFT = 4, -#endif - N_TSHIFT = 2 -}; diff --git a/gcc/gthr-dce.h b/gcc/gthr-dce.h deleted file mode 100755 index 3cba8a0..0000000 --- a/gcc/gthr-dce.h +++ /dev/null @@ -1,150 +0,0 @@ - -/* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __gthr_dce_h -#define __gthr_dce_h - -/* DCE threads interface. - DCE threads are based on POSIX threads draft 4, and many things - have changed since then. */ - -#define __GTHREADS 1 - -#include <pthread.h> - -typedef pthread_key_t __gthread_key_t; -typedef pthread_once_t __gthread_once_t; -typedef pthread_mutex_t __gthread_mutex_t; - -#define __GTHREAD_ONCE_INIT pthread_once_init -/* Howto define __GTHREAD_MUTEX_INIT? */ - -#if SUPPORTS_WEAK && GTHREAD_USE_WEAK - -#pragma weak pthread_once -#pragma weak pthread_once_init -#pragma weak pthread_key_create -#pragma weak pthread_key_delete -#pragma weak pthread_getspecific -#pragma weak pthread_setspecific -#pragma weak pthread_create - -#pragma weak pthread_mutex_lock -#pragma weak pthread_mutex_trylock -#pragma weak pthread_mutex_unlock - -static void *__gthread_active_ptr = &pthread_create; - -static inline int -__gthread_active_p () -{ - return __gthread_active_ptr != 0; -} - -#else /* not SUPPORTS_WEAK */ - -static inline int -__gthread_active_p () -{ - return 1; -} - -#endif /* SUPPORTS_WEAK */ - -static inline int -__gthread_once (__gthread_once_t *once, void (*func) ()) -{ - if (__gthread_active_p ()) - return pthread_once (once, func); - else - return -1; -} - -static inline int -__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) -{ - return pthread_keycreate (key, dtor); -} - -static inline int -__gthread_key_dtor (__gthread_key_t key, void *ptr) -{ - /* Nothing needed. */ - return 0; -} - -static inline int -__gthread_key_delete (__gthread_key_t key) -{ - return pthread_key_delete (key); -} - -static inline void * -__gthread_getspecific (__gthread_key_t key) -{ - void *ptr; - if (pthread_getspecific (key, &ptr) == 0) - return ptr; - else - return 0; -} - -static inline int -__gthread_setspecific (__gthread_key_t key, const void *ptr) -{ - return pthread_setspecific (key, (void *) ptr); -} - -static inline int -__gthread_mutex_lock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return pthread_mutex_lock (mutex); - else - return 0; -} - -static inline int -__gthread_mutex_trylock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return pthread_mutex_trylock (mutex); - else - return 0; -} - -static inline int -__gthread_mutex_unlock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return pthread_mutex_unlock (mutex); - else - return 0; -} - -#endif /* not __gthr_dce_h */ diff --git a/gcc/gthr-posix.h b/gcc/gthr-posix.h deleted file mode 100755 index 19231c3..0000000 --- a/gcc/gthr-posix.h +++ /dev/null @@ -1,147 +0,0 @@ -/* Threads compatibily routines for libgcc2. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __gthr_posix_h -#define __gthr_posix_h - -/* POSIX threads specific definitions. - Easy, since the interface is just one-to-one mapping. */ - -#define __GTHREADS 1 - -#include <pthread.h> - -typedef pthread_key_t __gthread_key_t; -typedef pthread_once_t __gthread_once_t; -typedef pthread_mutex_t __gthread_mutex_t; - -#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER -#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT - -#if SUPPORTS_WEAK && GTHREAD_USE_WEAK - -#pragma weak pthread_once -#pragma weak pthread_key_create -#pragma weak pthread_key_delete -#pragma weak pthread_getspecific -#pragma weak pthread_setspecific -#pragma weak pthread_create - -#pragma weak pthread_mutex_lock -#pragma weak pthread_mutex_trylock -#pragma weak pthread_mutex_unlock - -static void *__gthread_active_ptr = &pthread_create; - -static inline int -__gthread_active_p () -{ - return __gthread_active_ptr != 0; -} - -#else /* not SUPPORTS_WEAK */ - -static inline int -__gthread_active_p () -{ - return 1; -} - -#endif /* SUPPORTS_WEAK */ - -static inline int -__gthread_once (__gthread_once_t *once, void (*func) ()) -{ - if (__gthread_active_p ()) - return pthread_once (once, func); - else - return -1; -} - -static inline int -__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) -{ - return pthread_key_create (key, dtor); -} - -static inline int -__gthread_key_dtor (__gthread_key_t key, void *ptr) -{ - /* Just reset the key value to zero. */ - if (ptr) - return pthread_setspecific (key, 0); - else - return 0; -} - -static inline int -__gthread_key_delete (__gthread_key_t key) -{ - return pthread_key_delete (key); -} - -static inline void * -__gthread_getspecific (__gthread_key_t key) -{ - return pthread_getspecific (key); -} - -static inline int -__gthread_setspecific (__gthread_key_t key, const void *ptr) -{ - return pthread_setspecific (key, ptr); -} - -static inline int -__gthread_mutex_lock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return pthread_mutex_lock (mutex); - else - return 0; -} - -static inline int -__gthread_mutex_trylock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return pthread_mutex_trylock (mutex); - else - return 0; -} - -static inline int -__gthread_mutex_unlock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return pthread_mutex_unlock (mutex); - else - return 0; -} - -#endif /* not __gthr_posix_h */ diff --git a/gcc/gthr-qt.h b/gcc/gthr-qt.h deleted file mode 100755 index 0fdcfd3..0000000 --- a/gcc/gthr-qt.h +++ /dev/null @@ -1,152 +0,0 @@ -/* CYGNUS LOCAL java quickthreads (entire file) */ - -/* Threads compatibility routines for libgcc2. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __gthr_qt_h -#define __gthr_qt_h - -/* Cooperative threads package based on QuickThreads. */ - -#define __GTHREADS 1 - -#include <coop.h> - -typedef int __gthread_key_t; -typedef void *__gthread_once_t; -typedef coop_m __gthread_mutex_t; - -#define __GTHREAD_MUTEX_INIT_FUNCTION coop_mutex_init -#define __GTHREAD_ONCE_INIT 0 - -#if SUPPORTS_WEAK && GTHREAD_USE_WEAK - -#pragma weak coop_once -#pragma weak coop_key_create -#pragma weak coop_key_destroy -#pragma weak coop_getspecific -#pragma weak coop_setspecific -#pragma weak coop_create - -#pragma weak coop_mutex_init -#pragma weak coop_mutex_lock -#pragma weak coop_mutex_trylock -#pragma weak coop_mutex_unlock - -static void *__gthread_active_ptr = &coop_create; - -static inline int -__gthread_active_p () -{ - return __gthread_active_ptr != 0; -} - -#else /* not SUPPORTS_WEAK */ - -static inline int -__gthread_active_p () -{ - return 1; -} - -#endif /* SUPPORTS_WEAK */ - -static inline int -__gthread_once (__gthread_once_t *once, void (*func) ()) -{ - if (__gthread_active_p ()) - { - coop_once (once, func); - return 0; - } - else - return -1; -} - -static inline int -__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) -{ - *key = coop_key_create (dtor); - return 0; -} - -static inline int -__gthread_key_dtor (__gthread_key_t key, void *ptr) -{ - /* Just reset the key value to zero. */ - if (ptr) - coop_setspecific (0, key, 0); - return 0; -} - -static inline int -__gthread_key_delete (__gthread_key_t key) -{ - coop_key_destroy (key); - return 0; -} - -static inline void * -__gthread_getspecific (__gthread_key_t key) -{ - return coop_getspecific (key); -} - -static inline int -__gthread_setspecific (__gthread_key_t key, const void *ptr) -{ - coop_setspecific (0, key, ptr); - return 0; -} - -static inline int -__gthread_mutex_lock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - coop_mutex_lock (mutex); - return 0; -} - -static inline int -__gthread_mutex_trylock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return coop_mutex_trylock (mutex); - else - return 0; -} - -static inline int -__gthread_mutex_unlock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - coop_mutex_unlock (mutex); - return 0; -} - -#endif /* __gthr_qt_h */ diff --git a/gcc/gthr-single.h b/gcc/gthr-single.h deleted file mode 100755 index f8dfbff..0000000 --- a/gcc/gthr-single.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Threads compatibily routines for libgcc2. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __gthr_single_h -#define __gthr_single_h - -/* Just provide compatibility for mutex handling. */ - -typedef int __gthread_mutex_t; - -#define __GTHREAD_MUTEX_INIT 0 - -static inline int -__gthread_active_p () -{ - return 0; -} - -static inline int -__gthread_mutex_lock (__gthread_mutex_t *mutex __attribute__ ((__unused__))) -{ - return 0; -} - -static inline int -__gthread_mutex_trylock (__gthread_mutex_t *mutex __attribute__ ((__unused__))) -{ - return 0; -} - -static inline int -__gthread_mutex_unlock (__gthread_mutex_t *mutex __attribute__ ((__unused__))) -{ - return 0; -} - -#endif /* not __gthr_single_h */ diff --git a/gcc/gthr-solaris.h b/gcc/gthr-solaris.h deleted file mode 100755 index a6f669c..0000000 --- a/gcc/gthr-solaris.h +++ /dev/null @@ -1,177 +0,0 @@ -/* Threads compatibily routines for libgcc2. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __gthr_solaris_h -#define __gthr_solaris_h - -/* Solaris threads as found in Solaris 2.[456]. - Actually these are Unix International (UI) threads, but I don't - know if anyone else implements these. */ - -#define __GTHREADS 1 - -#include <thread.h> -#include <errno.h> - -typedef thread_key_t __gthread_key_t; -typedef struct -{ - mutex_t mutex; - int once; -} __gthread_once_t; -typedef mutex_t __gthread_mutex_t; - -#define __GTHREAD_ONCE_INIT { DEFAULTMUTEX, 0 } -#define __GTHREAD_MUTEX_INIT DEFAULTMUTEX - -#if SUPPORTS_WEAK && GTHREAD_USE_WEAK - -#pragma weak thr_keycreate -#pragma weak thr_getspecific -#pragma weak thr_setspecific -#pragma weak thr_create - -#pragma weak mutex_lock -#pragma weak mutex_trylock -#pragma weak mutex_unlock - -/* This will not actually work in Solaris 2.5, since libc contains - dummy symbols of all thr_* routines. */ - -static void *__gthread_active_ptr = &thr_create; - -static inline int -__gthread_active_p () -{ - return __gthread_active_ptr != 0; -} - -#else /* not SUPPORTS_WEAK */ - -static inline int -__gthread_active_p () -{ - return 1; -} - -#endif /* SUPPORTS_WEAK */ - -static inline int -__gthread_once (__gthread_once_t *once, void (*func) ()) -{ - if (! __gthread_active_p ()) - return -1; - - if (once == 0 || func == 0) - return EINVAL; - - if (once->once == 0) - { - int status = mutex_lock (&once->mutex); - if (status != 0) - return status; - if (once->once == 0) - { - (*func) (); - once->once ++; - } - mutex_unlock (&once->mutex); - } - return 0; -} - -static inline int -__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) -{ - /* Solaris 2.5 contains thr_* routines no-op in libc, so test if we actually - got a reasonable key value, and if not, fail. */ - *key = -1; - if (thr_keycreate (key, dtor) != 0 || *key == -1) - return -1; - else - return 0; -} - -static inline int -__gthread_key_dtor (__gthread_key_t key, void *ptr) -{ - /* Nothing needed. */ - return 0; -} - -static inline int -__gthread_key_delete (__gthread_key_t key) -{ - /* Not possible. */ - return -1; -} - -static inline void * -__gthread_getspecific (__gthread_key_t key) -{ - void *ptr; - if (thr_getspecific (key, &ptr) == 0) - return ptr; - else - return 0; -} - -static inline int -__gthread_setspecific (__gthread_key_t key, const void *ptr) -{ - return thr_setspecific (key, (void *) ptr); -} - -static inline int -__gthread_mutex_lock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return mutex_lock (mutex); - else - return 0; -} - -static inline int -__gthread_mutex_trylock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return mutex_trylock (mutex); - else - return 0; -} - -static inline int -__gthread_mutex_unlock (__gthread_mutex_t *mutex) -{ - if (__gthread_active_p ()) - return mutex_unlock (mutex); - else - return 0; -} - -#endif /* not __gthr_solaris_h */ diff --git a/gcc/gthr-vxworks.h b/gcc/gthr-vxworks.h deleted file mode 100755 index 6d51ded..0000000 --- a/gcc/gthr-vxworks.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Threads compatibily routines for libgcc2 for VxWorks. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. - Contributed by Mike Stump <mrs@wrs.com>. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __gthr_vxworks_h -#define __gthr_vxworks_h - -/* POSIX threads specific definitions. - Easy, since the interface is just one-to-one mapping. */ - -#define __GTHREADS 1 - -#include <vxWorks.h> -#include <semLib.h> -/* typedef void *SEM_ID; */ - -typedef int __gthread_key_t; -typedef char __gthread_once_t; -typedef SEM_ID __gthread_mutex_t; - -#define __GTHREAD_MUTEX_INIT 0 -#define __GTHREAD_ONCE_INIT 0 - -#ifndef REG_SAVED_REG -static inline int -__gthread_once (__gthread_once_t *once, void (*func) ()) -{ - (*func)(); - return 0; -} - -extern __gthread_key_t eh_context_key; - -/* This is not the right way to do it, but the semantic of pthreads - don't map well enough onto VxWorks. */ - -static void -__ehdtor (void *pTcb) -{ - int tid = (int) pTcb; - void *p = (void*)taskVarGet(tid, &eh_context_key); - if (p != (void*)-1) - { - if (p) - free (p); - taskVarSet(tid, &eh_context_key, 0); - } -} - -/* This only works for the code in libgcc2.c. */ - -static inline int -__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) -{ - *key = 0; - - /* Do this first so that the task variables are visible during the - running of the delete hook. */ - - taskVarInit(); - - /* We don't have a way to track dtor here, so instead, we - register a generic routine that can cleanup any task. */ - - taskDeleteHookAdd (__ehdtor); - - return 0; -} - -#define __gthread_setspecific(key, ptr) \ - (key = (int) ptr, 0) - -static inline int -__gthread_key_dtor (__gthread_key_t key, void *ptr) -{ - /* Just reset the key value to zero. */ - if (ptr) - return __gthread_setspecific (key, 0); - else - return 0; -} - -#define __gthread_key_delete(key) \ - taskVarDelete (taskIdSelf (), &key) - -#define __gthread_getspecific(key) \ - ((key == 0) \ - ? ((taskVarAdd (taskIdSelf (), &key) != OK) \ - ? (__terminate (), (void*)0) \ - : (void*)0) \ - : (void*)key) -#endif - -static inline int -__gthread_mutex_lock (__gthread_mutex_t *mutex) -{ - if (*mutex == 0) - *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE); - return semTake (*mutex, WAIT_FOREVER); -} - -static inline int -__gthread_mutex_trylock (__gthread_mutex_t *mutex) -{ - if (*mutex == 0) - *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE); - return semTake (*mutex, NO_WAIT); -} - -static inline int -__gthread_mutex_unlock (__gthread_mutex_t *mutex) -{ - /* We could return the */ - return semGive (*mutex); -} - -#endif /* not __gthr_vxworks_h */ diff --git a/gcc/gthr.h b/gcc/gthr.h deleted file mode 100755 index 7511e35..0000000 --- a/gcc/gthr.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Threads compatibily routines for libgcc2. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __gthr_h -#define __gthr_h - -/* If this file is compiled with threads support, it must - #define __GTHREADS 1 - to indicate that threads support is present. Also it has define - function - int __gthread_active_p () - that returns 1 if thread system is active, 0 if not. - - The threads interface must define the following types: - __gthread_key_t - __gthread_once_t - __gthread_mutex_t - - The threads interface must define the following macros: - - __GTHREAD_ONCE_INIT - to initialize __gthread_once_t - __GTHREAD_MUTEX_INIT - to initialize __gthread_mutex_t to get a fast - non-recursive mutex. - __GTHREAD_MUTEX_INIT_FUNCTION - some systems can't initalize a mutex without a - function call. On such systems, define this to a - function which looks like this: - void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *) - Don't define __GTHREAD_MUTEX_INIT in this case - - The threads interface must define the following static functions: - - int __gthread_once (__gthread_once_t *once, void (*func) ()) - - int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *)) - int __gthread_key_delete (__gthread_key_t key) - - int __gthread_key_dtor (__gthread_key_t key, void *ptr) - - void *__gthread_getspecific (__gthread_key_t key) - int __gthread_setspecific (__gthread_key_t key, const void *ptr) - - int __gthread_mutex_lock (__gthread_mutex_t *mutex); - int __gthread_mutex_trylock (__gthread_mutex_t *mutex); - int __gthread_mutex_unlock (__gthread_mutex_t *mutex); - - All functions returning int should return zero on success or the error - number. If the operation is not supported, -1 is returned. - - Currently supported threads packages are - POSIX threads with -D_PTHREADS - DCE threads with -D_DCE_THREADS - Solaris/UI threads with -D_SOLARIS_THREADS -*/ - -/* Check first for thread specific defines. */ -#if _PTHREADS -#include "gthr-posix.h" -#elif _DCE_THREADS -#include "gthr-dce.h" -#elif _SOLARIS_THREADS -#include "gthr-solaris.h" - -/* Include GTHREAD_FILE if one is defined. */ -#elif defined(HAVE_GTHR_DEFAULT) -#if SUPPORTS_WEAK -#ifndef GTHREAD_USE_WEAK -#define GTHREAD_USE_WEAK 1 -#endif -#endif -#include "gthr-default.h" - -/* Fallback to single thread definitions. */ -#else -#include "gthr-single.h" -#endif - -#endif /* not __gthr_h */ diff --git a/gcc/just-fixinc b/gcc/just-fixinc deleted file mode 100755 index 3faa909..0000000 --- a/gcc/just-fixinc +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -# $Id: just-fixinc,v 1.42 1998/11/11 05:49:02 law Exp $ -# This script exists for use after installing -# the GCC binaries from a distribution tape/CD-ROM. -# Use it *after* copying the directory of binaries -# to the proper installed location. -# It runs fixincludes (or fixinc.svr4, if appropriate) to correct bugs in -# the system header files. -# This script needs to be customized for each type of installation so that -# others may run it after the installation-sans-fixincludes is completed. - -# The corrected header files go in the GCC installation directory -# so that only GCC sees them. -# This script does not modify the original header files in /usr/include. -# It only modifies copies in the GCC installation directory. - -installed=/opt/gnu/lib/gcc-lib/sparc-sun-solaris2/2.6.0 -cd $installed/include - -rmdir tmpfoo > /dev/null 2>&1 -mkdir tmpfoo -mv va-sparc.h varargs.h stdarg.h stddef.h limits.h float.h proto.h tmpfoo - -$installed/fixinc.svr4 $installed/include /usr/include $installed - -# Make sure fixed native limits.h gets renamed to syslimits.h before gcc's -# limits.h from tmpfoo is moved back. -rm -f syslimits.h -if test -f limits.h ; then - mv limits.h syslimits.h -else - cp $installed/gsyslimits.h syslimits.h -fi -chmod a+r syslimits.h - -mv tmpfoo/* . -rmdir tmpfoo - -# eof diff --git a/gcc/mips-tdump.c b/gcc/mips-tdump.c deleted file mode 100755 index 1f9c045..0000000 --- a/gcc/mips-tdump.c +++ /dev/null @@ -1,1603 +0,0 @@ -/* Read and manage MIPS symbol tables from object modules. - Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. - Contributed by hartzell@boulder.colorado.edu, - Rewritten by meissner@osf.org. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" - -#ifdef index -#undef index -#undef rindex -#endif -#ifndef CROSS_COMPILE -#include <a.out.h> -#else -#include "mips/a.out.h" -#endif /* CROSS_COMPILE */ - -#ifndef MIPS_IS_STAB -/* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for - and mips-tdump.c to print them out. This is used on the Alpha, - which does not include mips.h. - - These must match the corresponding definitions in gdb/mipsread.c. - Unfortunately, gcc and gdb do not currently share any directories. */ - -#define CODE_MASK 0x8F300 -#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK) -#define MIPS_MARK_STAB(code) ((code)+CODE_MASK) -#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK) -#endif - -#define __proto(x) PARAMS(x) -typedef PTR PTR_T; -typedef const PTR_T CPTR_T; - -#define uchar unsigned char -#define ushort unsigned short -#define uint unsigned int -#define ulong unsigned long - - -static void -fatal(s) - const char *s; -{ - fprintf(stderr, "%s\n", s); - exit(FATAL_EXIT_CODE); -} - -/* Same as `malloc' but report error if no memory available. */ -/* Do this before size_t is fiddled with so it matches the prototype - in libiberty.h . */ -PTR -xmalloc (size) - size_t size; -{ - register PTR value = (PTR) malloc (size); - if (value == 0) - fatal ("Virtual memory exhausted."); - return value; -} - -/* Due to size_t being defined in sys/types.h and different - in stddef.h, we have to do this by hand..... Note, these - types are correct for MIPS based systems, and may not be - correct for other systems. */ - -#define size_t uint -#define ptrdiff_t int - - -/* Redefinition of storage classes as an enumeration for better - debugging. */ - -#ifndef stStaParam -#define stStaParam 16 /* Fortran static parameters */ -#endif - -#ifndef btVoid -#define btVoid 26 /* void basic type */ -#endif - -typedef enum sc { - sc_Nil = scNil, /* no storage class */ - sc_Text = scText, /* text symbol */ - sc_Data = scData, /* initialized data symbol */ - sc_Bss = scBss, /* un-initialized data symbol */ - sc_Register = scRegister, /* value of symbol is register number */ - sc_Abs = scAbs, /* value of symbol is absolute */ - sc_Undefined = scUndefined, /* who knows? */ - sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */ - sc_Bits = scBits, /* this is a bit field */ - sc_CdbSystem = scCdbSystem, /* var's value is IN CDB's address space */ - sc_RegImage = scRegImage, /* register value saved on stack */ - sc_Info = scInfo, /* symbol contains debugger information */ - sc_UserStruct = scUserStruct, /* addr in struct user for current process */ - sc_SData = scSData, /* load time only small data */ - sc_SBss = scSBss, /* load time only small common */ - sc_RData = scRData, /* load time only read only data */ - sc_Var = scVar, /* Var parameter (fortran,pascal) */ - sc_Common = scCommon, /* common variable */ - sc_SCommon = scSCommon, /* small common */ - sc_VarRegister = scVarRegister, /* Var parameter in a register */ - sc_Variant = scVariant, /* Variant record */ - sc_SUndefined = scSUndefined, /* small undefined(external) data */ - sc_Init = scInit, /* .init section symbol */ - sc_Max = scMax /* Max storage class+1 */ -} sc_t; - -/* Redefinition of symbol type. */ - -typedef enum st { - st_Nil = stNil, /* Nuthin' special */ - st_Global = stGlobal, /* external symbol */ - st_Static = stStatic, /* static */ - st_Param = stParam, /* procedure argument */ - st_Local = stLocal, /* local variable */ - st_Label = stLabel, /* label */ - st_Proc = stProc, /* " " Procedure */ - st_Block = stBlock, /* beginning of block */ - st_End = stEnd, /* end (of anything) */ - st_Member = stMember, /* member (of anything - struct/union/enum */ - st_Typedef = stTypedef, /* type definition */ - st_File = stFile, /* file name */ - st_RegReloc = stRegReloc, /* register relocation */ - st_Forward = stForward, /* forwarding address */ - st_StaticProc = stStaticProc, /* load time only static procs */ - st_StaParam = stStaParam, /* Fortran static parameters */ - st_Constant = stConstant, /* const */ -#ifdef stStruct - st_Struct = stStruct, /* struct */ - st_Union = stUnion, /* union */ - st_Enum = stEnum, /* enum */ -#endif - st_Str = stStr, /* string */ - st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */ - st_Expr = stExpr, /* 2+2 vs. 4 */ - st_Type = stType, /* post-coercion SER */ - st_Max = stMax /* max type+1 */ -} st_t; - -/* Redefinition of type qualifiers. */ - -typedef enum tq { - tq_Nil = tqNil, /* bt is what you see */ - tq_Ptr = tqPtr, /* pointer */ - tq_Proc = tqProc, /* procedure */ - tq_Array = tqArray, /* duh */ - tq_Far = tqFar, /* longer addressing - 8086/8 land */ - tq_Vol = tqVol, /* volatile */ - tq_Max = tqMax /* Max type qualifier+1 */ -} tq_t; - -/* Redefinition of basic types. */ - -typedef enum bt { - bt_Nil = btNil, /* undefined */ - bt_Adr = btAdr, /* address - integer same size as pointer */ - bt_Char = btChar, /* character */ - bt_UChar = btUChar, /* unsigned character */ - bt_Short = btShort, /* short */ - bt_UShort = btUShort, /* unsigned short */ - bt_Int = btInt, /* int */ - bt_UInt = btUInt, /* unsigned int */ - bt_Long = btLong, /* long */ - bt_ULong = btULong, /* unsigned long */ - bt_Float = btFloat, /* float (real) */ - bt_Double = btDouble, /* Double (real) */ - bt_Struct = btStruct, /* Structure (Record) */ - bt_Union = btUnion, /* Union (variant) */ - bt_Enum = btEnum, /* Enumerated */ - bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */ - bt_Range = btRange, /* subrange of int */ - bt_Set = btSet, /* pascal sets */ - bt_Complex = btComplex, /* fortran complex */ - bt_DComplex = btDComplex, /* fortran double complex */ - bt_Indirect = btIndirect, /* forward or unnamed typedef */ - bt_FixedDec = btFixedDec, /* Fixed Decimal */ - bt_FloatDec = btFloatDec, /* Float Decimal */ - bt_String = btString, /* Varying Length Character String */ - bt_Bit = btBit, /* Aligned Bit String */ - bt_Picture = btPicture, /* Picture */ - bt_Void = btVoid, /* void */ - bt_Max = btMax /* Max basic type+1 */ -} bt_t; - -/* Redefinition of the language codes. */ - -typedef enum lang { - lang_C = langC, - lang_Pascal = langPascal, - lang_Fortran = langFortran, - lang_Assembler = langAssembler, - lang_Machine = langMachine, - lang_Nil = langNil, - lang_Ada = langAda, - lang_Pl1 = langPl1, - lang_Cobol = langCobol -} lang_t; - -/* Redefinition of the debug level codes. */ - -typedef enum glevel { - glevel_0 = GLEVEL_0, - glevel_1 = GLEVEL_1, - glevel_2 = GLEVEL_2, - glevel_3 = GLEVEL_3 -} glevel_t; - - -/* Keep track of the active scopes. */ -typedef struct scope { - struct scope *prev; /* previous scope */ - ulong open_sym; /* symbol opening scope */ - sc_t sc; /* storage class */ - st_t st; /* symbol type */ -} scope_t; - -struct filehdr global_hdr; /* a.out header */ - -int errors = 0; /* # of errors */ -int want_aux = 0; /* print aux table */ -int want_line = 0; /* print line numbers */ -int want_rfd = 0; /* print relative file desc's */ -int want_scope = 0; /* print scopes for every symbol */ -int tfile = 0; /* no global header file */ -int tfile_fd; /* file descriptor of .T file */ -off_t tfile_offset; /* current offset in .T file */ -scope_t *cur_scope = 0; /* list of active scopes */ -scope_t *free_scope = 0; /* list of freed scopes */ -HDRR sym_hdr; /* symbolic header */ -char *l_strings; /* local strings */ -char *e_strings; /* external strings */ -SYMR *l_symbols; /* local symbols */ -EXTR *e_symbols; /* external symbols */ -LINER *lines; /* line numbers */ -DNR *dense_nums; /* dense numbers */ -OPTR *opt_symbols; /* optimization symbols */ -AUXU *aux_symbols; /* Auxiliary symbols */ -char *aux_used; /* map of which aux syms are used */ -FDR *file_desc; /* file tables */ -ulong *rfile_desc; /* relative file tables */ -PDR *proc_desc; /* procedure tables */ - -/* Forward reference for functions. */ -PTR_T read_seek __proto((PTR_T, size_t, off_t, const char *)); -void read_tfile __proto((void)); -void print_global_hdr __proto((struct filehdr *)); -void print_sym_hdr __proto((HDRR *)); -void print_file_desc __proto((FDR *, int)); -void print_symbol __proto((SYMR *, int, char *, AUXU *, int, FDR *)); -void print_aux __proto((AUXU, int, int)); -void emit_aggregate __proto((char *, AUXU, AUXU, const char *, FDR *)); -const char *st_to_string __proto((st_t)); -const char *sc_to_string __proto((sc_t)); -const char *glevel_to_string __proto((glevel_t)); -const char *lang_to_string __proto((lang_t)); -const char *type_to_string __proto((AUXU *, int, FDR *)); - -#ifndef __alpha -# ifdef NEED_DECLARATION_MALLOC -extern PTR_T malloc __proto((size_t)); -# endif -# ifdef NEED_DECLARATION_CALLOC -extern PTR_T calloc __proto((size_t, size_t)); -# endif -# ifdef NEED_DECLARATION_REALLOC -extern PTR_T realloc __proto((PTR_T, size_t)); -# endif -#endif - -extern char *optarg; -extern int optind; -extern int opterr; - -/* Create a table of debugging stab-codes and corresponding names. */ - -#define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING}, -struct {short code; char string[10];} stab_names[] = { -#include "stab.def" -#undef __define_stab -}; - - -/* Read some bytes at a specified location, and return a pointer. */ - -PTR_T -read_seek (ptr, size, offset, context) - PTR_T ptr; /* pointer to buffer or NULL */ - size_t size; /* # bytes to read */ - off_t offset; /* offset to read at */ - const char *context; /* context for error message */ -{ - long read_size = 0; - - if (size == 0) /* nothing to read */ - return ptr; - - if ((ptr == (PTR_T) 0 && (ptr = malloc (size)) == (PTR_T) 0) - || (tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1) - || (read_size = read (tfile_fd, ptr, size)) < 0) - { - perror (context); - exit (1); - } - - if (read_size != size) - { - fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n", - context, read_size, (long) size); - exit (1); - } - - tfile_offset = offset + size; - return ptr; -} - - -/* Convert language code to string format. */ - -const char * -lang_to_string (lang) - lang_t lang; -{ - switch (lang) - { - case langC: return "C"; - case langPascal: return "Pascal"; - case langFortran: return "Fortran"; - case langAssembler: return "Assembler"; - case langMachine: return "Machine"; - case langNil: return "Nil"; - case langAda: return "Ada"; - case langPl1: return "Pl1"; - case langCobol: return "Cobol"; - } - - return "Unknown language"; -} - - -/* Convert storage class to string. */ - -const char * -sc_to_string(storage_class) - sc_t storage_class; -{ - switch(storage_class) - { - case sc_Nil: return "Nil"; - case sc_Text: return "Text"; - case sc_Data: return "Data"; - case sc_Bss: return "Bss"; - case sc_Register: return "Register"; - case sc_Abs: return "Abs"; - case sc_Undefined: return "Undefined"; - case sc_CdbLocal: return "CdbLocal"; - case sc_Bits: return "Bits"; - case sc_CdbSystem: return "CdbSystem"; - case sc_RegImage: return "RegImage"; - case sc_Info: return "Info"; - case sc_UserStruct: return "UserStruct"; - case sc_SData: return "SData"; - case sc_SBss: return "SBss"; - case sc_RData: return "RData"; - case sc_Var: return "Var"; - case sc_Common: return "Common"; - case sc_SCommon: return "SCommon"; - case sc_VarRegister: return "VarRegister"; - case sc_Variant: return "Variant"; - case sc_SUndefined: return "SUndefined"; - case sc_Init: return "Init"; - case sc_Max: return "Max"; - } - - return "???"; -} - - -/* Convert symbol type to string. */ - -const char * -st_to_string(symbol_type) - st_t symbol_type; -{ - switch(symbol_type) - { - case st_Nil: return "Nil"; - case st_Global: return "Global"; - case st_Static: return "Static"; - case st_Param: return "Param"; - case st_Local: return "Local"; - case st_Label: return "Label"; - case st_Proc: return "Proc"; - case st_Block: return "Block"; - case st_End: return "End"; - case st_Member: return "Member"; - case st_Typedef: return "Typedef"; - case st_File: return "File"; - case st_RegReloc: return "RegReloc"; - case st_Forward: return "Forward"; - case st_StaticProc: return "StaticProc"; - case st_Constant: return "Constant"; - case st_StaParam: return "StaticParam"; -#ifdef stStruct - case st_Struct: return "Struct"; - case st_Union: return "Union"; - case st_Enum: return "Enum"; -#endif - case st_Str: return "String"; - case st_Number: return "Number"; - case st_Expr: return "Expr"; - case st_Type: return "Type"; - case st_Max: return "Max"; - } - - return "???"; -} - - -/* Convert debug level to string. */ - -const char * -glevel_to_string (g_level) - glevel_t g_level; -{ - switch(g_level) - { - case GLEVEL_0: return "G0"; - case GLEVEL_1: return "G1"; - case GLEVEL_2: return "G2"; - case GLEVEL_3: return "G3"; - } - - return "??"; -} - - -/* Convert the type information to string format. */ - -const char * -type_to_string (aux_ptr, index, fdp) - AUXU *aux_ptr; - int index; - FDR *fdp; -{ - AUXU u; - struct qual { - tq_t type; - int low_bound; - int high_bound; - int stride; - } qualifiers[7]; - - bt_t basic_type; - int i; - static char buffer1[1024]; - static char buffer2[1024]; - char *p1 = buffer1; - char *p2 = buffer2; - char *used_ptr = aux_used + (aux_ptr - aux_symbols); - - for (i = 0; i < 7; i++) - { - qualifiers[i].low_bound = 0; - qualifiers[i].high_bound = 0; - qualifiers[i].stride = 0; - } - - used_ptr[index] = 1; - u = aux_ptr[index++]; - if (u.isym == -1) - return "-1 (no type)"; - - basic_type = (bt_t) u.ti.bt; - qualifiers[0].type = (tq_t) u.ti.tq0; - qualifiers[1].type = (tq_t) u.ti.tq1; - qualifiers[2].type = (tq_t) u.ti.tq2; - qualifiers[3].type = (tq_t) u.ti.tq3; - qualifiers[4].type = (tq_t) u.ti.tq4; - qualifiers[5].type = (tq_t) u.ti.tq5; - qualifiers[6].type = tq_Nil; - - /* - * Go get the basic type. - */ - switch (basic_type) - { - case bt_Nil: /* undefined */ - strcpy (p1, "nil"); - break; - - case bt_Adr: /* address - integer same size as pointer */ - strcpy (p1, "address"); - break; - - case bt_Char: /* character */ - strcpy (p1, "char"); - break; - - case bt_UChar: /* unsigned character */ - strcpy (p1, "unsigned char"); - break; - - case bt_Short: /* short */ - strcpy (p1, "short"); - break; - - case bt_UShort: /* unsigned short */ - strcpy (p1, "unsigned short"); - break; - - case bt_Int: /* int */ - strcpy (p1, "int"); - break; - - case bt_UInt: /* unsigned int */ - strcpy (p1, "unsigned int"); - break; - - case bt_Long: /* long */ - strcpy (p1, "long"); - break; - - case bt_ULong: /* unsigned long */ - strcpy (p1, "unsigned long"); - break; - - case bt_Float: /* float (real) */ - strcpy (p1, "float"); - break; - - case bt_Double: /* Double (real) */ - strcpy (p1, "double"); - break; - - /* Structures add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to struct def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case bt_Struct: /* Structure (Record) */ - emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp); - used_ptr[index] = 1; - if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) - used_ptr[++index] = 1; - - index++; /* skip aux words */ - break; - - /* Unions add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to union def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case bt_Union: /* Union */ - emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp); - used_ptr[index] = 1; - if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) - used_ptr[++index] = 1; - - index++; /* skip aux words */ - break; - - /* Enumerations add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to enum def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case bt_Enum: /* Enumeration */ - emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp); - used_ptr[index] = 1; - if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE) - used_ptr[++index] = 1; - - index++; /* skip aux words */ - break; - - case bt_Typedef: /* defined via a typedef, isymRef points */ - strcpy (p1, "typedef"); - break; - - case bt_Range: /* subrange of int */ - strcpy (p1, "subrange"); - break; - - case bt_Set: /* pascal sets */ - strcpy (p1, "set"); - break; - - case bt_Complex: /* fortran complex */ - strcpy (p1, "complex"); - break; - - case bt_DComplex: /* fortran double complex */ - strcpy (p1, "double complex"); - break; - - case bt_Indirect: /* forward or unnamed typedef */ - strcpy (p1, "forward/unnamed typedef"); - break; - - case bt_FixedDec: /* Fixed Decimal */ - strcpy (p1, "fixed decimal"); - break; - - case bt_FloatDec: /* Float Decimal */ - strcpy (p1, "float decimal"); - break; - - case bt_String: /* Varying Length Character String */ - strcpy (p1, "string"); - break; - - case bt_Bit: /* Aligned Bit String */ - strcpy (p1, "bit"); - break; - - case bt_Picture: /* Picture */ - strcpy (p1, "picture"); - break; - - case bt_Void: /* Void */ - strcpy (p1, "void"); - break; - - default: - sprintf (p1, "Unknown basic type %d", (int) basic_type); - break; - } - - p1 += strlen (buffer1); - - /* - * If this is a bitfield, get the bitsize. - */ - if (u.ti.fBitfield) - { - int bitsize; - - used_ptr[index] = 1; - bitsize = aux_ptr[index++].width; - sprintf (p1, " : %d", bitsize); - p1 += strlen (buffer1); - } - - - /* - * Deal with any qualifiers. - */ - if (qualifiers[0].type != tq_Nil) - { - /* - * Snarf up any array bounds in the correct order. Arrays - * store 5 successive words in the aux. table: - * word 0 RNDXR to type of the bounds (ie, int) - * word 1 Current file descriptor index - * word 2 low bound - * word 3 high bound (or -1 if []) - * word 4 stride size in bits - */ - for (i = 0; i < 7; i++) - { - if (qualifiers[i].type == tq_Array) - { - qualifiers[i].low_bound = aux_ptr[index+2].dnLow; - qualifiers[i].high_bound = aux_ptr[index+3].dnHigh; - qualifiers[i].stride = aux_ptr[index+4].width; - used_ptr[index] = 1; - used_ptr[index+1] = 1; - used_ptr[index+2] = 1; - used_ptr[index+3] = 1; - used_ptr[index+4] = 1; - index += 5; - } - } - - /* - * Now print out the qualifiers. - */ - for (i = 0; i < 6; i++) - { - switch (qualifiers[i].type) - { - case tq_Nil: - case tq_Max: - break; - - case tq_Ptr: - strcpy (p2, "ptr to "); - p2 += sizeof ("ptr to ")-1; - break; - - case tq_Vol: - strcpy (p2, "volatile "); - p2 += sizeof ("volatile ")-1; - break; - - case tq_Far: - strcpy (p2, "far "); - p2 += sizeof ("far ")-1; - break; - - case tq_Proc: - strcpy (p2, "func. ret. "); - p2 += sizeof ("func. ret. "); - break; - - case tq_Array: - { - int first_array = i; - int j; - - /* Print array bounds reversed (ie, in the order the C - programmer writes them). C is such a fun language.... */ - - while (i < 5 && qualifiers[i+1].type == tq_Array) - i++; - - for (j = i; j >= first_array; j--) - { - strcpy (p2, "array ["); - p2 += sizeof ("array [")-1; - if (qualifiers[j].low_bound != 0) - sprintf (p2, - "%ld:%ld {%ld bits}", - (long) qualifiers[j].low_bound, - (long) qualifiers[j].high_bound, - (long) qualifiers[j].stride); - - else if (qualifiers[j].high_bound != -1) - sprintf (p2, - "%ld {%ld bits}", - (long) (qualifiers[j].high_bound + 1), - (long) (qualifiers[j].stride)); - - else - sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride)); - - p2 += strlen (p2); - strcpy (p2, "] of "); - p2 += sizeof ("] of ")-1; - } - } - break; - } - } - } - - strcpy (p2, buffer1); - return buffer2; -} - - -/* Print out the global file header for object files. */ - -void -print_global_hdr (ptr) - struct filehdr *ptr; -{ - char *time = ctime ((time_t *)&ptr->f_timdat); - ushort flags = ptr->f_flags; - - printf("Global file header:\n"); - printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic); - printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns); - printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time); - printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr); - printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms); - printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr); - printf(" %-*s 0x%x", 24, "flags", (ushort) flags); - - if ((flags & F_RELFLG) != 0) - printf (", F_RELFLG"); - - if ((flags & F_EXEC) != 0) - printf (", F_EXEC"); - - if ((flags & F_LNNO) != 0) - printf (", F_LNNO"); - - if ((flags & F_LSYMS) != 0) - printf (", F_LSYMS"); - - if ((flags & F_MINMAL) != 0) - printf (", F_MINMAL"); - - if ((flags & F_UPDATE) != 0) - printf (", F_UPDATE"); - - if ((flags & F_SWABD) != 0) - printf (", F_SWABD"); - - if ((flags & F_AR16WR) != 0) - printf (", F_AR16WR"); - - if ((flags & F_AR32WR) != 0) - printf (", F_AR32WR"); - - if ((flags & F_AR32W) != 0) - printf (", F_AR32W"); - - if ((flags & F_PATCH) != 0) - printf (", F_PATCH/F_NODF"); - - printf ("\n\n"); -} - - -/* Print out the symbolic header. */ - -void -print_sym_hdr (sym_ptr) - HDRR *sym_ptr; -{ - int width = 20; - - printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n", - sym_ptr->magic & 0xffff, - (sym_ptr->vstamp & 0xffff) >> 8, - sym_ptr->vstamp & 0xff); - - printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes"); - printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n"); - - printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers", - (long) sym_ptr->cbLineOffset, - (long) sym_ptr->cbLine, - (long) sym_ptr->cbLine, - (int) sym_ptr->ilineMax); - - printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers", - (long) sym_ptr->cbDnOffset, - (long) sym_ptr->idnMax, - (long) (sym_ptr->idnMax * sizeof (DNR))); - - printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables", - (long) sym_ptr->cbPdOffset, - (long) sym_ptr->ipdMax, - (long) (sym_ptr->ipdMax * sizeof (PDR))); - - printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols", - (long) sym_ptr->cbSymOffset, - (long) sym_ptr->isymMax, - (long) (sym_ptr->isymMax * sizeof (SYMR))); - - printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols", - (long) sym_ptr->cbOptOffset, - (long) sym_ptr->ioptMax, - (long) (sym_ptr->ioptMax * sizeof (OPTR))); - - printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols", - (long) sym_ptr->cbAuxOffset, - (long) sym_ptr->iauxMax, - (long) (sym_ptr->iauxMax * sizeof (AUXU))); - - printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings", - (long) sym_ptr->cbSsOffset, - (long) sym_ptr->issMax, - (long) sym_ptr->issMax); - - printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings", - (long) sym_ptr->cbSsExtOffset, - (long) sym_ptr->issExtMax, - (long) sym_ptr->issExtMax); - - printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables", - (long) sym_ptr->cbFdOffset, - (long) sym_ptr->ifdMax, - (long) (sym_ptr->ifdMax * sizeof (FDR))); - - printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files", - (long) sym_ptr->cbRfdOffset, - (long) sym_ptr->crfd, - (long) (sym_ptr->crfd * sizeof (ulong))); - - printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols", - (long) sym_ptr->cbExtOffset, - (long) sym_ptr->iextMax, - (long) (sym_ptr->iextMax * sizeof (EXTR))); -} - - -/* Print out a symbol. */ - -void -print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp) - SYMR *sym_ptr; - int number; - char *strbase; - AUXU *aux_base; - int ifd; - FDR *fdp; -{ - sc_t storage_class = (sc_t) sym_ptr->sc; - st_t symbol_type = (st_t) sym_ptr->st; - ulong index = sym_ptr->index; - char *used_ptr = aux_used + (aux_base - aux_symbols); - scope_t *scope_ptr; - - printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase); - - if (aux_base != (AUXU *) 0 && index != indexNil) - switch (symbol_type) - { - case st_Nil: - case st_Label: - break; - - case st_File: - case st_Block: - printf (" End+1 symbol: %ld\n", index); - if (want_scope) - { - if (free_scope == (scope_t *) 0) - scope_ptr = (scope_t *) malloc (sizeof (scope_t)); - else - { - scope_ptr = free_scope; - free_scope = scope_ptr->prev; - } - scope_ptr->open_sym = number; - scope_ptr->st = symbol_type; - scope_ptr->sc = storage_class; - scope_ptr->prev = cur_scope; - cur_scope = scope_ptr; - } - break; - - case st_End: - if (storage_class == sc_Text || storage_class == sc_Info) - printf (" First symbol: %ld\n", index); - else - { - used_ptr[index] = 1; - printf (" First symbol: %ld\n", (long) aux_base[index].isym); - } - - if (want_scope) - { - if (cur_scope == (scope_t *) 0) - printf (" Can't pop end scope\n"); - else - { - scope_ptr = cur_scope; - cur_scope = scope_ptr->prev; - scope_ptr->prev = free_scope; - free_scope = scope_ptr; - } - } - break; - - case st_Proc: - case st_StaticProc: - if (MIPS_IS_STAB(sym_ptr)) - ; - else if (ifd == -1) /* local symbol */ - { - used_ptr[index] = used_ptr[index+1] = 1; - printf (" End+1 symbol: %-7ld Type: %s\n", - (long) aux_base[index].isym, - type_to_string (aux_base, index+1, fdp)); - } - else /* global symbol */ - printf (" Local symbol: %ld\n", index); - - if (want_scope) - { - if (free_scope == (scope_t *) 0) - scope_ptr = (scope_t *) malloc (sizeof (scope_t)); - else - { - scope_ptr = free_scope; - free_scope = scope_ptr->prev; - } - scope_ptr->open_sym = number; - scope_ptr->st = symbol_type; - scope_ptr->sc = storage_class; - scope_ptr->prev = cur_scope; - cur_scope = scope_ptr; - } - break; - -#ifdef stStruct - case st_Struct: - case st_Union: - case st_Enum: - printf (" End+1 symbol: %lu\n", index); - break; -#endif - - default: - if (!MIPS_IS_STAB (sym_ptr)) - { - used_ptr[index] = 1; - printf (" Type: %s\n", - type_to_string (aux_base, index, fdp)); - } - break; - } - - if (want_scope) - { - printf (" Scopes: "); - if (cur_scope == (scope_t *) 0) - printf (" none\n"); - else - { - for (scope_ptr = cur_scope; - scope_ptr != (scope_t *) 0; - scope_ptr = scope_ptr->prev) - { - const char *class; - if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc) - class = "func."; - else if (scope_ptr->st == st_File) - class = "file"; - else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text) - class = "block"; - else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info) - class = "type"; - else - class = "???"; - - printf (" %ld [%s]", scope_ptr->open_sym, class); - } - printf ("\n"); - } - } - - printf (" Value: %-13ld ", - (long)sym_ptr->value); - if (ifd == -1) - printf ("String index: %ld\n", (long)sym_ptr->iss); - else - printf ("String index: %-11ld Ifd: %d\n", - (long)sym_ptr->iss, ifd); - - printf (" Symbol type: %-11sStorage class: %-11s", - st_to_string (symbol_type), sc_to_string (storage_class)); - - if (MIPS_IS_STAB(sym_ptr)) - { - register int i = sizeof(stab_names) / sizeof(stab_names[0]); - const char *stab_name = "stab"; - short code = MIPS_UNMARK_STAB(sym_ptr->index); - while (--i >= 0) - if (stab_names[i].code == code) - { - stab_name = stab_names[i].string; - break; - } - printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name); - } - else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil) - printf ("Index: %ld (line#)\n", (long)sym_ptr->index); - else - printf ("Index: %ld\n", (long)sym_ptr->index); - -} - - -/* Print out a word from the aux. table in various formats. */ - -void -print_aux (u, auxi, used) - AUXU u; - int auxi; - int used; -{ - printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n", - (used) ? " " : "* ", - auxi, - (long) u.isym, - (long) u.rndx.rfd, - (long) u.rndx.index, - u.ti.bt, - u.ti.fBitfield, - u.ti.continued, - u.ti.tq0, - u.ti.tq1, - u.ti.tq2, - u.ti.tq3, - u.ti.tq4, - u.ti.tq5); -} - - -/* Write aggregate information to a string. */ - -void -emit_aggregate (string, u, u2, which, fdp) - char *string; - AUXU u; - AUXU u2; - const char *which; - FDR *fdp; -{ - unsigned int ifd = u.rndx.rfd; - unsigned int index = u.rndx.index; - const char *name; - - if (ifd == ST_RFDESCAPE) - ifd = u2.isym; - - /* An ifd of -1 is an opaque type. An escaped index of 0 is a - struct return type of a procedure compiled without -g. */ - if (ifd == 0xffffffff - || (u.rndx.rfd == ST_RFDESCAPE && index == 0)) - name = "<undefined>"; - else if (index == indexNil) - name = "<no name>"; - else - { - if (fdp == 0 || sym_hdr.crfd == 0) - fdp = &file_desc[ifd]; - else - fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]]; - name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss]; - } - - sprintf (string, - "%s %s { ifd = %u, index = %u }", - which, name, ifd, index); -} - - -/* Print out information about a file descriptor, and the symbols, - procedures, and line numbers within it. */ - -void -print_file_desc (fdp, number) - FDR *fdp; - int number; -{ - char *str_base; - AUXU *aux_base; - int symi, pdi; - int width = 20; - char *used_base; - - str_base = l_strings + fdp->issBase; - aux_base = aux_symbols + fdp->iauxBase; - used_base = aux_used + (aux_base - aux_symbols); - - printf ("\nFile #%d, \"%s\"\n\n", number, str_base + fdp->rss); - - printf (" Name index = %-10ld Readin = %s\n", - (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No"); - - printf (" Merge = %-10s Endian = %s\n", - (fdp->fMerge) ? "Yes" : "No", - (fdp->fBigendian) ? "BIG" : "LITTLE"); - - printf (" Debug level = %-10s Language = %s\n", - glevel_to_string (fdp->glevel), - lang_to_string((lang_t) fdp->lang)); - - printf (" Adr = 0x%08lx\n\n", (long) fdp->adr); - - printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset"); - printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======"); - - printf(" %-*s %11lu %11lu %11lu %11lu\n", - width, "Local strings", - (ulong) fdp->issBase, - (ulong) fdp->cbSs, - (ulong) fdp->cbSs, - (ulong) (fdp->issBase + sym_hdr.cbSsOffset)); - - printf(" %-*s %11lu %11lu %11lu %11lu\n", - width, "Local symbols", - (ulong) fdp->isymBase, - (ulong) fdp->csym, - (ulong) (fdp->csym * sizeof (SYMR)), - (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset)); - - printf(" %-*s %11lu %11lu %11lu %11lu\n", - width, "Line numbers", - (ulong) fdp->cbLineOffset, - (ulong) fdp->cline, - (ulong) fdp->cbLine, - (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset)); - - printf(" %-*s %11lu %11lu %11lu %11lu\n", - width, "Optimization symbols", - (ulong) fdp->ioptBase, - (ulong) fdp->copt, - (ulong) (fdp->copt * sizeof (OPTR)), - (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset)); - - printf(" %-*s %11lu %11lu %11lu %11lu\n", - width, "Procedures", - (ulong) fdp->ipdFirst, - (ulong) fdp->cpd, - (ulong) (fdp->cpd * sizeof (PDR)), - (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset)); - - printf(" %-*s %11lu %11lu %11lu %11lu\n", - width, "Auxiliary symbols", - (ulong) fdp->iauxBase, - (ulong) fdp->caux, - (ulong) (fdp->caux * sizeof (AUXU)), - (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset)); - - printf(" %-*s %11lu %11lu %11lu %11lu\n", - width, "Relative Files", - (ulong) fdp->rfdBase, - (ulong) fdp->crfd, - (ulong) (fdp->crfd * sizeof (ulong)), - (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset)); - - - if (want_scope && cur_scope != (scope_t *) 0) - printf ("\n Warning scope does not start at 0!\n"); - - /* - * print the info about the symbol table. - */ - printf ("\n There are %lu local symbols, starting at %lu\n", - (ulong) fdp->csym, - (ulong) (fdp->isymBase + sym_hdr.cbSymOffset)); - - for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++) - print_symbol (&l_symbols[symi], - symi - fdp->isymBase, - str_base, - aux_base, - -1, - fdp); - - if (want_scope && cur_scope != (scope_t *) 0) - printf ("\n Warning scope does not end at 0!\n"); - - /* - * print the aux. table if desired. - */ - - if (want_aux && fdp->caux != 0) - { - int auxi; - - printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n", - (ulong) fdp->caux, - (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset)); - - for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++) - print_aux (aux_base[auxi], auxi, used_base[auxi]); - } - - /* - * print the relative file descriptors. - */ - if (want_rfd && fdp->crfd != 0) - { - ulong *rfd_ptr, i; - - printf ("\n There are %lu relative file descriptors, starting at %lu.\n", - (ulong) fdp->crfd, - (ulong) fdp->rfdBase); - - rfd_ptr = rfile_desc + fdp->rfdBase; - for (i = 0; i < (ulong) fdp->crfd; i++) - { - printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr); - rfd_ptr++; - } - } - - /* - * do the procedure descriptors. - */ - printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd); - printf ("starting at %lu.\n", (ulong) fdp->ipdFirst); - - for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++) - { - PDR *proc_ptr = &proc_desc[pdi]; - printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst)); - - printf ("\t Name index = %-11ld Name = \"%s\"\n", - (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss, - l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base); - - printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n", - (long) proc_ptr->regmask, - (long) proc_ptr->regoffset, - (long) proc_ptr->fregmask, - (long) proc_ptr->fregoffset); - - printf ("\t .frame $%d,%ld,$%d\n", - (int) proc_ptr->framereg, - (long) proc_ptr->frameoffset, - (int) proc_ptr->pcreg); - - printf ("\t Opt. start = %-11ld Symbols start = %ld\n", - (long) proc_ptr->iopt, - (long) proc_ptr->isym); - - printf ("\t First line # = %-11ld Last line # = %ld\n", - (long) proc_ptr->lnLow, - (long) proc_ptr->lnHigh); - - printf ("\t Line Offset = %-11ld Address = 0x%08lx\n", - (long) proc_ptr->cbLineOffset, - (long) proc_ptr->adr); - - /* - * print the line number entries. - */ - - if (want_line && fdp->cline != 0) - { - int delta, count; - long cur_line = proc_ptr->lnLow; - uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset - + fdp->cbLineOffset); - uchar *line_end; - - if (pdi == fdp->cpd + fdp->ipdFirst - 1) /* last procedure */ - line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset; - else /* not last proc. */ - line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset - + fdp->cbLineOffset); - - printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n", - (ulong) (line_end - line_ptr), - (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset)); - - while (line_ptr < line_end) - { /* sign extend nibble */ - delta = ((*line_ptr >> 4) ^ 0x8) - 0x8; - count = (*line_ptr & 0xf) + 1; - if (delta != -8) - line_ptr++; - else - { - delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff); - delta = (delta ^ 0x8000) - 0x8000; - line_ptr += 3; - } - - cur_line += delta; - printf ("\t Line %11ld, delta %5d, count %2d\n", - cur_line, - delta, - count); - } - } - } -} - - -/* Read in the portions of the .T file that we will print out. */ - -void -read_tfile __proto((void)) -{ - short magic; - off_t sym_hdr_offset = 0; - - (void) read_seek ((PTR_T) &magic, sizeof (magic), (off_t) 0, "Magic number"); - if (!tfile) - { - /* Print out the global header, since this is not a T-file. */ - - (void) read_seek ((PTR_T) &global_hdr, sizeof (global_hdr), (off_t) 0, - "Global file header"); - - print_global_hdr (&global_hdr); - - if (global_hdr.f_symptr == 0) - { - printf ("No symbolic header, Goodbye!\n"); - exit (1); - } - - sym_hdr_offset = global_hdr.f_symptr; - } - - (void) read_seek ((PTR_T) &sym_hdr, - sizeof (sym_hdr), - sym_hdr_offset, - "Symbolic header"); - - print_sym_hdr (&sym_hdr); - - lines = (LINER *) read_seek ((PTR_T) 0, - sym_hdr.cbLine, - sym_hdr.cbLineOffset, - "Line numbers"); - - dense_nums = (DNR *) read_seek ((PTR_T) 0, - sym_hdr.idnMax * sizeof (DNR), - sym_hdr.cbDnOffset, - "Dense numbers"); - - proc_desc = (PDR *) read_seek ((PTR_T) 0, - sym_hdr.ipdMax * sizeof (PDR), - sym_hdr.cbPdOffset, - "Procedure tables"); - - l_symbols = (SYMR *) read_seek ((PTR_T) 0, - sym_hdr.isymMax * sizeof (SYMR), - sym_hdr.cbSymOffset, - "Local symbols"); - - opt_symbols = (OPTR *) read_seek ((PTR_T) 0, - sym_hdr.ioptMax * sizeof (OPTR), - sym_hdr.cbOptOffset, - "Optimization symbols"); - - aux_symbols = (AUXU *) read_seek ((PTR_T) 0, - sym_hdr.iauxMax * sizeof (AUXU), - sym_hdr.cbAuxOffset, - "Auxiliary symbols"); - - if (sym_hdr.iauxMax > 0) - { - aux_used = calloc (sym_hdr.iauxMax, 1); - if (aux_used == (char *) 0) - { - perror ("calloc"); - exit (1); - } - } - - l_strings = (char *) read_seek ((PTR_T) 0, - sym_hdr.issMax, - sym_hdr.cbSsOffset, - "Local string table"); - - e_strings = (char *) read_seek ((PTR_T) 0, - sym_hdr.issExtMax, - sym_hdr.cbSsExtOffset, - "External string table"); - - file_desc = (FDR *) read_seek ((PTR_T) 0, - sym_hdr.ifdMax * sizeof (FDR), - sym_hdr.cbFdOffset, - "File tables"); - - rfile_desc = (ulong *) read_seek ((PTR_T) 0, - sym_hdr.crfd * sizeof (ulong), - sym_hdr.cbRfdOffset, - "Relative file tables"); - - e_symbols = (EXTR *) read_seek ((PTR_T) 0, - sym_hdr.iextMax * sizeof (EXTR), - sym_hdr.cbExtOffset, - "External symbols"); -} - - - -int -main (argc, argv) - int argc; - char **argv; -{ - int i, opt; - - /* - * Process arguments - */ - while ((opt = getopt (argc, argv, "alrst")) != EOF) - switch (opt) - { - default: errors++; break; - case 'a': want_aux++; break; /* print aux table */ - case 'l': want_line++; break; /* print line numbers */ - case 'r': want_rfd++; break; /* print relative fd's */ - case 's': want_scope++; break; /* print scope info */ - case 't': tfile++; break; /* this is a tfile (without header), and not a .o */ - } - - if (errors || optind != argc - 1) - { - fprintf (stderr, "Calling Sequence:\n"); - fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]); - fprintf (stderr, "\n"); - fprintf (stderr, "switches:\n"); - fprintf (stderr, "\t-a Print out auxiliary table.\n"); - fprintf (stderr, "\t-l Print out line numbers.\n"); - fprintf (stderr, "\t-r Print out relative file descriptors.\n"); - fprintf (stderr, "\t-s Print out the current scopes for an item.\n"); - fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n"); - return 1; - } - - /* - * Open and process the input file. - */ - tfile_fd = open (argv[optind], O_RDONLY); - if (tfile_fd < 0) - { - perror (argv[optind]); - return 1; - } - - read_tfile (); - - /* - * Print any global aux words if any. - */ - if (want_aux) - { - long last_aux_in_use; - - if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0) - { - printf ("\nGlobal auxiliary entries before first file:\n"); - for (i = 0; i < file_desc[0].iauxBase; i++) - print_aux (aux_symbols[i], 0, aux_used[i]); - } - - if (sym_hdr.ifdMax == 0) - last_aux_in_use = 0; - else - last_aux_in_use - = (file_desc[sym_hdr.ifdMax-1].iauxBase - + file_desc[sym_hdr.ifdMax-1].caux - 1); - - if (last_aux_in_use < sym_hdr.iauxMax-1) - { - printf ("\nGlobal auxiliary entries after last file:\n"); - for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++) - print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]); - } - } - - /* - * Print the information for each file. - */ - for (i = 0; i < sym_hdr.ifdMax; i++) - print_file_desc (&file_desc[i], i); - - /* - * Print the external symbols. - */ - want_scope = 0; /* scope info is meaning for extern symbols */ - printf ("\nThere are %lu external symbols, starting at %lu\n", - (ulong) sym_hdr.iextMax, - (ulong) sym_hdr.cbExtOffset); - - for(i = 0; i < sym_hdr.iextMax; i++) - print_symbol (&e_symbols[i].asym, i, e_strings, - aux_symbols + file_desc[e_symbols[i].ifd].iauxBase, - e_symbols[i].ifd, - &file_desc[e_symbols[i].ifd]); - - /* - * Print unused aux symbols now. - */ - - if (want_aux) - { - int first_time = 1; - - for (i = 0; i < sym_hdr.iauxMax; i++) - { - if (! aux_used[i]) - { - if (first_time) - { - printf ("\nThe following auxiliary table entries were unused:\n\n"); - first_time = 0; - } - - printf (" #%-5d %11ld 0x%08lx %s\n", - i, - (long) aux_symbols[i].isym, - (long) aux_symbols[i].isym, - type_to_string (aux_symbols, i, (FDR *) 0)); - } - } - } - - return 0; -} - - -void -fancy_abort () -{ - fprintf (stderr, "mips-tdump internal error"); - exit (1); -} diff --git a/gcc/mips-tfile.c b/gcc/mips-tfile.c deleted file mode 100755 index 588f4ef..0000000 --- a/gcc/mips-tfile.c +++ /dev/null @@ -1,5782 +0,0 @@ -/* Update the symbol table (the .T file) in a MIPS object to - contain debugging information specified by the GNU compiler - in the form of comments (the mips assembler does not support - assembly access to debug information). - Copyright (C) 1991, 93-95, 97, 98, 1999 Free Software Foundation, Inc. - Contributed by Michael Meissner (meissner@cygnus.com). - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Here is a brief description of the MIPS ECOFF symbol table. The - MIPS symbol table has the following pieces: - - Symbolic Header - | - +-- Auxiliary Symbols - | - +-- Dense number table - | - +-- Optimizer Symbols - | - +-- External Strings - | - +-- External Symbols - | - +-- Relative file descriptors - | - +-- File table - | - +-- Procedure table - | - +-- Line number table - | - +-- Local Strings - | - +-- Local Symbols - - The symbolic header points to each of the other tables, and also - contains the number of entries. It also contains a magic number - and MIPS compiler version number, such as 2.0. - - The auxiliary table is a series of 32 bit integers, that are - referenced as needed from the local symbol table. Unlike standard - COFF, the aux. information does not follow the symbol that uses - it, but rather is a separate table. In theory, this would allow - the MIPS compilers to collapse duplicate aux. entries, but I've not - noticed this happening with the 1.31 compiler suite. The different - types of aux. entries are: - - 1) dnLow: Low bound on array dimension. - - 2) dnHigh: High bound on array dimension. - - 3) isym: Index to the local symbol which is the start of the - function for the end of function first aux. entry. - - 4) width: Width of structures and bitfields. - - 5) count: Count of ranges for variant part. - - 6) rndx: A relative index into the symbol table. The relative - index field has two parts: rfd which is a pointer into the - relative file index table or ST_RFDESCAPE which says the next - aux. entry is the file number, and index: which is the pointer - into the local symbol within a given file table. This is for - things like references to types defined in another file. - - 7) Type information: This is like the COFF type bits, except it - is 32 bits instead of 16; they still have room to add new - basic types; and they can handle more than 6 levels of array, - pointer, function, etc. Each type information field contains - the following structure members: - - a) fBitfield: a bit that says this is a bitfield, and the - size in bits follows as the next aux. entry. - - b) continued: a bit that says the next aux. entry is a - continuation of the current type information (in case - there are more than 6 levels of array/ptr/function). - - c) bt: an integer containing the base type before adding - array, pointer, function, etc. qualifiers. The - current base types that I have documentation for are: - - btNil -- undefined - btAdr -- address - integer same size as ptr - btChar -- character - btUChar -- unsigned character - btShort -- short - btUShort -- unsigned short - btInt -- int - btUInt -- unsigned int - btLong -- long - btULong -- unsigned long - btFloat -- float (real) - btDouble -- Double (real) - btStruct -- Structure (Record) - btUnion -- Union (variant) - btEnum -- Enumerated - btTypedef -- defined via a typedef isymRef - btRange -- subrange of int - btSet -- pascal sets - btComplex -- fortran complex - btDComplex -- fortran double complex - btIndirect -- forward or unnamed typedef - btFixedDec -- Fixed Decimal - btFloatDec -- Float Decimal - btString -- Varying Length Character String - btBit -- Aligned Bit String - btPicture -- Picture - btVoid -- Void (MIPS cc revision >= 2.00) - - d) tq0 - tq5: type qualifier fields as needed. The - current type qualifier fields I have documentation for - are: - - tqNil -- no more qualifiers - tqPtr -- pointer - tqProc -- procedure - tqArray -- array - tqFar -- 8086 far pointers - tqVol -- volatile - - - The dense number table is used in the front ends, and disappears by - the time the .o is created. - - With the 1.31 compiler suite, the optimization symbols don't seem - to be used as far as I can tell. - - The linker is the first entity that creates the relative file - descriptor table, and I believe it is used so that the individual - file table pointers don't have to be rewritten when the objects are - merged together into the program file. - - Unlike COFF, the basic symbol & string tables are split into - external and local symbols/strings. The relocation information - only goes off of the external symbol table, and the debug - information only goes off of the internal symbol table. The - external symbols can have links to an appropriate file index and - symbol within the file to give it the appropriate type information. - Because of this, the external symbols are actually larger than the - internal symbols (to contain the link information), and contain the - local symbol structure as a member, though this member is not the - first member of the external symbol structure (!). I suspect this - split is to make strip easier to deal with. - - Each file table has offsets for where the line numbers, local - strings, local symbols, and procedure table starts from within the - global tables, and the indexs are reset to 0 for each of those - tables for the file. - - The procedure table contains the binary equivalents of the .ent - (start of the function address), .frame (what register is the - virtual frame pointer, constant offset from the register to obtain - the VFP, and what register holds the return address), .mask/.fmask - (bitmask of saved registers, and where the first register is stored - relative to the VFP) assembler directives. It also contains the - low and high bounds of the line numbers if debugging is turned on. - - The line number table is a compressed form of the normal COFF line - table. Each line number entry is either 1 or 3 bytes long, and - contains a signed delta from the previous line, and an unsigned - count of the number of instructions this statement takes. - - The local symbol table contains the following fields: - - 1) iss: index to the local string table giving the name of the - symbol. - - 2) value: value of the symbol (address, register number, etc.). - - 3) st: symbol type. The current symbol types are: - - stNil -- Nuthin' special - stGlobal -- external symbol - stStatic -- static - stParam -- procedure argument - stLocal -- local variable - stLabel -- label - stProc -- External Procedure - stBlock -- beginning of block - stEnd -- end (of anything) - stMember -- member (of anything) - stTypedef -- type definition - stFile -- file name - stRegReloc -- register relocation - stForward -- forwarding address - stStaticProc -- Static procedure - stConstant -- const - - 4) sc: storage class. The current storage classes are: - - scText -- text symbol - scData -- initialized data symbol - scBss -- un-initialized data symbol - scRegister -- value of symbol is register number - scAbs -- value of symbol is absolute - scUndefined -- who knows? - scCdbLocal -- variable's value is IN se->va.?? - scBits -- this is a bit field - scCdbSystem -- value is IN debugger's address space - scRegImage -- register value saved on stack - scInfo -- symbol contains debugger information - scUserStruct -- addr in struct user for current process - scSData -- load time only small data - scSBss -- load time only small common - scRData -- load time only read only data - scVar -- Var parameter (fortranpascal) - scCommon -- common variable - scSCommon -- small common - scVarRegister -- Var parameter in a register - scVariant -- Variant record - scSUndefined -- small undefined(external) data - scInit -- .init section symbol - - 5) index: pointer to a local symbol or aux. entry. - - - - For the following program: - - #include <stdio.h> - - main(){ - printf("Hello World!\n"); - return 0; - } - - Mips-tdump produces the following information: - - Global file header: - magic number 0x162 - # sections 2 - timestamp 645311799, Wed Jun 13 17:16:39 1990 - symbolic header offset 284 - symbolic header size 96 - optional header 56 - flags 0x0 - - Symbolic header, magic number = 0x7009, vstamp = 1.31: - - Info Offset Number Bytes - ==== ====== ====== ===== - - Line numbers 380 4 4 [13] - Dense numbers 0 0 0 - Procedures Tables 384 1 52 - Local Symbols 436 16 192 - Optimization Symbols 0 0 0 - Auxiliary Symbols 628 39 156 - Local Strings 784 80 80 - External Strings 864 144 144 - File Tables 1008 2 144 - Relative Files 0 0 0 - External Symbols 1152 20 320 - - File #0, "hello2.c" - - Name index = 1 Readin = No - Merge = No Endian = LITTLE - Debug level = G2 Language = C - Adr = 0x00000000 - - Info Start Number Size Offset - ==== ===== ====== ==== ====== - Local strings 0 15 15 784 - Local symbols 0 6 72 436 - Line numbers 0 13 13 380 - Optimization symbols 0 0 0 0 - Procedures 0 1 52 384 - Auxiliary symbols 0 14 56 628 - Relative Files 0 0 0 0 - - There are 6 local symbols, starting at 436 - - Symbol# 0: "hello2.c" - End+1 symbol = 6 - String index = 1 - Storage class = Text Index = 6 - Symbol type = File Value = 0 - - Symbol# 1: "main" - End+1 symbol = 5 - Type = int - String index = 10 - Storage class = Text Index = 12 - Symbol type = Proc Value = 0 - - Symbol# 2: "" - End+1 symbol = 4 - String index = 0 - Storage class = Text Index = 4 - Symbol type = Block Value = 8 - - Symbol# 3: "" - First symbol = 2 - String index = 0 - Storage class = Text Index = 2 - Symbol type = End Value = 28 - - Symbol# 4: "main" - First symbol = 1 - String index = 10 - Storage class = Text Index = 1 - Symbol type = End Value = 52 - - Symbol# 5: "hello2.c" - First symbol = 0 - String index = 1 - Storage class = Text Index = 0 - Symbol type = End Value = 0 - - There are 14 auxiliary table entries, starting at 628. - - * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0] - * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0] - * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0] - * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0] - * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0] - * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0] - * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0] - * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0] - * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0] - * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0] - * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0] - #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0] - #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0] - - There are 1 procedure descriptor entries, starting at 0. - - Procedure descriptor 0: - Name index = 10 Name = "main" - .mask 0x80000000,-4 .fmask 0x00000000,0 - .frame $29,24,$31 - Opt. start = -1 Symbols start = 1 - First line # = 3 Last line # = 6 - Line Offset = 0 Address = 0x00000000 - - There are 4 bytes holding line numbers, starting at 380. - Line 3, delta 0, count 2 - Line 4, delta 1, count 3 - Line 5, delta 1, count 2 - Line 6, delta 1, count 6 - - File #1, "/usr/include/stdio.h" - - Name index = 1 Readin = No - Merge = Yes Endian = LITTLE - Debug level = G2 Language = C - Adr = 0x00000000 - - Info Start Number Size Offset - ==== ===== ====== ==== ====== - Local strings 15 65 65 799 - Local symbols 6 10 120 508 - Line numbers 0 0 0 380 - Optimization symbols 0 0 0 0 - Procedures 1 0 0 436 - Auxiliary symbols 14 25 100 684 - Relative Files 0 0 0 0 - - There are 10 local symbols, starting at 442 - - Symbol# 0: "/usr/include/stdio.h" - End+1 symbol = 10 - String index = 1 - Storage class = Text Index = 10 - Symbol type = File Value = 0 - - Symbol# 1: "_iobuf" - End+1 symbol = 9 - String index = 22 - Storage class = Info Index = 9 - Symbol type = Block Value = 20 - - Symbol# 2: "_cnt" - Type = int - String index = 29 - Storage class = Info Index = 4 - Symbol type = Member Value = 0 - - Symbol# 3: "_ptr" - Type = ptr to char - String index = 34 - Storage class = Info Index = 15 - Symbol type = Member Value = 32 - - Symbol# 4: "_base" - Type = ptr to char - String index = 39 - Storage class = Info Index = 16 - Symbol type = Member Value = 64 - - Symbol# 5: "_bufsiz" - Type = int - String index = 45 - Storage class = Info Index = 4 - Symbol type = Member Value = 96 - - Symbol# 6: "_flag" - Type = short - String index = 53 - Storage class = Info Index = 3 - Symbol type = Member Value = 128 - - Symbol# 7: "_file" - Type = char - String index = 59 - Storage class = Info Index = 2 - Symbol type = Member Value = 144 - - Symbol# 8: "" - First symbol = 1 - String index = 0 - Storage class = Info Index = 1 - Symbol type = End Value = 0 - - Symbol# 9: "/usr/include/stdio.h" - First symbol = 0 - String index = 1 - Storage class = Text Index = 0 - Symbol type = End Value = 0 - - There are 25 auxiliary table entries, starting at 642. - - * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f] - #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0] - #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0] - * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0] - * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1] - * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0] - * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4] - * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0] - * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0] - * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0] - * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0] - - There are 0 procedure descriptor entries, starting at 1. - - There are 20 external symbols, starting at 1152 - - Symbol# 0: "_iob" - Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 } - String index = 0 Ifd = 1 - Storage class = Nil Index = 17 - Symbol type = Global Value = 60 - - Symbol# 1: "fopen" - String index = 5 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 2: "fdopen" - String index = 11 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 3: "freopen" - String index = 18 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 4: "popen" - String index = 26 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 5: "tmpfile" - String index = 32 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 6: "ftell" - String index = 40 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 7: "rewind" - String index = 46 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 8: "setbuf" - String index = 53 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 9: "setbuffer" - String index = 60 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 10: "setlinebuf" - String index = 70 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 11: "fgets" - String index = 81 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 12: "gets" - String index = 87 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 13: "ctermid" - String index = 92 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 14: "cuserid" - String index = 100 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 15: "tempnam" - String index = 108 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 16: "tmpnam" - String index = 116 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 17: "sprintf" - String index = 123 Ifd = 1 - Storage class = Nil Index = 1048575 - Symbol type = Proc Value = 0 - - Symbol# 18: "main" - Type = int - String index = 131 Ifd = 0 - Storage class = Text Index = 1 - Symbol type = Proc Value = 0 - - Symbol# 19: "printf" - String index = 136 Ifd = 0 - Storage class = Undefined Index = 1048575 - Symbol type = Proc Value = 0 - - The following auxiliary table entries were unused: - - #0 0 0x00000000 void - #2 8 0x00000008 char - #3 16 0x00000010 short - #4 24 0x00000018 int - #5 32 0x00000020 long - #6 40 0x00000028 float - #7 44 0x0000002c double - #8 12 0x0000000c unsigned char - #9 20 0x00000014 unsigned short - #10 28 0x0000001c unsigned int - #11 36 0x00000024 unsigned long - #14 0 0x00000000 void - #15 24 0x00000018 int - #19 32 0x00000020 long - #20 40 0x00000028 float - #21 44 0x0000002c double - #22 12 0x0000000c unsigned char - #23 20 0x00000014 unsigned short - #24 28 0x0000001c unsigned int - #25 36 0x00000024 unsigned long - #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 } - -*/ - - -#include "config.h" -#include "system.h" - -#ifndef __SABER__ -#define saber_stop() -#endif - -#ifndef __LINE__ -#define __LINE__ 0 -#endif - -#define __proto(x) PARAMS(x) -typedef PTR PTR_T; -typedef const PTR_T CPTR_T; - -/* Due to size_t being defined in sys/types.h and different - in stddef.h, we have to do this by hand..... Note, these - types are correct for MIPS based systems, and may not be - correct for other systems. Ultrix 4.0 and Silicon Graphics - have this fixed, but since the following is correct, and - the fact that including stddef.h gets you GCC's version - instead of the standard one it's not worth it to fix it. */ - -#if defined(__OSF1__) || defined(__OSF__) || defined(__osf__) -#define Size_t long unsigned int -#else -#define Size_t unsigned int -#endif -#define Ptrdiff_t long - -/* The following might be called from obstack or malloc, - so they can't be static. */ - -extern void pfatal_with_name - __proto((const char *)); -extern void fancy_abort __proto((void)); - void botch __proto((const char *)); -extern void xfree __proto((PTR)); - -extern void fatal PVPROTO((const char *format, ...)) ATTRIBUTE_PRINTF_1; -extern void error PVPROTO((const char *format, ...)) ATTRIBUTE_PRINTF_1; - -#ifndef MIPS_DEBUGGING_INFO - -static int line_number; -static int cur_line_start; -static int debug; -static int had_errors; -static const char *progname; -static const char *input_name; - -int -main () -{ - fprintf (stderr, "Mips-tfile should only be run on a MIPS computer!\n"); - exit (1); -} - -#else /* MIPS_DEBUGGING defined */ - -/* The local and global symbols have a field index, so undo any defines - of index -> strchr and rindex -> strrchr. */ - -#undef rindex -#undef index - -#include <signal.h> - -#ifndef CROSS_COMPILE -#include <a.out.h> -#else -#include "mips/a.out.h" -#endif /* CROSS_COMPILE */ - -#if defined (USG) || !defined (HAVE_STAB_H) -#include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */ -#else -#include <stab.h> /* On BSD, use the system's stab.h. */ -#endif /* not USG */ - -#include "machmode.h" - -#ifdef __GNU_STAB__ -#define STAB_CODE_TYPE enum __stab_debug_code -#else -#define STAB_CODE_TYPE int -#endif - -#ifndef MALLOC_CHECK -#ifdef __SABER__ -#define MALLOC_CHECK -#endif -#endif - -#define IS_ASM_IDENT(ch) \ - (ISALNUM (ch) || (ch) == '_' || (ch) == '.' || (ch) == '$') - - -/* Redefinition of storage classes as an enumeration for better - debugging. */ - -typedef enum sc { - sc_Nil = scNil, /* no storage class */ - sc_Text = scText, /* text symbol */ - sc_Data = scData, /* initialized data symbol */ - sc_Bss = scBss, /* un-initialized data symbol */ - sc_Register = scRegister, /* value of symbol is register number */ - sc_Abs = scAbs, /* value of symbol is absolute */ - sc_Undefined = scUndefined, /* who knows? */ - sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */ - sc_Bits = scBits, /* this is a bit field */ - sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */ - sc_RegImage = scRegImage, /* register value saved on stack */ - sc_Info = scInfo, /* symbol contains debugger information */ - sc_UserStruct = scUserStruct, /* addr in struct user for current process */ - sc_SData = scSData, /* load time only small data */ - sc_SBss = scSBss, /* load time only small common */ - sc_RData = scRData, /* load time only read only data */ - sc_Var = scVar, /* Var parameter (fortran,pascal) */ - sc_Common = scCommon, /* common variable */ - sc_SCommon = scSCommon, /* small common */ - sc_VarRegister = scVarRegister, /* Var parameter in a register */ - sc_Variant = scVariant, /* Variant record */ - sc_SUndefined = scSUndefined, /* small undefined(external) data */ - sc_Init = scInit, /* .init section symbol */ - sc_Max = scMax /* Max storage class+1 */ -} sc_t; - -/* Redefinition of symbol type. */ - -typedef enum st { - st_Nil = stNil, /* Nuthin' special */ - st_Global = stGlobal, /* external symbol */ - st_Static = stStatic, /* static */ - st_Param = stParam, /* procedure argument */ - st_Local = stLocal, /* local variable */ - st_Label = stLabel, /* label */ - st_Proc = stProc, /* " " Procedure */ - st_Block = stBlock, /* beginning of block */ - st_End = stEnd, /* end (of anything) */ - st_Member = stMember, /* member (of anything - struct/union/enum */ - st_Typedef = stTypedef, /* type definition */ - st_File = stFile, /* file name */ - st_RegReloc = stRegReloc, /* register relocation */ - st_Forward = stForward, /* forwarding address */ - st_StaticProc = stStaticProc, /* load time only static procs */ - st_Constant = stConstant, /* const */ - st_Str = stStr, /* string */ - st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */ - st_Expr = stExpr, /* 2+2 vs. 4 */ - st_Type = stType, /* post-coercion SER */ - st_Max = stMax /* max type+1 */ -} st_t; - -/* Redefinition of type qualifiers. */ - -typedef enum tq { - tq_Nil = tqNil, /* bt is what you see */ - tq_Ptr = tqPtr, /* pointer */ - tq_Proc = tqProc, /* procedure */ - tq_Array = tqArray, /* duh */ - tq_Far = tqFar, /* longer addressing - 8086/8 land */ - tq_Vol = tqVol, /* volatile */ - tq_Max = tqMax /* Max type qualifier+1 */ -} tq_t; - -/* Redefinition of basic types. */ - -typedef enum bt { - bt_Nil = btNil, /* undefined */ - bt_Adr = btAdr, /* address - integer same size as pointer */ - bt_Char = btChar, /* character */ - bt_UChar = btUChar, /* unsigned character */ - bt_Short = btShort, /* short */ - bt_UShort = btUShort, /* unsigned short */ - bt_Int = btInt, /* int */ - bt_UInt = btUInt, /* unsigned int */ - bt_Long = btLong, /* long */ - bt_ULong = btULong, /* unsigned long */ - bt_Float = btFloat, /* float (real) */ - bt_Double = btDouble, /* Double (real) */ - bt_Struct = btStruct, /* Structure (Record) */ - bt_Union = btUnion, /* Union (variant) */ - bt_Enum = btEnum, /* Enumerated */ - bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */ - bt_Range = btRange, /* subrange of int */ - bt_Set = btSet, /* pascal sets */ - bt_Complex = btComplex, /* fortran complex */ - bt_DComplex = btDComplex, /* fortran double complex */ - bt_Indirect = btIndirect, /* forward or unnamed typedef */ - bt_FixedDec = btFixedDec, /* Fixed Decimal */ - bt_FloatDec = btFloatDec, /* Float Decimal */ - bt_String = btString, /* Varying Length Character String */ - bt_Bit = btBit, /* Aligned Bit String */ - bt_Picture = btPicture, /* Picture */ - -#ifdef btVoid - bt_Void = btVoid, /* Void */ -#else -#define bt_Void bt_Nil -#endif - - bt_Max = btMax /* Max basic type+1 */ -} bt_t; - - - -/* Basic COFF storage classes. */ -enum coff_storage { - C_EFCN = -1, - C_NULL = 0, - C_AUTO = 1, - C_EXT = 2, - C_STAT = 3, - C_REG = 4, - C_EXTDEF = 5, - C_LABEL = 6, - C_ULABEL = 7, - C_MOS = 8, - C_ARG = 9, - C_STRTAG = 10, - C_MOU = 11, - C_UNTAG = 12, - C_TPDEF = 13, - C_USTATIC = 14, - C_ENTAG = 15, - C_MOE = 16, - C_REGPARM = 17, - C_FIELD = 18, - C_BLOCK = 100, - C_FCN = 101, - C_EOS = 102, - C_FILE = 103, - C_LINE = 104, - C_ALIAS = 105, - C_HIDDEN = 106, - C_MAX = 107 -} coff_storage_t; - -/* Regular COFF fundamental type. */ -typedef enum coff_type { - T_NULL = 0, - T_ARG = 1, - T_CHAR = 2, - T_SHORT = 3, - T_INT = 4, - T_LONG = 5, - T_FLOAT = 6, - T_DOUBLE = 7, - T_STRUCT = 8, - T_UNION = 9, - T_ENUM = 10, - T_MOE = 11, - T_UCHAR = 12, - T_USHORT = 13, - T_UINT = 14, - T_ULONG = 15, - T_MAX = 16 -} coff_type_t; - -/* Regular COFF derived types. */ -typedef enum coff_dt { - DT_NON = 0, - DT_PTR = 1, - DT_FCN = 2, - DT_ARY = 3, - DT_MAX = 4 -} coff_dt_t; - -#define N_BTMASK 017 /* bitmask to isolate basic type */ -#define N_TMASK 003 /* bitmask to isolate derived type */ -#define N_BT_SHIFT 4 /* # bits to shift past basic type */ -#define N_TQ_SHIFT 2 /* # bits to shift derived types */ -#define N_TQ 6 /* # of type qualifiers */ - -/* States for whether to hash type or not. */ -typedef enum hash_state { - hash_no = 0, /* don't hash type */ - hash_yes = 1, /* ok to hash type, or use previous hash */ - hash_record = 2 /* ok to record hash, but don't use prev. */ -} hash_state_t; - - -/* Types of different sized allocation requests. */ -enum alloc_type { - alloc_type_none, /* dummy value */ - alloc_type_scope, /* nested scopes linked list */ - alloc_type_vlinks, /* glue linking pages in varray */ - alloc_type_shash, /* string hash element */ - alloc_type_thash, /* type hash element */ - alloc_type_tag, /* struct/union/tag element */ - alloc_type_forward, /* element to hold unknown tag */ - alloc_type_thead, /* head of type hash list */ - alloc_type_varray, /* general varray allocation */ - alloc_type_last /* last+1 element for array bounds */ -}; - - -#define WORD_ALIGN(x) (((x) + (sizeof (long) - 1)) & ~ (sizeof (long) - 1)) -#define DWORD_ALIGN(x) (((x) + 7) & ~7) - - -/* Structures to provide n-number of virtual arrays, each of which can - grow linearly, and which are written in the object file as sequential - pages. On systems with a BSD malloc that define USE_MALLOC, the - MAX_CLUSTER_PAGES should be 1 less than a power of two, since malloc - adds its overhead, and rounds up to the next power of 2. Pages are - linked together via a linked list. - - If PAGE_SIZE is > 4096, the string length in the shash_t structure - can't be represented (assuming there are strings > 4096 bytes). */ - -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 /* size of varray pages */ -#endif - -#define PAGE_USIZE ((Size_t)PAGE_SIZE) - - -#ifndef MAX_CLUSTER_PAGES /* # pages to get from system */ -#ifndef USE_MALLOC /* in one memory request */ -#define MAX_CLUSTER_PAGES 64 -#else -#define MAX_CLUSTER_PAGES 63 -#endif -#endif - - -/* Linked list connecting separate page allocations. */ -typedef struct vlinks { - struct vlinks *prev; /* previous set of pages */ - struct vlinks *next; /* next set of pages */ - union page *datum; /* start of page */ - unsigned long start_index; /* starting index # of page */ -} vlinks_t; - - -/* Virtual array header. */ -typedef struct varray { - vlinks_t *first; /* first page link */ - vlinks_t *last; /* last page link */ - unsigned long num_allocated; /* # objects allocated */ - unsigned short object_size; /* size in bytes of each object */ - unsigned short objects_per_page; /* # objects that can fit on a page */ - unsigned short objects_last_page; /* # objects allocated on last page */ -} varray_t; - -#ifndef MALLOC_CHECK -#define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type)) -#else -#define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE) -#endif - -#define INIT_VARRAY(type) { /* macro to initialize a varray */ \ - (vlinks_t *) 0, /* first */ \ - (vlinks_t *) 0, /* last */ \ - 0, /* num_allocated */ \ - sizeof (type), /* object_size */ \ - OBJECTS_PER_PAGE (type), /* objects_per_page */ \ - OBJECTS_PER_PAGE (type), /* objects_last_page */ \ -} - -/* Master type for indexes within the symbol table. */ -typedef unsigned long symint_t; - - -/* Linked list support for nested scopes (file, block, structure, etc.). */ -typedef struct scope { - struct scope *prev; /* previous scope level */ - struct scope *free; /* free list pointer */ - SYMR *lsym; /* pointer to local symbol node */ - symint_t lnumber; /* lsym index */ - st_t type; /* type of the node */ -} scope_t; - - -/* Forward reference list for tags referenced, but not yet defined. */ -typedef struct forward { - struct forward *next; /* next forward reference */ - struct forward *free; /* free list pointer */ - AUXU *ifd_ptr; /* pointer to store file index */ - AUXU *index_ptr; /* pointer to store symbol index */ - AUXU *type_ptr; /* pointer to munge type info */ -} forward_t; - - -/* Linked list support for tags. The first tag in the list is always - the current tag for that block. */ -typedef struct tag { - struct tag *free; /* free list pointer */ - struct shash *hash_ptr; /* pointer to the hash table head */ - struct tag *same_name; /* tag with same name in outer scope */ - struct tag *same_block; /* next tag defined in the same block. */ - struct forward *forward_ref; /* list of forward references */ - bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */ - symint_t ifd; /* file # tag defined in */ - symint_t indx; /* index within file's local symbols */ -} tag_t; - - -/* Head of a block's linked list of tags. */ -typedef struct thead { - struct thead *prev; /* previous block */ - struct thead *free; /* free list pointer */ - struct tag *first_tag; /* first tag in block defined */ -} thead_t; - - -/* Union containing pointers to each the small structures which are freed up. */ -typedef union small_free { - scope_t *f_scope; /* scope structure */ - thead_t *f_thead; /* tag head structure */ - tag_t *f_tag; /* tag element structure */ - forward_t *f_forward; /* forward tag reference */ -} small_free_t; - - -/* String hash table support. The size of the hash table must fit - within a page. */ - -#ifndef SHASH_SIZE -#define SHASH_SIZE 1009 -#endif - -#define HASH_LEN_MAX ((1 << 12) - 1) /* Max length we can store */ - -typedef struct shash { - struct shash *next; /* next hash value */ - char *string; /* string we are hashing */ - symint_t len; /* string length */ - symint_t indx; /* index within string table */ - EXTR *esym_ptr; /* global symbol pointer */ - SYMR *sym_ptr; /* local symbol pointer */ - SYMR *end_ptr; /* symbol pointer to end block */ - tag_t *tag_ptr; /* tag pointer */ - PDR *proc_ptr; /* procedure descriptor pointer */ -} shash_t; - - -/* Type hash table support. The size of the hash table must fit - within a page with the other extended file descriptor information. - Because unique types which are hashed are fewer in number than - strings, we use a smaller hash value. */ - -#ifndef THASH_SIZE -#define THASH_SIZE 113 -#endif - -typedef struct thash { - struct thash *next; /* next hash value */ - AUXU type; /* type we are hashing */ - symint_t indx; /* index within string table */ -} thash_t; - - -/* Extended file descriptor that contains all of the support necessary - to add things to each file separately. */ -typedef struct efdr { - FDR fdr; /* File header to be written out */ - FDR *orig_fdr; /* original file header */ - char *name; /* filename */ - int name_len; /* length of the filename */ - symint_t void_type; /* aux. pointer to 'void' type */ - symint_t int_type; /* aux. pointer to 'int' type */ - scope_t *cur_scope; /* current nested scopes */ - symint_t file_index; /* current file number */ - int nested_scopes; /* # nested scopes */ - varray_t strings; /* local strings */ - varray_t symbols; /* local symbols */ - varray_t procs; /* procedures */ - varray_t aux_syms; /* auxiliary symbols */ - struct efdr *next_file; /* next file descriptor */ - /* string/type hash tables */ - shash_t **shash_head; /* string hash table */ - thash_t *thash_head[THASH_SIZE]; -} efdr_t; - -/* Pre-initialized extended file structure. */ -static efdr_t init_file = -{ - { /* FDR structure */ - 0, /* adr: memory address of beginning of file */ - 0, /* rss: file name (of source, if known) */ - 0, /* issBase: file's string space */ - 0, /* cbSs: number of bytes in the ss */ - 0, /* isymBase: beginning of symbols */ - 0, /* csym: count file's of symbols */ - 0, /* ilineBase: file's line symbols */ - 0, /* cline: count of file's line symbols */ - 0, /* ioptBase: file's optimization entries */ - 0, /* copt: count of file's optimization entries */ - 0, /* ipdFirst: start of procedures for this file */ - 0, /* cpd: count of procedures for this file */ - 0, /* iauxBase: file's auxiliary entries */ - 0, /* caux: count of file's auxiliary entries */ - 0, /* rfdBase: index into the file indirect table */ - 0, /* crfd: count file indirect entries */ - langC, /* lang: language for this file */ - 1, /* fMerge: whether this file can be merged */ - 0, /* fReadin: true if read in (not just created) */ -#ifdef HOST_WORDS_BIG_ENDIAN - 1, /* fBigendian: if 1, compiled on big endian machine */ -#else - 0, /* fBigendian: if 1, compiled on big endian machine */ -#endif - GLEVEL_2, /* glevel: level this file was compiled with */ - 0, /* reserved: reserved for future use */ - 0, /* cbLineOffset: byte offset from header for this file ln's */ - 0, /* cbLine: size of lines for this file */ - }, - - (FDR *) 0, /* orig_fdr: original file header pointer */ - (char *) 0, /* name: pointer to filename */ - 0, /* name_len: length of filename */ - 0, /* void_type: ptr to aux node for void type */ - 0, /* int_type: ptr to aux node for int type */ - (scope_t *) 0, /* cur_scope: current scope being processed */ - 0, /* file_index: current file # */ - 0, /* nested_scopes: # nested scopes */ - INIT_VARRAY (char), /* strings: local string varray */ - INIT_VARRAY (SYMR), /* symbols: local symbols varray */ - INIT_VARRAY (PDR), /* procs: procedure varray */ - INIT_VARRAY (AUXU), /* aux_syms: auxiliary symbols varray */ - - (struct efdr *) 0, /* next_file: next file structure */ - - (shash_t **) 0, /* shash_head: string hash table */ - { 0 }, /* thash_head: type hash table */ -}; - - -static efdr_t *first_file; /* first file descriptor */ -static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */ - - -/* Union of various things that are held in pages. */ -typedef union page { - char byte [ PAGE_SIZE ]; - unsigned char ubyte [ PAGE_SIZE ]; - efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ]; - FDR ofile [ PAGE_SIZE / sizeof (FDR) ]; - PDR proc [ PAGE_SIZE / sizeof (PDR) ]; - SYMR sym [ PAGE_SIZE / sizeof (SYMR) ]; - EXTR esym [ PAGE_SIZE / sizeof (EXTR) ]; - AUXU aux [ PAGE_SIZE / sizeof (AUXU) ]; - DNR dense [ PAGE_SIZE / sizeof (DNR) ]; - scope_t scope [ PAGE_SIZE / sizeof (scope_t) ]; - vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ]; - shash_t shash [ PAGE_SIZE / sizeof (shash_t) ]; - thash_t thash [ PAGE_SIZE / sizeof (thash_t) ]; - tag_t tag [ PAGE_SIZE / sizeof (tag_t) ]; - forward_t forward [ PAGE_SIZE / sizeof (forward_t) ]; - thead_t thead [ PAGE_SIZE / sizeof (thead_t) ]; -} page_t; - - -/* Structure holding allocation information for small sized structures. */ -typedef struct alloc_info { - const char *alloc_name; /* name of this allocation type (must be first) */ - page_t *cur_page; /* current page being allocated from */ - small_free_t free_list; /* current free list if any */ - int unallocated; /* number of elements unallocated on page */ - int total_alloc; /* total number of allocations */ - int total_free; /* total number of frees */ - int total_pages; /* total number of pages allocated */ -} alloc_info_t; - -/* Type information collected together. */ -typedef struct type_info { - bt_t basic_type; /* basic type */ - coff_type_t orig_type; /* original COFF-based type */ - int num_tq; /* # type qualifiers */ - int num_dims; /* # dimensions */ - int num_sizes; /* # sizes */ - int extra_sizes; /* # extra sizes not tied with dims */ - tag_t * tag_ptr; /* tag pointer */ - int bitfield; /* symbol is a bitfield */ - int unknown_tag; /* this is an unknown tag */ - tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/ - symint_t dimensions [N_TQ]; /* dimensions for each array */ - symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of - struct/union/enum + bitfield size */ -} type_info_t; - -/* Pre-initialized type_info struct. */ -static type_info_t type_info_init = { - bt_Nil, /* basic type */ - T_NULL, /* original COFF-based type */ - 0, /* # type qualifiers */ - 0, /* # dimensions */ - 0, /* # sizes */ - 0, /* sizes not tied with dims */ - NULL, /* ptr to tag */ - 0, /* bitfield */ - 0, /* unknown tag */ - { /* type qualifiers */ - tq_Nil, - tq_Nil, - tq_Nil, - tq_Nil, - tq_Nil, - tq_Nil, - }, - { /* dimensions */ - 0, - 0, - 0, - 0, - 0, - 0 - }, - { /* sizes */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - }, -}; - - -/* Global virtual arrays & hash table for external strings as well as - for the tags table and global tables for file descriptors, and - dense numbers. */ - -static varray_t file_desc = INIT_VARRAY (efdr_t); -static varray_t dense_num = INIT_VARRAY (DNR); -static varray_t tag_strings = INIT_VARRAY (char); -static varray_t ext_strings = INIT_VARRAY (char); -static varray_t ext_symbols = INIT_VARRAY (EXTR); - -static shash_t *orig_str_hash[SHASH_SIZE]; -static shash_t *ext_str_hash [SHASH_SIZE]; -static shash_t *tag_hash [SHASH_SIZE]; - -/* Static types for int and void. Also, remember the last function's - type (which is set up when we encounter the declaration for the - function, and used when the end block for the function is emitted. */ - -static type_info_t int_type_info; -static type_info_t void_type_info; -static type_info_t last_func_type_info; -static EXTR *last_func_eptr; - - -/* Convert COFF basic type to ECOFF basic type. The T_NULL type - really should use bt_Void, but this causes the current ecoff GDB to - issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS - 2.0) doesn't understand it, even though the compiler generates it. - Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler - suite, but for now go with what works. */ - -static bt_t map_coff_types[ (int)T_MAX ] = { - bt_Nil, /* T_NULL */ - bt_Nil, /* T_ARG */ - bt_Char, /* T_CHAR */ - bt_Short, /* T_SHORT */ - bt_Int, /* T_INT */ - bt_Long, /* T_LONG */ - bt_Float, /* T_FLOAT */ - bt_Double, /* T_DOUBLE */ - bt_Struct, /* T_STRUCT */ - bt_Union, /* T_UNION */ - bt_Enum, /* T_ENUM */ - bt_Enum, /* T_MOE */ - bt_UChar, /* T_UCHAR */ - bt_UShort, /* T_USHORT */ - bt_UInt, /* T_UINT */ - bt_ULong /* T_ULONG */ -}; - -/* Convert COFF storage class to ECOFF storage class. */ -static sc_t map_coff_storage[ (int)C_MAX ] = { - sc_Nil, /* 0: C_NULL */ - sc_Abs, /* 1: C_AUTO auto var */ - sc_Undefined, /* 2: C_EXT external */ - sc_Data, /* 3: C_STAT static */ - sc_Register, /* 4: C_REG register */ - sc_Undefined, /* 5: C_EXTDEF ??? */ - sc_Text, /* 6: C_LABEL label */ - sc_Text, /* 7: C_ULABEL user label */ - sc_Info, /* 8: C_MOS member of struct */ - sc_Abs, /* 9: C_ARG argument */ - sc_Info, /* 10: C_STRTAG struct tag */ - sc_Info, /* 11: C_MOU member of union */ - sc_Info, /* 12: C_UNTAG union tag */ - sc_Info, /* 13: C_TPDEF typedef */ - sc_Data, /* 14: C_USTATIC ??? */ - sc_Info, /* 15: C_ENTAG enum tag */ - sc_Info, /* 16: C_MOE member of enum */ - sc_Register, /* 17: C_REGPARM register parameter */ - sc_Bits, /* 18; C_FIELD bitfield */ - sc_Nil, /* 19 */ - sc_Nil, /* 20 */ - sc_Nil, /* 21 */ - sc_Nil, /* 22 */ - sc_Nil, /* 23 */ - sc_Nil, /* 24 */ - sc_Nil, /* 25 */ - sc_Nil, /* 26 */ - sc_Nil, /* 27 */ - sc_Nil, /* 28 */ - sc_Nil, /* 29 */ - sc_Nil, /* 30 */ - sc_Nil, /* 31 */ - sc_Nil, /* 32 */ - sc_Nil, /* 33 */ - sc_Nil, /* 34 */ - sc_Nil, /* 35 */ - sc_Nil, /* 36 */ - sc_Nil, /* 37 */ - sc_Nil, /* 38 */ - sc_Nil, /* 39 */ - sc_Nil, /* 40 */ - sc_Nil, /* 41 */ - sc_Nil, /* 42 */ - sc_Nil, /* 43 */ - sc_Nil, /* 44 */ - sc_Nil, /* 45 */ - sc_Nil, /* 46 */ - sc_Nil, /* 47 */ - sc_Nil, /* 48 */ - sc_Nil, /* 49 */ - sc_Nil, /* 50 */ - sc_Nil, /* 51 */ - sc_Nil, /* 52 */ - sc_Nil, /* 53 */ - sc_Nil, /* 54 */ - sc_Nil, /* 55 */ - sc_Nil, /* 56 */ - sc_Nil, /* 57 */ - sc_Nil, /* 58 */ - sc_Nil, /* 59 */ - sc_Nil, /* 60 */ - sc_Nil, /* 61 */ - sc_Nil, /* 62 */ - sc_Nil, /* 63 */ - sc_Nil, /* 64 */ - sc_Nil, /* 65 */ - sc_Nil, /* 66 */ - sc_Nil, /* 67 */ - sc_Nil, /* 68 */ - sc_Nil, /* 69 */ - sc_Nil, /* 70 */ - sc_Nil, /* 71 */ - sc_Nil, /* 72 */ - sc_Nil, /* 73 */ - sc_Nil, /* 74 */ - sc_Nil, /* 75 */ - sc_Nil, /* 76 */ - sc_Nil, /* 77 */ - sc_Nil, /* 78 */ - sc_Nil, /* 79 */ - sc_Nil, /* 80 */ - sc_Nil, /* 81 */ - sc_Nil, /* 82 */ - sc_Nil, /* 83 */ - sc_Nil, /* 84 */ - sc_Nil, /* 85 */ - sc_Nil, /* 86 */ - sc_Nil, /* 87 */ - sc_Nil, /* 88 */ - sc_Nil, /* 89 */ - sc_Nil, /* 90 */ - sc_Nil, /* 91 */ - sc_Nil, /* 92 */ - sc_Nil, /* 93 */ - sc_Nil, /* 94 */ - sc_Nil, /* 95 */ - sc_Nil, /* 96 */ - sc_Nil, /* 97 */ - sc_Nil, /* 98 */ - sc_Nil, /* 99 */ - sc_Text, /* 100: C_BLOCK block start/end */ - sc_Text, /* 101: C_FCN function start/end */ - sc_Info, /* 102: C_EOS end of struct/union/enum */ - sc_Nil, /* 103: C_FILE file start */ - sc_Nil, /* 104: C_LINE line number */ - sc_Nil, /* 105: C_ALIAS combined type info */ - sc_Nil, /* 106: C_HIDDEN ??? */ -}; - -/* Convert COFF storage class to ECOFF symbol type. */ -static st_t map_coff_sym_type[ (int)C_MAX ] = { - st_Nil, /* 0: C_NULL */ - st_Local, /* 1: C_AUTO auto var */ - st_Global, /* 2: C_EXT external */ - st_Static, /* 3: C_STAT static */ - st_Local, /* 4: C_REG register */ - st_Global, /* 5: C_EXTDEF ??? */ - st_Label, /* 6: C_LABEL label */ - st_Label, /* 7: C_ULABEL user label */ - st_Member, /* 8: C_MOS member of struct */ - st_Param, /* 9: C_ARG argument */ - st_Block, /* 10: C_STRTAG struct tag */ - st_Member, /* 11: C_MOU member of union */ - st_Block, /* 12: C_UNTAG union tag */ - st_Typedef, /* 13: C_TPDEF typedef */ - st_Static, /* 14: C_USTATIC ??? */ - st_Block, /* 15: C_ENTAG enum tag */ - st_Member, /* 16: C_MOE member of enum */ - st_Param, /* 17: C_REGPARM register parameter */ - st_Member, /* 18; C_FIELD bitfield */ - st_Nil, /* 19 */ - st_Nil, /* 20 */ - st_Nil, /* 21 */ - st_Nil, /* 22 */ - st_Nil, /* 23 */ - st_Nil, /* 24 */ - st_Nil, /* 25 */ - st_Nil, /* 26 */ - st_Nil, /* 27 */ - st_Nil, /* 28 */ - st_Nil, /* 29 */ - st_Nil, /* 30 */ - st_Nil, /* 31 */ - st_Nil, /* 32 */ - st_Nil, /* 33 */ - st_Nil, /* 34 */ - st_Nil, /* 35 */ - st_Nil, /* 36 */ - st_Nil, /* 37 */ - st_Nil, /* 38 */ - st_Nil, /* 39 */ - st_Nil, /* 40 */ - st_Nil, /* 41 */ - st_Nil, /* 42 */ - st_Nil, /* 43 */ - st_Nil, /* 44 */ - st_Nil, /* 45 */ - st_Nil, /* 46 */ - st_Nil, /* 47 */ - st_Nil, /* 48 */ - st_Nil, /* 49 */ - st_Nil, /* 50 */ - st_Nil, /* 51 */ - st_Nil, /* 52 */ - st_Nil, /* 53 */ - st_Nil, /* 54 */ - st_Nil, /* 55 */ - st_Nil, /* 56 */ - st_Nil, /* 57 */ - st_Nil, /* 58 */ - st_Nil, /* 59 */ - st_Nil, /* 60 */ - st_Nil, /* 61 */ - st_Nil, /* 62 */ - st_Nil, /* 63 */ - st_Nil, /* 64 */ - st_Nil, /* 65 */ - st_Nil, /* 66 */ - st_Nil, /* 67 */ - st_Nil, /* 68 */ - st_Nil, /* 69 */ - st_Nil, /* 70 */ - st_Nil, /* 71 */ - st_Nil, /* 72 */ - st_Nil, /* 73 */ - st_Nil, /* 74 */ - st_Nil, /* 75 */ - st_Nil, /* 76 */ - st_Nil, /* 77 */ - st_Nil, /* 78 */ - st_Nil, /* 79 */ - st_Nil, /* 80 */ - st_Nil, /* 81 */ - st_Nil, /* 82 */ - st_Nil, /* 83 */ - st_Nil, /* 84 */ - st_Nil, /* 85 */ - st_Nil, /* 86 */ - st_Nil, /* 87 */ - st_Nil, /* 88 */ - st_Nil, /* 89 */ - st_Nil, /* 90 */ - st_Nil, /* 91 */ - st_Nil, /* 92 */ - st_Nil, /* 93 */ - st_Nil, /* 94 */ - st_Nil, /* 95 */ - st_Nil, /* 96 */ - st_Nil, /* 97 */ - st_Nil, /* 98 */ - st_Nil, /* 99 */ - st_Block, /* 100: C_BLOCK block start/end */ - st_Proc, /* 101: C_FCN function start/end */ - st_End, /* 102: C_EOS end of struct/union/enum */ - st_File, /* 103: C_FILE file start */ - st_Nil, /* 104: C_LINE line number */ - st_Nil, /* 105: C_ALIAS combined type info */ - st_Nil, /* 106: C_HIDDEN ??? */ -}; - -/* Map COFF derived types to ECOFF type qualifiers. */ -static tq_t map_coff_derived_type[ (int)DT_MAX ] = { - tq_Nil, /* 0: DT_NON no more qualifiers */ - tq_Ptr, /* 1: DT_PTR pointer */ - tq_Proc, /* 2: DT_FCN function */ - tq_Array, /* 3: DT_ARY array */ -}; - - -/* Keep track of different sized allocation requests. */ -static alloc_info_t alloc_counts[ (int)alloc_type_last ]; - - -/* Pointers and such to the original symbol table that is read in. */ -static struct filehdr orig_file_header; /* global object file header */ - -static HDRR orig_sym_hdr; /* symbolic header on input */ -static char *orig_linenum; /* line numbers */ -static DNR *orig_dense; /* dense numbers */ -static PDR *orig_procs; /* procedures */ -static SYMR *orig_local_syms; /* local symbols */ -static OPTR *orig_opt_syms; /* optimization symbols */ -static AUXU *orig_aux_syms; /* auxiliary symbols */ -static char *orig_local_strs; /* local strings */ -static char *orig_ext_strs; /* external strings */ -static FDR *orig_files; /* file descriptors */ -static symint_t *orig_rfds; /* relative file desc's */ -static EXTR *orig_ext_syms; /* external symbols */ - -/* Macros to convert an index into a given object within the original - symbol table. */ -#define CHECK(num,max,str) \ - (((unsigned long)num > (unsigned long)max) ? out_of_bounds (num, max, str, __LINE__) : 0) - -#define ORIG_LINENUM(indx) (CHECK ((indx), orig_sym_hdr.cbLine, "line#"), (indx) + orig_linenum) -#define ORIG_DENSE(indx) (CHECK ((indx), orig_sym_hdr.idnMax, "dense"), (indx) + orig_dense) -#define ORIG_PROCS(indx) (CHECK ((indx), orig_sym_hdr.ipdMax, "procs"), (indx) + orig_procs) -#define ORIG_FILES(indx) (CHECK ((indx), orig_sym_hdr.ifdMax, "funcs"), (indx) + orig_files) -#define ORIG_LSYMS(indx) (CHECK ((indx), orig_sym_hdr.isymMax, "lsyms"), (indx) + orig_local_syms) -#define ORIG_LSTRS(indx) (CHECK ((indx), orig_sym_hdr.issMax, "lstrs"), (indx) + orig_local_strs) -#define ORIG_ESYMS(indx) (CHECK ((indx), orig_sym_hdr.iextMax, "esyms"), (indx) + orig_ext_syms) -#define ORIG_ESTRS(indx) (CHECK ((indx), orig_sym_hdr.issExtMax, "estrs"), (indx) + orig_ext_strs) -#define ORIG_OPT(indx) (CHECK ((indx), orig_sym_hdr.ioptMax, "opt"), (indx) + orig_opt_syms) -#define ORIG_AUX(indx) (CHECK ((indx), orig_sym_hdr.iauxMax, "aux"), (indx) + orig_aux_syms) -#define ORIG_RFDS(indx) (CHECK ((indx), orig_sym_hdr.crfd, "rfds"), (indx) + orig_rfds) - -/* Various other statics. */ -static HDRR symbolic_header; /* symbolic header */ -static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */ -static PDR *cur_proc_ptr = (PDR *) 0; /* current procedure header */ -static SYMR *cur_oproc_begin = (SYMR *) 0; /* original proc. sym begin info */ -static SYMR *cur_oproc_end = (SYMR *) 0; /* original proc. sym end info */ -static PDR *cur_oproc_ptr = (PDR *) 0; /* current original procedure*/ -static thead_t *cur_tag_head = (thead_t *) 0;/* current tag head */ -static long file_offset = 0; /* current file offset */ -static long max_file_offset = 0; /* maximum file offset */ -static FILE *object_stream = (FILE *) 0; /* file desc. to output .o */ -static FILE *obj_in_stream = (FILE *) 0; /* file desc. to input .o */ -static char *progname = (char *) 0; /* program name for errors */ -static const char *input_name = "stdin"; /* name of input file */ -static char *object_name = (char *) 0; /* tmp. name of object file */ -static char *obj_in_name = (char *) 0; /* name of input object file */ -static char *cur_line_start = (char *) 0; /* current line read in */ -static char *cur_line_ptr = (char *) 0; /* ptr within current line */ -static unsigned cur_line_nbytes = 0; /* # bytes for current line */ -static unsigned cur_line_alloc = 0; /* # bytes total in buffer */ -static long line_number = 0; /* current input line number */ -static int debug = 0; /* trace functions */ -static int version = 0; /* print version # */ -static int had_errors = 0; /* != 0 if errors were found */ -static int rename_output = 0; /* != 0 if rename output file*/ -static int delete_input = 0; /* != 0 if delete input after done */ -static int stabs_seen = 0; /* != 0 if stabs have been seen */ - - -/* Pseudo symbol to use when putting stabs into the symbol table. */ -#ifndef STABS_SYMBOL -#define STABS_SYMBOL "@stabs" -#endif - -static char stabs_symbol[] = STABS_SYMBOL; - - -/* Forward reference for functions. See the definition for more details. */ - -#ifndef STATIC -#define STATIC static -#endif - -STATIC int out_of_bounds __proto((symint_t, symint_t, const char *, int)); - -STATIC shash_t *hash_string __proto((const char *, - Ptrdiff_t, - shash_t **, - symint_t *)); - -STATIC symint_t add_string __proto((varray_t *, - shash_t **, - const char *, - const char *, - shash_t **)); - -STATIC symint_t add_local_symbol - __proto((const char *, - const char *, - st_t, - sc_t, - symint_t, - symint_t)); - -STATIC symint_t add_ext_symbol __proto((const char *, - const char *, - st_t, - sc_t, - long, - symint_t, - int)); - -STATIC symint_t add_aux_sym_symint - __proto((symint_t)); - -STATIC symint_t add_aux_sym_rndx - __proto((int, symint_t)); - -STATIC symint_t add_aux_sym_tir __proto((type_info_t *, - hash_state_t, - thash_t **)); - -STATIC tag_t * get_tag __proto((const char *, - const char *, - symint_t, - bt_t)); - -STATIC void add_unknown_tag __proto((tag_t *)); - -STATIC void add_procedure __proto((const char *, - const char *)); - -STATIC void add_file __proto((const char *, - const char *)); - -STATIC void add_bytes __proto((varray_t *, - char *, - Size_t)); - -STATIC void add_varray_page __proto((varray_t *)); - -STATIC void update_headers __proto((void)); - -STATIC void write_varray __proto((varray_t *, off_t, const char *)); -STATIC void write_object __proto((void)); -STATIC const char *st_to_string __proto((st_t)); -STATIC const char *sc_to_string __proto((sc_t)); -STATIC char *read_line __proto((void)); -STATIC void parse_input __proto((void)); -STATIC void mark_stabs __proto((const char *)); -STATIC void parse_begin __proto((const char *)); -STATIC void parse_bend __proto((const char *)); -STATIC void parse_def __proto((const char *)); -STATIC void parse_end __proto((const char *)); -STATIC void parse_ent __proto((const char *)); -STATIC void parse_file __proto((const char *)); -STATIC void parse_stabs_common - __proto((const char *, const char *, const char *)); -STATIC void parse_stabs __proto((const char *)); -STATIC void parse_stabn __proto((const char *)); -STATIC page_t *read_seek __proto((Size_t, off_t, const char *)); -STATIC void copy_object __proto((void)); - -STATIC void catch_signal __proto((int)); -STATIC page_t *allocate_page __proto((void)); - -STATIC page_t *allocate_multiple_pages - __proto((Size_t)); - -STATIC void free_multiple_pages - __proto((page_t *, Size_t)); - -#ifndef MALLOC_CHECK -STATIC page_t *allocate_cluster - __proto((Size_t)); -#endif - -STATIC forward_t *allocate_forward __proto((void)); -STATIC scope_t *allocate_scope __proto((void)); -STATIC shash_t *allocate_shash __proto((void)); -STATIC tag_t *allocate_tag __proto((void)); -STATIC thash_t *allocate_thash __proto((void)); -STATIC thead_t *allocate_thead __proto((void)); -STATIC vlinks_t *allocate_vlinks __proto((void)); - -STATIC void free_forward __proto((forward_t *)); -STATIC void free_scope __proto((scope_t *)); -STATIC void free_tag __proto((tag_t *)); -STATIC void free_thead __proto((thead_t *)); - -STATIC char *local_index __proto((const char *, int)); -STATIC char *local_rindex __proto((const char *, int)); -STATIC const char *my_strsignal __proto((int)); - -extern char *mktemp __proto((char *)); -extern long strtol __proto((const char *, char **, int)); - -extern char *optarg; -extern int optind; -extern int opterr; -extern char *version_string; - -/* List of assembler pseudo ops and beginning sequences that need - special actions. Someday, this should be a hash table, and such, - but for now a linear list of names and calls to memcmp will - do...... */ - -typedef struct _pseudo_ops { - const char *name; /* pseudo-op in ascii */ - int len; /* length of name to compare */ - void (*func) __proto((const char *)); /* function to handle line */ -} pseudo_ops_t; - -static pseudo_ops_t pseudo_ops[] = { - { "#.def", sizeof("#.def")-1, parse_def }, - { "#.begin", sizeof("#.begin")-1, parse_begin }, - { "#.bend", sizeof("#.bend")-1, parse_bend }, - { ".end", sizeof(".end")-1, parse_end }, - { ".ent", sizeof(".ent")-1, parse_ent }, - { ".file", sizeof(".file")-1, parse_file }, - { "#.stabs", sizeof("#.stabs")-1, parse_stabs }, - { "#.stabn", sizeof("#.stabn")-1, parse_stabn }, - { ".stabs", sizeof(".stabs")-1, parse_stabs }, - { ".stabn", sizeof(".stabn")-1, parse_stabn }, - { "#@stabs", sizeof("#@stabs")-1, mark_stabs }, -}; - - -/* Add a page to a varray object. */ - -STATIC void -add_varray_page (vp) - varray_t *vp; /* varray to add page to */ -{ - vlinks_t *new_links = allocate_vlinks (); - -#ifdef MALLOC_CHECK - if (vp->object_size > 1) - new_links->datum = (page_t *) xcalloc (1, vp->object_size); - else -#endif - new_links->datum = allocate_page (); - - alloc_counts[ (int)alloc_type_varray ].total_alloc++; - alloc_counts[ (int)alloc_type_varray ].total_pages++; - - new_links->start_index = vp->num_allocated; - vp->objects_last_page = 0; - - if (vp->first == (vlinks_t *) 0) /* first allocation? */ - vp->first = vp->last = new_links; - else - { /* 2nd or greater allocation */ - new_links->prev = vp->last; - vp->last->next = new_links; - vp->last = new_links; - } -} - - -/* Compute hash code (from tree.c) */ - -#define HASHBITS 30 - -STATIC shash_t * -hash_string (text, hash_len, hash_tbl, ret_hash_index) - const char *text; /* ptr to text to hash */ - Ptrdiff_t hash_len; /* length of the text */ - shash_t **hash_tbl; /* hash table */ - symint_t *ret_hash_index; /* ptr to store hash index */ -{ - register unsigned long hi; - register Ptrdiff_t i; - register shash_t *ptr; - register int first_ch = *text; - - hi = hash_len; - for (i = 0; i < hash_len; i++) - hi = ((hi & 0x003fffff) * 613) + (text[i] & 0xff); - - hi &= (1 << HASHBITS) - 1; - hi %= SHASH_SIZE; - - if (ret_hash_index != (symint_t *) 0) - *ret_hash_index = hi; - - for (ptr = hash_tbl[hi]; ptr != (shash_t *) 0; ptr = ptr->next) - if ((symint_t) hash_len == ptr->len - && first_ch == ptr->string[0] - && memcmp ((CPTR_T) text, (CPTR_T) ptr->string, hash_len) == 0) - break; - - return ptr; -} - - -/* Add a string (and null pad) to one of the string tables. A - consequence of hashing strings, is that we don't let strings - cross page boundaries. The extra nulls will be ignored. */ - -STATIC symint_t -add_string (vp, hash_tbl, start, end_p1, ret_hash) - varray_t *vp; /* string virtual array */ - shash_t **hash_tbl; /* ptr to hash table */ - const char *start; /* 1st byte in string */ - const char *end_p1; /* 1st byte after string */ - shash_t **ret_hash; /* return hash pointer */ -{ - register Ptrdiff_t len = end_p1 - start; - register shash_t *hash_ptr; - symint_t hi; - - if (len >= (Ptrdiff_t) PAGE_USIZE) - fatal ("String too big (%ld bytes)", (long) len); - - hash_ptr = hash_string (start, len, hash_tbl, &hi); - if (hash_ptr == (shash_t *) 0) - { - register char *p; - - if (vp->objects_last_page + len >= (long) PAGE_USIZE) - { - vp->num_allocated - = ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE; - add_varray_page (vp); - } - - hash_ptr = allocate_shash (); - hash_ptr->next = hash_tbl[hi]; - hash_tbl[hi] = hash_ptr; - - hash_ptr->len = len; - hash_ptr->indx = vp->num_allocated; - hash_ptr->string = p = & vp->last->datum->byte[ vp->objects_last_page ]; - - vp->objects_last_page += len+1; - vp->num_allocated += len+1; - - while (len-- > 0) - *p++ = *start++; - - *p = '\0'; - } - - if (ret_hash != (shash_t **) 0) - *ret_hash = hash_ptr; - - return hash_ptr->indx; -} - - -/* Add a local symbol. */ - -STATIC symint_t -add_local_symbol (str_start, str_end_p1, type, storage, value, indx) - const char *str_start; /* first byte in string */ - const char *str_end_p1; /* first byte after string */ - st_t type; /* symbol type */ - sc_t storage; /* storage class */ - symint_t value; /* value of symbol */ - symint_t indx; /* index to local/aux. syms */ -{ - register symint_t ret; - register SYMR *psym; - register scope_t *pscope; - register thead_t *ptag_head; - register tag_t *ptag; - register tag_t *ptag_next; - register varray_t *vp = &cur_file_ptr->symbols; - register int scope_delta = 0; - shash_t *hash_ptr = (shash_t *) 0; - - if (vp->objects_last_page == vp->objects_per_page) - add_varray_page (vp); - - psym = &vp->last->datum->sym[ vp->objects_last_page++ ]; - - psym->value = value; - psym->st = (unsigned) type; - psym->sc = (unsigned) storage; - psym->index = indx; - psym->iss = (str_start == (const char *) 0) - ? 0 - : add_string (&cur_file_ptr->strings, - &cur_file_ptr->shash_head[0], - str_start, - str_end_p1, - &hash_ptr); - - ret = vp->num_allocated++; - - if (MIPS_IS_STAB(psym)) - return ret; - - /* Save the symbol within the hash table if this is a static - item, and it has a name. */ - if (hash_ptr != (shash_t *) 0 - && (type == st_Global || type == st_Static || type == st_Label - || type == st_Proc || type == st_StaticProc)) - hash_ptr->sym_ptr = psym; - - /* push or pop a scope if appropriate. */ - switch (type) - { - default: - break; - - case st_File: /* beginning of file */ - case st_Proc: /* procedure */ - case st_StaticProc: /* static procedure */ - case st_Block: /* begin scope */ - pscope = allocate_scope (); - pscope->prev = cur_file_ptr->cur_scope; - pscope->lsym = psym; - pscope->lnumber = ret; - pscope->type = type; - cur_file_ptr->cur_scope = pscope; - - if (type != st_File) - scope_delta = 1; - - /* For every block type except file, struct, union, or - enumeration blocks, push a level on the tag stack. We omit - file types, so that tags can span file boundaries. */ - if (type != st_File && storage != sc_Info) - { - ptag_head = allocate_thead (); - ptag_head->first_tag = 0; - ptag_head->prev = cur_tag_head; - cur_tag_head = ptag_head; - } - break; - - case st_End: - pscope = cur_file_ptr->cur_scope; - if (pscope == (scope_t *)0) - error ("internal error, too many st_End's"); - - else - { - st_t begin_type = (st_t) pscope->lsym->st; - - if (begin_type != st_File) - scope_delta = -1; - - /* Except for file, structure, union, or enumeration end - blocks remove all tags created within this scope. */ - if (begin_type != st_File && storage != sc_Info) - { - ptag_head = cur_tag_head; - cur_tag_head = ptag_head->prev; - - for (ptag = ptag_head->first_tag; - ptag != (tag_t *) 0; - ptag = ptag_next) - { - if (ptag->forward_ref != (forward_t *) 0) - add_unknown_tag (ptag); - - ptag_next = ptag->same_block; - ptag->hash_ptr->tag_ptr = ptag->same_name; - free_tag (ptag); - } - - free_thead (ptag_head); - } - - cur_file_ptr->cur_scope = pscope->prev; - psym->index = pscope->lnumber; /* blk end gets begin sym # */ - - if (storage != sc_Info) - psym->iss = pscope->lsym->iss; /* blk end gets same name */ - - if (begin_type == st_File || begin_type == st_Block) - pscope->lsym->index = ret+1; /* block begin gets next sym # */ - - /* Functions push two or more aux words as follows: - 1st word: index+1 of the end symbol - 2nd word: type of the function (plus any aux words needed). - Also, tie the external pointer back to the function begin symbol. */ - else - { - symint_t type; - pscope->lsym->index = add_aux_sym_symint (ret+1); - type = add_aux_sym_tir (&last_func_type_info, - hash_no, - &cur_file_ptr->thash_head[0]); - if (last_func_eptr) - { - last_func_eptr->ifd = cur_file_ptr->file_index; - - /* The index for an external st_Proc symbol is the index - of the st_Proc symbol in the local symbol table. */ - last_func_eptr->asym.index = psym->index; - } - } - - free_scope (pscope); - } - } - - cur_file_ptr->nested_scopes += scope_delta; - - if (debug && type != st_File - && (debug > 2 || type == st_Block || type == st_End - || type == st_Proc || type == st_StaticProc)) - { - const char *sc_str = sc_to_string (storage); - const char *st_str = st_to_string (type); - int depth = cur_file_ptr->nested_scopes + (scope_delta < 0); - - fprintf (stderr, - "\tlsym\tv= %10ld, depth= %2d, sc= %-12s", - value, depth, sc_str); - - if (str_start && str_end_p1 - str_start > 0) - fprintf (stderr, " st= %-11s name= %.*s\n", - st_str, (int) (str_end_p1 - str_start), str_start); - else - { - Size_t len = strlen (st_str); - fprintf (stderr, " st= %.*s\n", (int) (len-1), st_str); - } - } - - return ret; -} - - -/* Add an external symbol. */ - -STATIC symint_t -add_ext_symbol (str_start, str_end_p1, type, storage, value, indx, ifd) - const char *str_start; /* first byte in string */ - const char *str_end_p1; /* first byte after string */ - st_t type; /* symbol type */ - sc_t storage; /* storage class */ - long value; /* value of symbol */ - symint_t indx; /* index to local/aux. syms */ - int ifd; /* file index */ -{ - register EXTR *psym; - register varray_t *vp = &ext_symbols; - shash_t *hash_ptr = (shash_t *) 0; - - if (debug > 1) - { - const char *sc_str = sc_to_string (storage); - const char *st_str = st_to_string (type); - - fprintf (stderr, - "\tesym\tv= %10ld, ifd= %2d, sc= %-12s", - value, ifd, sc_str); - - if (str_start && str_end_p1 - str_start > 0) - fprintf (stderr, " st= %-11s name= %.*s\n", - st_str, (int) (str_end_p1 - str_start), str_start); - else - fprintf (stderr, " st= %s\n", st_str); - } - - if (vp->objects_last_page == vp->objects_per_page) - add_varray_page (vp); - - psym = &vp->last->datum->esym[ vp->objects_last_page++ ]; - - psym->ifd = ifd; - psym->asym.value = value; - psym->asym.st = (unsigned) type; - psym->asym.sc = (unsigned) storage; - psym->asym.index = indx; - psym->asym.iss = (str_start == (const char *) 0) - ? 0 - : add_string (&ext_strings, - &ext_str_hash[0], - str_start, - str_end_p1, - &hash_ptr); - - hash_ptr->esym_ptr = psym; - return vp->num_allocated++; -} - - -/* Add an auxiliary symbol (passing a symint). */ - -STATIC symint_t -add_aux_sym_symint (aux_word) - symint_t aux_word; /* auxiliary information word */ -{ - register AUXU *aux_ptr; - register efdr_t *file_ptr = cur_file_ptr; - register varray_t *vp = &file_ptr->aux_syms; - - if (vp->objects_last_page == vp->objects_per_page) - add_varray_page (vp); - - aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ]; - aux_ptr->isym = aux_word; - - return vp->num_allocated++; -} - - -/* Add an auxiliary symbol (passing a file/symbol index combo). */ - -STATIC symint_t -add_aux_sym_rndx (file_index, sym_index) - int file_index; - symint_t sym_index; -{ - register AUXU *aux_ptr; - register efdr_t *file_ptr = cur_file_ptr; - register varray_t *vp = &file_ptr->aux_syms; - - if (vp->objects_last_page == vp->objects_per_page) - add_varray_page (vp); - - aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ]; - aux_ptr->rndx.rfd = file_index; - aux_ptr->rndx.index = sym_index; - - return vp->num_allocated++; -} - - -/* Add an auxiliary symbol (passing the basic type and possibly - type qualifiers). */ - -STATIC symint_t -add_aux_sym_tir (t, state, hash_tbl) - type_info_t *t; /* current type information */ - hash_state_t state; /* whether to hash type or not */ - thash_t **hash_tbl; /* pointer to hash table to use */ -{ - register AUXU *aux_ptr; - register efdr_t *file_ptr = cur_file_ptr; - register varray_t *vp = &file_ptr->aux_syms; - static AUXU init_aux; - symint_t ret; - int i; - AUXU aux; - - aux = init_aux; - aux.ti.bt = (int) t->basic_type; - aux.ti.continued = 0; - aux.ti.fBitfield = t->bitfield; - - aux.ti.tq0 = (int) t->type_qualifiers[0]; - aux.ti.tq1 = (int) t->type_qualifiers[1]; - aux.ti.tq2 = (int) t->type_qualifiers[2]; - aux.ti.tq3 = (int) t->type_qualifiers[3]; - aux.ti.tq4 = (int) t->type_qualifiers[4]; - aux.ti.tq5 = (int) t->type_qualifiers[5]; - - - /* For anything that adds additional information, we must not hash, - so check here, and reset our state. */ - - if (state != hash_no - && (t->type_qualifiers[0] == tq_Array - || t->type_qualifiers[1] == tq_Array - || t->type_qualifiers[2] == tq_Array - || t->type_qualifiers[3] == tq_Array - || t->type_qualifiers[4] == tq_Array - || t->type_qualifiers[5] == tq_Array - || t->basic_type == bt_Struct - || t->basic_type == bt_Union - || t->basic_type == bt_Enum - || t->bitfield - || t->num_dims > 0)) - state = hash_no; - - /* See if we can hash this type, and save some space, but some types - can't be hashed (because they contain arrays or continuations), - and others can be put into the hash list, but cannot use existing - types because other aux entries precede this one. */ - - if (state != hash_no) - { - register thash_t *hash_ptr; - register symint_t hi; - - hi = aux.isym & ((1 << HASHBITS) - 1); - hi %= THASH_SIZE; - - for (hash_ptr = hash_tbl[hi]; - hash_ptr != (thash_t *) 0; - hash_ptr = hash_ptr->next) - { - if (aux.isym == hash_ptr->type.isym) - break; - } - - if (hash_ptr != (thash_t *) 0 && state == hash_yes) - return hash_ptr->indx; - - if (hash_ptr == (thash_t *) 0) - { - hash_ptr = allocate_thash (); - hash_ptr->next = hash_tbl[hi]; - hash_ptr->type = aux; - hash_ptr->indx = vp->num_allocated; - hash_tbl[hi] = hash_ptr; - } - } - - /* Everything is set up, add the aux symbol. */ - if (vp->objects_last_page == vp->objects_per_page) - add_varray_page (vp); - - aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ]; - *aux_ptr = aux; - - ret = vp->num_allocated++; - - /* Add bitfield length if it exists. - - NOTE: Mips documentation claims bitfield goes at the end of the - AUX record, but the DECstation compiler emits it here. - (This would only make a difference for enum bitfields.) - - Also note: We use the last size given since gcc may emit 2 - for an enum bitfield. */ - - if (t->bitfield) - (void) add_aux_sym_symint ((symint_t)t->sizes[t->num_sizes-1]); - - - /* Add tag information if needed. Structure, union, and enum - references add 2 aux symbols: a [file index, symbol index] - pointer to the structure type, and the current file index. */ - - if (t->basic_type == bt_Struct - || t->basic_type == bt_Union - || t->basic_type == bt_Enum) - { - register symint_t file_index = t->tag_ptr->ifd; - register symint_t sym_index = t->tag_ptr->indx; - - if (t->unknown_tag) - { - (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index); - (void) add_aux_sym_symint ((symint_t)-1); - } - else if (sym_index != indexNil) - { - (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index); - (void) add_aux_sym_symint (file_index); - } - else - { - register forward_t *forward_ref = allocate_forward (); - - forward_ref->type_ptr = aux_ptr; - forward_ref->next = t->tag_ptr->forward_ref; - t->tag_ptr->forward_ref = forward_ref; - - (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index); - forward_ref->index_ptr - = &vp->last->datum->aux[ vp->objects_last_page - 1]; - - (void) add_aux_sym_symint (file_index); - forward_ref->ifd_ptr - = &vp->last->datum->aux[ vp->objects_last_page - 1]; - } - } - - /* Add information about array bounds if they exist. */ - for (i = 0; i < t->num_dims; i++) - { - (void) add_aux_sym_rndx (ST_RFDESCAPE, - cur_file_ptr->int_type); - - (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/ - (void) add_aux_sym_symint ((symint_t) 0); /* low bound */ - (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/ - (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */ - ? 0 - : (t->sizes[i] * 8) / t->dimensions[i]); - }; - - /* NOTE: Mips documentation claims that the bitfield width goes here. - But it needs to be emitted earlier. */ - - return ret; -} - - -/* Add a tag to the tag table (unless it already exists). */ - -STATIC tag_t * -get_tag (tag_start, tag_end_p1, indx, basic_type) - const char *tag_start; /* 1st byte of tag name */ - const char *tag_end_p1; /* 1st byte after tag name */ - symint_t indx; /* index of tag start block */ - bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */ -{ - shash_t *hash_ptr; - tag_t *tag_ptr; - hash_ptr = hash_string (tag_start, - tag_end_p1 - tag_start, - &tag_hash[0], - (symint_t *) 0); - - if (hash_ptr != (shash_t *) 0 - && hash_ptr->tag_ptr != (tag_t *) 0) - { - tag_ptr = hash_ptr->tag_ptr; - if (indx != indexNil) - { - tag_ptr->basic_type = basic_type; - tag_ptr->ifd = cur_file_ptr->file_index; - tag_ptr->indx = indx; - } - return tag_ptr; - } - - (void) add_string (&tag_strings, - &tag_hash[0], - tag_start, - tag_end_p1, - &hash_ptr); - - tag_ptr = allocate_tag (); - tag_ptr->forward_ref = (forward_t *) 0; - tag_ptr->hash_ptr = hash_ptr; - tag_ptr->same_name = hash_ptr->tag_ptr; - tag_ptr->basic_type = basic_type; - tag_ptr->indx = indx; - tag_ptr->ifd = (indx == indexNil) ? -1 : cur_file_ptr->file_index; - tag_ptr->same_block = cur_tag_head->first_tag; - - cur_tag_head->first_tag = tag_ptr; - hash_ptr->tag_ptr = tag_ptr; - - return tag_ptr; -} - - -/* Add an unknown {struct, union, enum} tag. */ - -STATIC void -add_unknown_tag (ptag) - tag_t *ptag; /* pointer to tag information */ -{ - shash_t *hash_ptr = ptag->hash_ptr; - char *name_start = hash_ptr->string; - char *name_end_p1 = name_start + hash_ptr->len; - forward_t *f_next = ptag->forward_ref; - forward_t *f_cur; - int sym_index; - int file_index = cur_file_ptr->file_index; - - if (debug > 1) - { - const char *agg_type = "{unknown aggregate type}"; - switch (ptag->basic_type) - { - case bt_Struct: agg_type = "struct"; break; - case bt_Union: agg_type = "union"; break; - case bt_Enum: agg_type = "enum"; break; - default: break; - } - - fprintf (stderr, "unknown %s %.*s found\n", - agg_type, (int) hash_ptr->len, name_start); - } - - sym_index = add_local_symbol (name_start, - name_end_p1, - st_Block, - sc_Info, - (symint_t) 0, - (symint_t) 0); - - (void) add_local_symbol (name_start, - name_end_p1, - st_End, - sc_Info, - (symint_t) 0, - (symint_t) 0); - - while (f_next != (forward_t *) 0) - { - f_cur = f_next; - f_next = f_next->next; - - f_cur->ifd_ptr->isym = file_index; - f_cur->index_ptr->rndx.index = sym_index; - - free_forward (f_cur); - } - - return; -} - - -/* Add a procedure to the current file's list of procedures, and record - this is the current procedure. If the assembler created a PDR for - this procedure, use that to initialize the current PDR. */ - -STATIC void -add_procedure (func_start, func_end_p1) - const char *func_start; /* 1st byte of func name */ - const char *func_end_p1; /* 1st byte after func name */ -{ - register PDR *new_proc_ptr; - register efdr_t *file_ptr = cur_file_ptr; - register varray_t *vp = &file_ptr->procs; - register symint_t value = 0; - register st_t proc_type = st_Proc; - register shash_t *shash_ptr = hash_string (func_start, - func_end_p1 - func_start, - &orig_str_hash[0], - (symint_t *) 0); - - if (debug) - fputc ('\n', stderr); - - if (vp->objects_last_page == vp->objects_per_page) - add_varray_page (vp); - - cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[ vp->objects_last_page++ ]; - - vp->num_allocated++; - - - /* Did the assembler create this procedure? If so, get the PDR information. */ - cur_oproc_ptr = (PDR *) 0; - if (shash_ptr != (shash_t *) 0) - { - register PDR *old_proc_ptr = shash_ptr->proc_ptr; - register SYMR *sym_ptr = shash_ptr->sym_ptr; - - if (old_proc_ptr != (PDR *) 0 - && sym_ptr != (SYMR *) 0 - && ((st_t)sym_ptr->st == st_Proc || (st_t)sym_ptr->st == st_StaticProc)) - { - cur_oproc_begin = sym_ptr; - cur_oproc_end = shash_ptr->end_ptr; - value = sym_ptr->value; - - cur_oproc_ptr = old_proc_ptr; - proc_type = (st_t)sym_ptr->st; - *new_proc_ptr = *old_proc_ptr; /* initialize */ - } - } - - if (cur_oproc_ptr == (PDR *) 0) - error ("Did not find a PDR block for %.*s", - (int) (func_end_p1 - func_start), func_start); - - /* Determine the start of symbols. */ - new_proc_ptr->isym = file_ptr->symbols.num_allocated; - - /* Push the start of the function. */ - (void) add_local_symbol (func_start, func_end_p1, - proc_type, sc_Text, - value, - (symint_t) 0); -} - - -/* Add a new filename, and set up all of the file relative - virtual arrays (strings, symbols, aux syms, etc.). Record - where the current file structure lives. */ - -STATIC void -add_file (file_start, file_end_p1) - const char *file_start; /* first byte in string */ - const char *file_end_p1; /* first byte after string */ -{ - static char zero_bytes[2] = { '\0', '\0' }; - - register Ptrdiff_t len = file_end_p1 - file_start; - register int first_ch = *file_start; - register efdr_t *file_ptr; - - if (debug) - fprintf (stderr, "\tfile\t%.*s\n", (int) len, file_start); - - /* See if the file has already been created. */ - for (file_ptr = first_file; - file_ptr != (efdr_t *) 0; - file_ptr = file_ptr->next_file) - { - if (first_ch == file_ptr->name[0] - && file_ptr->name[len] == '\0' - && memcmp ((CPTR_T) file_start, (CPTR_T) file_ptr->name, len) == 0) - { - cur_file_ptr = file_ptr; - break; - } - } - - /* If this is a new file, create it. */ - if (file_ptr == (efdr_t *) 0) - { - if (file_desc.objects_last_page == file_desc.objects_per_page) - add_varray_page (&file_desc); - - file_ptr = cur_file_ptr - = &file_desc.last->datum->file[ file_desc.objects_last_page++ ]; - *file_ptr = init_file; - - file_ptr->file_index = file_desc.num_allocated++; - - /* Allocate the string hash table. */ - file_ptr->shash_head = (shash_t **) allocate_page (); - - /* Make sure 0 byte in string table is null */ - add_string (&file_ptr->strings, - &file_ptr->shash_head[0], - &zero_bytes[0], - &zero_bytes[0], - (shash_t **) 0); - - if (file_end_p1 - file_start > (long) PAGE_USIZE-2) - fatal ("Filename goes over one page boundary."); - - /* Push the start of the filename. We assume that the filename - will be stored at string offset 1. */ - (void) add_local_symbol (file_start, file_end_p1, st_File, sc_Text, - (symint_t) 0, (symint_t) 0); - file_ptr->fdr.rss = 1; - file_ptr->name = &file_ptr->strings.last->datum->byte[1]; - file_ptr->name_len = file_end_p1 - file_start; - - /* Update the linked list of file descriptors. */ - *last_file_ptr = file_ptr; - last_file_ptr = &file_ptr->next_file; - - /* Add void & int types to the file (void should be first to catch - errant 0's within the index fields). */ - file_ptr->void_type = add_aux_sym_tir (&void_type_info, - hash_yes, - &cur_file_ptr->thash_head[0]); - - file_ptr->int_type = add_aux_sym_tir (&int_type_info, - hash_yes, - &cur_file_ptr->thash_head[0]); - } -} - - -/* Add a stream of random bytes to a varray. */ - -STATIC void -add_bytes (vp, input_ptr, nitems) - varray_t *vp; /* virtual array to add too */ - char *input_ptr; /* start of the bytes */ - Size_t nitems; /* # items to move */ -{ - register Size_t move_items; - register Size_t move_bytes; - register char *ptr; - - while (nitems > 0) - { - if (vp->objects_last_page >= vp->objects_per_page) - add_varray_page (vp); - - ptr = &vp->last->datum->byte[ vp->objects_last_page * vp->object_size ]; - move_items = vp->objects_per_page - vp->objects_last_page; - if (move_items > nitems) - move_items = nitems; - - move_bytes = move_items * vp->object_size; - nitems -= move_items; - - if (move_bytes >= 32) - { - (void) memcpy ((PTR_T) ptr, (CPTR_T) input_ptr, move_bytes); - input_ptr += move_bytes; - } - else - { - while (move_bytes-- > 0) - *ptr++ = *input_ptr++; - } - } -} - - -/* Convert storage class to string. */ - -STATIC const char * -sc_to_string(storage_class) - sc_t storage_class; -{ - switch(storage_class) - { - case sc_Nil: return "Nil,"; - case sc_Text: return "Text,"; - case sc_Data: return "Data,"; - case sc_Bss: return "Bss,"; - case sc_Register: return "Register,"; - case sc_Abs: return "Abs,"; - case sc_Undefined: return "Undefined,"; - case sc_CdbLocal: return "CdbLocal,"; - case sc_Bits: return "Bits,"; - case sc_CdbSystem: return "CdbSystem,"; - case sc_RegImage: return "RegImage,"; - case sc_Info: return "Info,"; - case sc_UserStruct: return "UserStruct,"; - case sc_SData: return "SData,"; - case sc_SBss: return "SBss,"; - case sc_RData: return "RData,"; - case sc_Var: return "Var,"; - case sc_Common: return "Common,"; - case sc_SCommon: return "SCommon,"; - case sc_VarRegister: return "VarRegister,"; - case sc_Variant: return "Variant,"; - case sc_SUndefined: return "SUndefined,"; - case sc_Init: return "Init,"; - case sc_Max: return "Max,"; - } - - return "???,"; -} - - -/* Convert symbol type to string. */ - -STATIC const char * -st_to_string(symbol_type) - st_t symbol_type; -{ - switch(symbol_type) - { - case st_Nil: return "Nil,"; - case st_Global: return "Global,"; - case st_Static: return "Static,"; - case st_Param: return "Param,"; - case st_Local: return "Local,"; - case st_Label: return "Label,"; - case st_Proc: return "Proc,"; - case st_Block: return "Block,"; - case st_End: return "End,"; - case st_Member: return "Member,"; - case st_Typedef: return "Typedef,"; - case st_File: return "File,"; - case st_RegReloc: return "RegReloc,"; - case st_Forward: return "Forward,"; - case st_StaticProc: return "StaticProc,"; - case st_Constant: return "Constant,"; - case st_Str: return "String,"; - case st_Number: return "Number,"; - case st_Expr: return "Expr,"; - case st_Type: return "Type,"; - case st_Max: return "Max,"; - } - - return "???,"; -} - - -/* Read a line from standard input, and return the start of the buffer - (which is grows if the line is too big). We split lines at the - semi-colon, and return each logical line independently. */ - -STATIC char * -read_line __proto((void)) -{ - static int line_split_p = 0; - register int string_p = 0; - register int comment_p = 0; - register int ch; - register char *ptr; - - if (cur_line_start == (char *) 0) - { /* allocate initial page */ - cur_line_start = (char *) allocate_page (); - cur_line_alloc = PAGE_SIZE; - } - - if (!line_split_p) - line_number++; - - line_split_p = 0; - cur_line_nbytes = 0; - - for (ptr = cur_line_start; (ch = getchar ()) != EOF; *ptr++ = ch) - { - if (++cur_line_nbytes >= cur_line_alloc-1) - { - register int num_pages = cur_line_alloc / PAGE_SIZE; - register char *old_buffer = cur_line_start; - - cur_line_alloc += PAGE_SIZE; - cur_line_start = (char *) allocate_multiple_pages (num_pages+1); - memcpy (cur_line_start, old_buffer, num_pages * PAGE_SIZE); - - ptr = cur_line_start + cur_line_nbytes - 1; - } - - if (ch == '\n') - { - *ptr++ = '\n'; - *ptr = '\0'; - cur_line_ptr = cur_line_start; - return cur_line_ptr; - } - - else if (ch == '\0') - error ("Null character found in input"); - - else if (!comment_p) - { - if (ch == '"') - string_p = !string_p; - - else if (ch == '#') - comment_p++; - - else if (ch == ';' && !string_p) - { - line_split_p = 1; - *ptr++ = '\n'; - *ptr = '\0'; - cur_line_ptr = cur_line_start; - return cur_line_ptr; - } - } - } - - if (ferror (stdin)) - pfatal_with_name (input_name); - - cur_line_ptr = (char *) 0; - return (char *) 0; -} - - -/* Parse #.begin directives which have a label as the first argument - which gives the location of the start of the block. */ - -STATIC void -parse_begin (start) - const char *start; /* start of directive */ -{ - const char *end_p1; /* end of label */ - int ch; - shash_t *hash_ptr; /* hash pointer to lookup label */ - - if (cur_file_ptr == (efdr_t *) 0) - { - error ("#.begin directive without a preceding .file directive"); - return; - } - - if (cur_proc_ptr == (PDR *) 0) - { - error ("#.begin directive without a preceding .ent directive"); - return; - } - - for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++) - ; - - hash_ptr = hash_string (start, - end_p1 - start, - &orig_str_hash[0], - (symint_t *) 0); - - if (hash_ptr == (shash_t *) 0) - { - error ("Label %.*s not found for #.begin", - (int) (end_p1 - start), start); - return; - } - - if (cur_oproc_begin == (SYMR *) 0) - { - error ("Procedure table %.*s not found for #.begin", - (int) (end_p1 - start), start); - return; - } - - (void) add_local_symbol ((const char *) 0, (const char *) 0, - st_Block, sc_Text, - (symint_t) hash_ptr->sym_ptr->value - cur_oproc_begin->value, - (symint_t) 0); -} - - -/* Parse #.bend directives which have a label as the first argument - which gives the location of the end of the block. */ - -STATIC void -parse_bend (start) - const char *start; /* start of directive */ -{ - const char *end_p1; /* end of label */ - int ch; - shash_t *hash_ptr; /* hash pointer to lookup label */ - - if (cur_file_ptr == (efdr_t *) 0) - { - error ("#.begin directive without a preceding .file directive"); - return; - } - - if (cur_proc_ptr == (PDR *) 0) - { - error ("#.bend directive without a preceding .ent directive"); - return; - } - - for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++) - ; - - hash_ptr = hash_string (start, - end_p1 - start, - &orig_str_hash[0], - (symint_t *) 0); - - if (hash_ptr == (shash_t *) 0) - { - error ("Label %.*s not found for #.bend", (int) (end_p1 - start), start); - return; - } - - if (cur_oproc_begin == (SYMR *) 0) - { - error ("Procedure table %.*s not found for #.bend", - (int) (end_p1 - start), start); - return; - } - - (void) add_local_symbol ((const char *) 0, (const char *) 0, - st_End, sc_Text, - (symint_t)hash_ptr->sym_ptr->value - cur_oproc_begin->value, - (symint_t) 0); -} - - -/* Parse #.def directives, which are contain standard COFF subdirectives - to describe the debugging format. These subdirectives include: - - .scl specify storage class - .val specify a value - .endef specify end of COFF directives - .type specify the type - .size specify the size of an array - .dim specify an array dimension - .tag specify a tag for a struct, union, or enum. */ - -STATIC void -parse_def (name_start) - const char *name_start; /* start of directive */ -{ - const char *dir_start; /* start of current directive*/ - const char *dir_end_p1; /* end+1 of current directive*/ - const char *arg_start; /* start of current argument */ - const char *arg_end_p1; /* end+1 of current argument */ - const char *name_end_p1; /* end+1 of label */ - const char *tag_start = (const char *) 0; /* start of tag name */ - const char *tag_end_p1 = (const char *) 0; /* end+1 of tag name */ - sc_t storage_class = sc_Nil; - st_t symbol_type = st_Nil; - type_info_t t; - EXTR *eptr = (EXTR *) 0; /* ext. sym equivalent to def*/ - int is_function = 0; /* != 0 if function */ - symint_t value = 0; - symint_t indx = cur_file_ptr->void_type; - int error_line = 0; - symint_t arg_number; - symint_t temp_array[ N_TQ ]; - int arg_was_number; - int ch, i; - Ptrdiff_t len; - - static int inside_enumeration = 0; /* is this an enumeration? */ - - - /* Initialize the type information. */ - t = type_info_init; - - - /* Search for the end of the name being defined. */ - /* Allow spaces and such in names for G++ templates, which produce stabs - that look like: - - #.def SMANIP<long unsigned int>; .scl 10; .type 0x8; .size 8; .endef */ - - for (name_end_p1 = name_start; (ch = *name_end_p1) != ';' && ch != '\0'; name_end_p1++) - ; - - if (ch == '\0') - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - /* Parse the remaining subdirectives now. */ - dir_start = name_end_p1+1; - for (;;) - { - while ((ch = *dir_start) == ' ' || ch == '\t') - ++dir_start; - - if (ch != '.') - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - /* Are we done? */ - if (dir_start[1] == 'e' - && memcmp (dir_start, ".endef", sizeof (".endef")-1) == 0) - break; - - /* Pick up the subdirective now */ - for (dir_end_p1 = dir_start+1; - (ch = *dir_end_p1) != ' ' && ch != '\t'; - dir_end_p1++) - { - if (ch == '\0' || ISSPACE (ch)) - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - } - - /* Pick up the subdirective argument now. */ - arg_was_number = arg_number = 0; - arg_end_p1 = (const char *) 0; - arg_start = dir_end_p1+1; - ch = *arg_start; - while (ch == ' ' || ch == '\t') - ch = *++arg_start; - - if (ISDIGIT (ch) || ch == '-' || ch == '+') - { - int ch2; - arg_number = strtol (arg_start, (char **) &arg_end_p1, 0); - if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',') - arg_was_number++; - } - - else if (ch == '\0' || ISSPACE (ch)) - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - if (!arg_was_number) - { - /* Allow spaces and such in names for G++ templates. */ - for (arg_end_p1 = arg_start+1; - (ch = *arg_end_p1) != ';' && ch != '\0'; - arg_end_p1++) - ; - - if (ch == '\0') - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - } - - /* Classify the directives now. */ - len = dir_end_p1 - dir_start; - switch (dir_start[1]) - { - default: - error_line = __LINE__; - saber_stop (); - goto bomb_out; - - case 'd': - if (len == sizeof (".dim")-1 - && memcmp (dir_start, ".dim", sizeof (".dim")-1) == 0 - && arg_was_number) - { - symint_t *t_ptr = &temp_array[ N_TQ-1 ]; - - *t_ptr = arg_number; - while (*arg_end_p1 == ',' && arg_was_number) - { - arg_start = arg_end_p1+1; - ch = *arg_start; - while (ch == ' ' || ch == '\t') - ch = *++arg_start; - - arg_was_number = 0; - if (ISDIGIT (ch) || ch == '-' || ch == '+') - { - int ch2; - arg_number = strtol (arg_start, (char **) &arg_end_p1, 0); - if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',') - arg_was_number++; - - if (t_ptr == &temp_array[0]) - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - *--t_ptr = arg_number; - } - } - - /* Reverse order of dimensions. */ - while (t_ptr <= &temp_array[ N_TQ-1 ]) - { - if (t.num_dims >= N_TQ-1) - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - t.dimensions[ t.num_dims++ ] = *t_ptr++; - } - break; - } - else - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - - case 's': - if (len == sizeof (".scl")-1 - && memcmp (dir_start, ".scl", sizeof (".scl")-1) == 0 - && arg_was_number - && arg_number < ((symint_t) C_MAX)) - { - /* If the symbol is a static or external, we have - already gotten the appropriate type and class, so - make sure we don't override those values. This is - needed because there are some type and classes that - are not in COFF, such as short data, etc. */ - if (symbol_type == st_Nil) - { - symbol_type = map_coff_sym_type[arg_number]; - storage_class = map_coff_storage [arg_number]; - } - break; - } - - else if (len == sizeof (".size")-1 - && memcmp (dir_start, ".size", sizeof (".size")-1) == 0 - && arg_was_number) - { - symint_t *t_ptr = &temp_array[ N_TQ-1 ]; - - *t_ptr = arg_number; - while (*arg_end_p1 == ',' && arg_was_number) - { - arg_start = arg_end_p1+1; - ch = *arg_start; - while (ch == ' ' || ch == '\t') - ch = *++arg_start; - - arg_was_number = 0; - if (ISDIGIT (ch) || ch == '-' || ch == '+') - { - int ch2; - arg_number = strtol (arg_start, (char **) &arg_end_p1, 0); - if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',') - arg_was_number++; - - if (t_ptr == &temp_array[0]) - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - *--t_ptr = arg_number; - } - } - - /* Reverse order of sizes. */ - while (t_ptr <= &temp_array[ N_TQ-1 ]) - { - if (t.num_sizes >= N_TQ-1) - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - t.sizes[ t.num_sizes++ ] = *t_ptr++; - } - break; - } - - else - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - - case 't': - if (len == sizeof (".type")-1 - && memcmp (dir_start, ".type", sizeof (".type")-1) == 0 - && arg_was_number) - { - tq_t *tq_ptr = &t.type_qualifiers[0]; - - t.orig_type = (coff_type_t) (arg_number & N_BTMASK); - t.basic_type = map_coff_types [(int)t.orig_type]; - for (i = N_TQ-1; i >= 0; i--) - { - int dt = (arg_number >> ((i * N_TQ_SHIFT) + N_BT_SHIFT) - & N_TMASK); - - if (dt != (int)DT_NON) - *tq_ptr++ = map_coff_derived_type [dt]; - } - - /* If this is a function, ignore it, so that we don't get - two entries (one from the .ent, and one for the .def - that precedes it). Save the type information so that - the end block can properly add it after the begin block - index. For MIPS knows what reason, we must strip off - the function type at this point. */ - if (tq_ptr != &t.type_qualifiers[0] && tq_ptr[-1] == tq_Proc) - { - is_function = 1; - tq_ptr[-1] = tq_Nil; - } - - break; - } - - else if (len == sizeof (".tag")-1 - && memcmp (dir_start, ".tag", sizeof (".tag")-1) == 0) - { - tag_start = arg_start; - tag_end_p1 = arg_end_p1; - break; - } - - else - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - - case 'v': - if (len == sizeof (".val")-1 - && memcmp (dir_start, ".val", sizeof (".val")-1) == 0) - { - if (arg_was_number) - value = arg_number; - - /* If the value is not an integer value, it must be the - name of a static or global item. Look up the name in - the original symbol table to pick up the storage - class, symbol type, etc. */ - else - { - shash_t *orig_hash_ptr; /* hash within orig sym table*/ - shash_t *ext_hash_ptr; /* hash within ext. sym table*/ - - ext_hash_ptr = hash_string (arg_start, - arg_end_p1 - arg_start, - &ext_str_hash[0], - (symint_t *) 0); - - if (ext_hash_ptr != (shash_t *) 0 - && ext_hash_ptr->esym_ptr != (EXTR *) 0) - eptr = ext_hash_ptr->esym_ptr; - - orig_hash_ptr = hash_string (arg_start, - arg_end_p1 - arg_start, - &orig_str_hash[0], - (symint_t *) 0); - - if ((orig_hash_ptr == (shash_t *) 0 - || orig_hash_ptr->sym_ptr == (SYMR *) 0) - && eptr == (EXTR *) 0) - { - fprintf (stderr, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n", - (int) (arg_end_p1 - arg_start), - arg_start); - value = 0; - } - else - { - SYMR *ptr = (orig_hash_ptr != (shash_t *) 0 - && orig_hash_ptr->sym_ptr != (SYMR *) 0) - ? orig_hash_ptr->sym_ptr - : &eptr->asym; - - symbol_type = (st_t) ptr->st; - storage_class = (sc_t) ptr->sc; - value = ptr->value; - } - } - break; - } - else - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - } - - /* Set up to find next directive. */ - dir_start = arg_end_p1 + 1; - } - - - if (storage_class == sc_Bits) - { - t.bitfield = 1; - t.extra_sizes = 1; - } - else - t.extra_sizes = 0; - - if (t.num_dims > 0) - { - int num_real_sizes = t.num_sizes - t.extra_sizes; - int diff = t.num_dims - num_real_sizes; - int i = t.num_dims - 1; - int j; - - if (num_real_sizes != 1 || diff < 0) - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - /* If this is an array, make sure the same number of dimensions - and sizes were passed, creating extra sizes for multiply - dimensioned arrays if not passed. */ - - if (diff) - { - for (j = (sizeof (t.sizes) / sizeof (t.sizes[0])) - 1; j >= 0; j--) - t.sizes[ j ] = ((j-diff) >= 0) ? t.sizes[ j-diff ] : 0; - - t.num_sizes = i + 1; - for ( i--; i >= 0; i-- ) - { - if (t.dimensions[ i+1 ]) - t.sizes[ i ] = t.sizes[ i+1 ] / t.dimensions[ i+1 ]; - else - t.sizes[ i ] = t.sizes[ i+1 ]; - } - } - } - - /* Except for enumeration members & begin/ending of scopes, put the - type word in the aux. symbol table. */ - - if (symbol_type == st_Block || symbol_type == st_End) - indx = 0; - - else if (inside_enumeration) - indx = cur_file_ptr->void_type; - - else - { - if (t.basic_type == bt_Struct - || t.basic_type == bt_Union - || t.basic_type == bt_Enum) - { - if (tag_start == (char *) 0) - { - error ("No tag specified for %.*s", - (int) (name_end_p1 - name_start), - name_start); - return; - } - - t.tag_ptr = get_tag (tag_start, tag_end_p1, (symint_t)indexNil, - t.basic_type); - } - - if (is_function) - { - last_func_type_info = t; - last_func_eptr = eptr; - return; - } - - indx = add_aux_sym_tir (&t, - hash_yes, - &cur_file_ptr->thash_head[0]); - } - - - /* If this is an external or static symbol, update the appropriate - external symbol. */ - - if (eptr != (EXTR *) 0 - && (eptr->asym.index == indexNil || cur_proc_ptr == (PDR *) 0)) - { - eptr->ifd = cur_file_ptr->file_index; - eptr->asym.index = indx; - } - - - /* Do any last minute adjustments that are necessary. */ - switch (symbol_type) - { - default: - break; - - - /* For the beginning of structs, unions, and enumerations, the - size info needs to be passed in the value field. */ - - case st_Block: - if (t.num_sizes - t.num_dims - t.extra_sizes != 1) - { - error_line = __LINE__; - saber_stop (); - goto bomb_out; - } - - else - value = t.sizes[0]; - - inside_enumeration = (t.orig_type == T_ENUM); - break; - - - /* For the end of structs, unions, and enumerations, omit the - name which is always ".eos". This needs to be done last, so - that any error reporting above gives the correct name. */ - - case st_End: - name_start = name_end_p1 = (const char *) 0; - value = inside_enumeration = 0; - break; - - - /* Members of structures and unions that aren't bitfields, need - to adjust the value from a byte offset to a bit offset. - Members of enumerations do not have the value adjusted, and - can be distinguished by indx == indexNil. For enumerations, - update the maximum enumeration value. */ - - case st_Member: - if (!t.bitfield && !inside_enumeration) - value *= 8; - - break; - } - - - /* Add the symbol, except for global symbols outside of functions, - for which the external symbol table is fine enough. */ - - if (eptr == (EXTR *) 0 - || eptr->asym.st == (int)st_Nil - || cur_proc_ptr != (PDR *) 0) - { - symint_t isym = add_local_symbol (name_start, name_end_p1, - symbol_type, storage_class, - value, - indx); - - /* deal with struct, union, and enum tags. */ - if (symbol_type == st_Block) - { - /* Create or update the tag information. */ - tag_t *tag_ptr = get_tag (name_start, - name_end_p1, - isym, - t.basic_type); - - /* If there are any forward references, fill in the appropriate - file and symbol indexes. */ - - symint_t file_index = cur_file_ptr->file_index; - forward_t *f_next = tag_ptr->forward_ref; - forward_t *f_cur; - - while (f_next != (forward_t *) 0) - { - f_cur = f_next; - f_next = f_next->next; - - f_cur->ifd_ptr->isym = file_index; - f_cur->index_ptr->rndx.index = isym; - - free_forward (f_cur); - } - - tag_ptr->forward_ref = (forward_t *) 0; - } - } - - /* Normal return */ - return; - - /* Error return, issue message. */ -bomb_out: - if (error_line) - error ("compiler error, badly formed #.def (internal line # = %d)", error_line); - else - error ("compiler error, badly formed #.def"); - - return; -} - - -/* Parse .end directives. */ - -STATIC void -parse_end (start) - const char *start; /* start of directive */ -{ - register const char *start_func, *end_func_p1; - register int ch; - register symint_t value; - register FDR *orig_fdr; - - if (cur_file_ptr == (efdr_t *) 0) - { - error (".end directive without a preceding .file directive"); - return; - } - - if (cur_proc_ptr == (PDR *) 0) - { - error (".end directive without a preceding .ent directive"); - return; - } - - /* Get the function name, skipping whitespace. */ - for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++) - ; - - ch = *start_func; - if (!IS_ASM_IDENT (ch)) - { - error (".end directive has no name"); - return; - } - - for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1) - ; - - - /* Get the value field for creating the end from the original object - file (which we find by locating the procedure start, and using the - pointer to the end+1 block and backing up. The index points to a - two word aux. symbol, whose first word is the index of the end - symbol, and the second word is the type of the function return - value. */ - - orig_fdr = cur_file_ptr->orig_fdr; - value = 0; - if (orig_fdr != (FDR *)0 && cur_oproc_end != (SYMR *) 0) - value = cur_oproc_end->value; - - else - error ("Cannot find .end block for %.*s", - (int) (end_func_p1 - start_func), start_func); - - (void) add_local_symbol (start_func, end_func_p1, - st_End, sc_Text, - value, - (symint_t) 0); - - cur_proc_ptr = cur_oproc_ptr = (PDR *) 0; -} - - -/* Parse .ent directives. */ - -STATIC void -parse_ent (start) - const char *start; /* start of directive */ -{ - register const char *start_func, *end_func_p1; - register int ch; - - if (cur_file_ptr == (efdr_t *) 0) - { - error (".ent directive without a preceding .file directive"); - return; - } - - if (cur_proc_ptr != (PDR *) 0) - { - error ("second .ent directive found before .end directive"); - return; - } - - for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++) - ; - - ch = *start_func; - if (!IS_ASM_IDENT (ch)) - { - error (".ent directive has no name"); - return; - } - - for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1) - ; - - (void) add_procedure (start_func, end_func_p1); -} - - -/* Parse .file directives. */ - -STATIC void -parse_file (start) - const char *start; /* start of directive */ -{ - char *p; - register char *start_name, *end_name_p1; - - (void) strtol (start, &p, 0); - if (start == p - || (start_name = local_index (p, '"')) == (char *) 0 - || (end_name_p1 = local_rindex (++start_name, '"')) == (char *) 0) - { - error ("Invalid .file directive"); - return; - } - - if (cur_proc_ptr != (PDR *) 0) - { - error ("No way to handle .file within .ent/.end section"); - return; - } - - add_file (start_name, end_name_p1); -} - - -/* Make sure the @stabs symbol is emitted. */ - -static void -mark_stabs (start) - const char *start ATTRIBUTE_UNUSED; /* Start of directive (ignored) */ -{ - if (!stabs_seen) - { - /* Add a dummy @stabs symbol. */ - stabs_seen = 1; - (void) add_local_symbol (stabs_symbol, - stabs_symbol + sizeof (stabs_symbol), - stNil, scInfo, -1, MIPS_MARK_STAB(0)); - - } -} - - -/* Parse .stabs directives. - - .stabs directives have five fields: - "string" a string, encoding the type information. - code a numeric code, defined in <stab.h> - 0 a zero - 0 a zero or line number - value a numeric value or an address. - - If the value is relocatable, we transform this into: - iss points as an index into string space - value value from lookup of the name - st st from lookup of the name - sc sc from lookup of the name - index code|CODE_MASK - - If the value is not relocatable, we transform this into: - iss points as an index into string space - value value - st st_Nil - sc sc_Nil - index code|CODE_MASK - - .stabn directives have four fields (string is null): - code a numeric code, defined in <stab.h> - 0 a zero - 0 a zero or a line number - value a numeric value or an address. */ - -STATIC void -parse_stabs_common (string_start, string_end, rest) - const char *string_start; /* start of string or NULL */ - const char *string_end; /* end+1 of string or NULL */ - const char *rest; /* rest of the directive. */ -{ - efdr_t *save_file_ptr = cur_file_ptr; - symint_t code; - symint_t value; - char *p; - st_t st; - sc_t sc; - int ch; - - if (stabs_seen == 0) - mark_stabs (""); - - /* Read code from stabs. */ - if (!ISDIGIT (*rest)) - { - error ("Invalid .stabs/.stabn directive, code is non-numeric"); - return; - } - - code = strtol (rest, &p, 0); - - /* Line number stabs are handled differently, since they have two values, - the line number and the address of the label. We use the index field - (aka code) to hold the line number, and the value field to hold the - address. The symbol type is st_Label, which should be different from - the other stabs, so that gdb can recognize it. */ - - if (code == (int)N_SLINE) - { - SYMR *sym_ptr, dummy_symr; - shash_t *shash_ptr; - - /* Skip ,0, */ - if (p[0] != ',' || p[1] != '0' || p[2] != ',' || !ISDIGIT (p[3])) - { - error ("Invalid line number .stabs/.stabn directive"); - return; - } - - code = strtol (p+3, &p, 0); - ch = *++p; - if (p[-1] != ',' || ISDIGIT (ch) || !IS_ASM_IDENT (ch)) - { - error ("Invalid line number .stabs/.stabn directive"); - return; - } - - dummy_symr.index = code; - if (dummy_symr.index != code) - { - error ("Line number (%lu) for .stabs/.stabn directive cannot fit in index field (20 bits)", - code); - - return; - } - - shash_ptr = hash_string (p, - strlen (p) - 1, - &orig_str_hash[0], - (symint_t *) 0); - - if (shash_ptr == (shash_t *) 0 - || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0) - { - error ("Invalid .stabs/.stabn directive, value not found"); - return; - } - - if ((st_t) sym_ptr->st != st_Label) - { - error ("Invalid line number .stabs/.stabn directive"); - return; - } - - st = st_Label; - sc = (sc_t) sym_ptr->sc; - value = sym_ptr->value; - } - else - { - /* Skip ,<num>,<num>, */ - if (*p++ != ',') - goto failure; - for (; ISDIGIT (*p); p++) - ; - if (*p++ != ',') - goto failure; - for (; ISDIGIT (*p); p++) - ; - if (*p++ != ',') - goto failure; - ch = *p; - if (!IS_ASM_IDENT (ch) && ch != '-') - { - failure: - error ("Invalid .stabs/.stabn directive, bad character"); - return; - } - - if (ISDIGIT (ch) || ch == '-') - { - st = st_Nil; - sc = sc_Nil; - value = strtol (p, &p, 0); - if (*p != '\n') - { - error ("Invalid .stabs/.stabn directive, stuff after numeric value"); - return; - } - } - else if (!IS_ASM_IDENT (ch)) - { - error ("Invalid .stabs/.stabn directive, bad character"); - return; - } - else - { - SYMR *sym_ptr; - shash_t *shash_ptr; - const char *start, *end_p1; - - start = p; - if ((end_p1 = strchr (start, '+')) == (char *) 0) - { - if ((end_p1 = strchr (start, '-')) == (char *) 0) - end_p1 = start + strlen(start) - 1; - } - - shash_ptr = hash_string (start, - end_p1 - start, - &orig_str_hash[0], - (symint_t *) 0); - - if (shash_ptr == (shash_t *) 0 - || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0) - { - shash_ptr = hash_string (start, - end_p1 - start, - &ext_str_hash[0], - (symint_t *) 0); - - if (shash_ptr == (shash_t *) 0 - || shash_ptr->esym_ptr == (EXTR *) 0) - { - error ("Invalid .stabs/.stabn directive, value not found"); - return; - } - else - sym_ptr = &(shash_ptr->esym_ptr->asym); - } - - /* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */ - if (code == (int) N_LBRAC || code == (int) N_RBRAC) - { - sc = scNil; - st = stNil; - } - else - { - sc = (sc_t) sym_ptr->sc; - st = (st_t) sym_ptr->st; - } - value = sym_ptr->value; - - ch = *end_p1++; - if (ch != '\n') - { - if (((!ISDIGIT (*end_p1)) && (*end_p1 != '-')) - || ((ch != '+') && (ch != '-'))) - { - error ("Invalid .stabs/.stabn directive, badly formed value"); - return; - } - if (ch == '+') - value += strtol (end_p1, &p, 0); - else if (ch == '-') - value -= strtol (end_p1, &p, 0); - - if (*p != '\n') - { - error ("Invalid .stabs/.stabn directive, stuff after numeric value"); - return; - } - } - } - code = MIPS_MARK_STAB(code); - } - - (void) add_local_symbol (string_start, string_end, st, sc, value, code); - /* Restore normal file type. */ - cur_file_ptr = save_file_ptr; -} - - -STATIC void -parse_stabs (start) - const char *start; /* start of directive */ -{ - const char *end = local_index (start+1, '"'); - - if (*start != '"' || end == (const char *) 0 || end[1] != ',') - { - error ("Invalid .stabs directive, no string"); - return; - } - - parse_stabs_common (start+1, end, end+2); -} - - -STATIC void -parse_stabn (start) - const char *start; /* start of directive */ -{ - parse_stabs_common ((const char *) 0, (const char *) 0, start); -} - - -/* Parse the input file, and write the lines to the output file - if needed. */ - -STATIC void -parse_input __proto((void)) -{ - register char *p; - register Size_t i; - register thead_t *ptag_head; - register tag_t *ptag; - register tag_t *ptag_next; - - if (debug) - fprintf (stderr, "\tinput\n"); - - /* Add a dummy scope block around the entire compilation unit for - structures defined outside of blocks. */ - ptag_head = allocate_thead (); - ptag_head->first_tag = 0; - ptag_head->prev = cur_tag_head; - cur_tag_head = ptag_head; - - while ((p = read_line ()) != (char *) 0) - { - /* Skip leading blanks */ - while (ISSPACE ((unsigned char)*p)) - p++; - - /* See if it's a directive we handle. If so, dispatch handler. */ - for (i = 0; i < sizeof (pseudo_ops) / sizeof (pseudo_ops[0]); i++) - if (memcmp (p, pseudo_ops[i].name, pseudo_ops[i].len) == 0 - && ISSPACE ((unsigned char)(p[pseudo_ops[i].len]))) - { - p += pseudo_ops[i].len; /* skip to first argument */ - while (ISSPACE ((unsigned char)*p)) - p++; - - (*pseudo_ops[i].func)( p ); - break; - } - } - - /* Process any tags at global level. */ - ptag_head = cur_tag_head; - cur_tag_head = ptag_head->prev; - - for (ptag = ptag_head->first_tag; - ptag != (tag_t *) 0; - ptag = ptag_next) - { - if (ptag->forward_ref != (forward_t *) 0) - add_unknown_tag (ptag); - - ptag_next = ptag->same_block; - ptag->hash_ptr->tag_ptr = ptag->same_name; - free_tag (ptag); - } - - free_thead (ptag_head); - -} - - -/* Update the global headers with the final offsets in preparation - to write out the .T file. */ - -STATIC void -update_headers __proto((void)) -{ - register symint_t i; - register efdr_t *file_ptr; - - /* Set up the symbolic header. */ - file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr; - symbolic_header.magic = orig_sym_hdr.magic; - symbolic_header.vstamp = orig_sym_hdr.vstamp; - - /* Set up global counts. */ - symbolic_header.issExtMax = ext_strings.num_allocated; - symbolic_header.idnMax = dense_num.num_allocated; - symbolic_header.ifdMax = file_desc.num_allocated; - symbolic_header.iextMax = ext_symbols.num_allocated; - symbolic_header.ilineMax = orig_sym_hdr.ilineMax; - symbolic_header.ioptMax = orig_sym_hdr.ioptMax; - symbolic_header.cbLine = orig_sym_hdr.cbLine; - symbolic_header.crfd = orig_sym_hdr.crfd; - - - /* Loop through each file, figuring out how many local syms, - line numbers, etc. there are. Also, put out end symbol - for the filename. */ - - for (file_ptr = first_file; - file_ptr != (efdr_t *) 0; - file_ptr = file_ptr->next_file) - { - register SYMR *sym_start; - register SYMR *sym; - register SYMR *sym_end_p1; - register FDR *fd_ptr = file_ptr->orig_fdr; - - cur_file_ptr = file_ptr; - - /* Copy st_Static symbols from the original local symbol table if - they did not get added to the new local symbol table. - This happens with stabs-in-ecoff or if the source file is - compiled without debugging. */ - sym_start = ORIG_LSYMS (fd_ptr->isymBase); - sym_end_p1 = sym_start + fd_ptr->csym; - for (sym = sym_start; sym < sym_end_p1; sym++) - { - if ((st_t)sym->st == st_Static) - { - register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss); - register Size_t len = strlen (str); - register shash_t *hash_ptr; - - /* Ignore internal labels. */ - if (str[0] == '$' && str[1] == 'L') - continue; - hash_ptr = hash_string (str, - (Ptrdiff_t)len, - &file_ptr->shash_head[0], - (symint_t *) 0); - if (hash_ptr == (shash_t *) 0) - { - (void) add_local_symbol (str, str + len, - (st_t)sym->st, (sc_t)sym->sc, - (symint_t)sym->value, - (symint_t)indexNil); - } - } - } - (void) add_local_symbol ((const char *) 0, (const char *) 0, - st_End, sc_Text, - (symint_t) 0, - (symint_t) 0); - - file_ptr->fdr.cpd = file_ptr->procs.num_allocated; - file_ptr->fdr.ipdFirst = symbolic_header.ipdMax; - symbolic_header.ipdMax += file_ptr->fdr.cpd; - - file_ptr->fdr.csym = file_ptr->symbols.num_allocated; - file_ptr->fdr.isymBase = symbolic_header.isymMax; - symbolic_header.isymMax += file_ptr->fdr.csym; - - file_ptr->fdr.caux = file_ptr->aux_syms.num_allocated; - file_ptr->fdr.iauxBase = symbolic_header.iauxMax; - symbolic_header.iauxMax += file_ptr->fdr.caux; - - file_ptr->fdr.cbSs = file_ptr->strings.num_allocated; - file_ptr->fdr.issBase = symbolic_header.issMax; - symbolic_header.issMax += file_ptr->fdr.cbSs; - } - -#ifndef ALIGN_SYMTABLE_OFFSET -#define ALIGN_SYMTABLE_OFFSET(OFFSET) (OFFSET) -#endif - - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - i = WORD_ALIGN (symbolic_header.cbLine); /* line numbers */ - if (i > 0) - { - symbolic_header.cbLineOffset = file_offset; - file_offset += i; - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = symbolic_header.ioptMax; /* optimization symbols */ - if (((long) i) > 0) - { - symbolic_header.cbOptOffset = file_offset; - file_offset += i * sizeof (OPTR); - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = symbolic_header.idnMax; /* dense numbers */ - if (i > 0) - { - symbolic_header.cbDnOffset = file_offset; - file_offset += i * sizeof (DNR); - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = symbolic_header.ipdMax; /* procedure tables */ - if (i > 0) - { - symbolic_header.cbPdOffset = file_offset; - file_offset += i * sizeof (PDR); - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = symbolic_header.isymMax; /* local symbols */ - if (i > 0) - { - symbolic_header.cbSymOffset = file_offset; - file_offset += i * sizeof (SYMR); - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = symbolic_header.iauxMax; /* aux syms. */ - if (i > 0) - { - symbolic_header.cbAuxOffset = file_offset; - file_offset += i * sizeof (TIR); - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = WORD_ALIGN (symbolic_header.issMax); /* local strings */ - if (i > 0) - { - symbolic_header.cbSsOffset = file_offset; - file_offset += i; - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = WORD_ALIGN (symbolic_header.issExtMax); /* external strings */ - if (i > 0) - { - symbolic_header.cbSsExtOffset = file_offset; - file_offset += i; - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = symbolic_header.ifdMax; /* file tables */ - if (i > 0) - { - symbolic_header.cbFdOffset = file_offset; - file_offset += i * sizeof (FDR); - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = symbolic_header.crfd; /* relative file descriptors */ - if (i > 0) - { - symbolic_header.cbRfdOffset = file_offset; - file_offset += i * sizeof (symint_t); - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } - - i = symbolic_header.iextMax; /* external symbols */ - if (i > 0) - { - symbolic_header.cbExtOffset = file_offset; - file_offset += i * sizeof (EXTR); - file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); - } -} - - -/* Write out a varray at a given location. */ - -STATIC void -write_varray (vp, offset, str) - varray_t *vp; /* virtual array */ - off_t offset; /* offset to write varray to */ - const char *str; /* string to print out when tracing */ -{ - int num_write, sys_write; - vlinks_t *ptr; - - if (vp->num_allocated == 0) - return; - - if (debug) - { - fputs ("\twarray\tvp = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, vp); - fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n", - (unsigned long) offset, vp->num_allocated * vp->object_size, str); - } - - if (file_offset != offset - && fseek (object_stream, (long)offset, SEEK_SET) < 0) - pfatal_with_name (object_name); - - for (ptr = vp->first; ptr != (vlinks_t *) 0; ptr = ptr->next) - { - num_write = (ptr->next == (vlinks_t *) 0) - ? vp->objects_last_page * vp->object_size - : vp->objects_per_page * vp->object_size; - - sys_write = fwrite ((PTR_T) ptr->datum, 1, num_write, object_stream); - if (sys_write <= 0) - pfatal_with_name (object_name); - - else if (sys_write != num_write) - fatal ("Wrote %d bytes to %s, system returned %d", - num_write, - object_name, - sys_write); - - file_offset += num_write; - } -} - - -/* Write out the symbol table in the object file. */ - -STATIC void -write_object __proto((void)) -{ - int sys_write; - efdr_t *file_ptr; - off_t offset; - - if (debug) - { - fputs ("\n\twrite\tvp = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &symbolic_header); - fprintf (stderr, ", offset = %7u, size = %7lu, %s\n", - 0, (unsigned long) sizeof (symbolic_header), "symbolic header"); - } - - sys_write = fwrite ((PTR_T) &symbolic_header, - 1, - sizeof (symbolic_header), - object_stream); - - if (sys_write < 0) - pfatal_with_name (object_name); - - else if (sys_write != sizeof (symbolic_header)) - fatal ("Wrote %d bytes to %s, system returned %d", - (int) sizeof (symbolic_header), - object_name, - sys_write); - - - file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr; - - if (symbolic_header.cbLine > 0) /* line numbers */ - { - long sys_write; - - if (file_offset != symbolic_header.cbLineOffset - && fseek (object_stream, symbolic_header.cbLineOffset, SEEK_SET) != 0) - pfatal_with_name (object_name); - - if (debug) - { - fputs ("\twrite\tvp = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &orig_linenum); - fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n", - (long) symbolic_header.cbLineOffset, - (long) symbolic_header.cbLine, "Line numbers"); - } - - sys_write = fwrite ((PTR_T) orig_linenum, - 1, - symbolic_header.cbLine, - object_stream); - - if (sys_write <= 0) - pfatal_with_name (object_name); - - else if (sys_write != symbolic_header.cbLine) - fatal ("Wrote %ld bytes to %s, system returned %ld", - (long) symbolic_header.cbLine, - object_name, - sys_write); - - file_offset = symbolic_header.cbLineOffset + symbolic_header.cbLine; - } - - if (symbolic_header.ioptMax > 0) /* optimization symbols */ - { - long sys_write; - long num_write = symbolic_header.ioptMax * sizeof (OPTR); - - if (file_offset != symbolic_header.cbOptOffset - && fseek (object_stream, symbolic_header.cbOptOffset, SEEK_SET) != 0) - pfatal_with_name (object_name); - - if (debug) - { - fputs ("\twrite\tvp = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &orig_opt_syms); - fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n", - (long) symbolic_header.cbOptOffset, - num_write, "Optimizer symbols"); - } - - sys_write = fwrite ((PTR_T) orig_opt_syms, - 1, - num_write, - object_stream); - - if (sys_write <= 0) - pfatal_with_name (object_name); - - else if (sys_write != num_write) - fatal ("Wrote %ld bytes to %s, system returned %ld", - num_write, - object_name, - sys_write); - - file_offset = symbolic_header.cbOptOffset + num_write; - } - - if (symbolic_header.idnMax > 0) /* dense numbers */ - write_varray (&dense_num, (off_t)symbolic_header.cbDnOffset, "Dense numbers"); - - if (symbolic_header.ipdMax > 0) /* procedure tables */ - { - offset = symbolic_header.cbPdOffset; - for (file_ptr = first_file; - file_ptr != (efdr_t *) 0; - file_ptr = file_ptr->next_file) - { - write_varray (&file_ptr->procs, offset, "Procedure tables"); - offset = file_offset; - } - } - - if (symbolic_header.isymMax > 0) /* local symbols */ - { - offset = symbolic_header.cbSymOffset; - for (file_ptr = first_file; - file_ptr != (efdr_t *) 0; - file_ptr = file_ptr->next_file) - { - write_varray (&file_ptr->symbols, offset, "Local symbols"); - offset = file_offset; - } - } - - if (symbolic_header.iauxMax > 0) /* aux symbols */ - { - offset = symbolic_header.cbAuxOffset; - for (file_ptr = first_file; - file_ptr != (efdr_t *) 0; - file_ptr = file_ptr->next_file) - { - write_varray (&file_ptr->aux_syms, offset, "Aux. symbols"); - offset = file_offset; - } - } - - if (symbolic_header.issMax > 0) /* local strings */ - { - offset = symbolic_header.cbSsOffset; - for (file_ptr = first_file; - file_ptr != (efdr_t *) 0; - file_ptr = file_ptr->next_file) - { - write_varray (&file_ptr->strings, offset, "Local strings"); - offset = file_offset; - } - } - - if (symbolic_header.issExtMax > 0) /* external strings */ - write_varray (&ext_strings, symbolic_header.cbSsExtOffset, "External strings"); - - if (symbolic_header.ifdMax > 0) /* file tables */ - { - offset = symbolic_header.cbFdOffset; - if (file_offset != offset - && fseek (object_stream, (long)offset, SEEK_SET) < 0) - pfatal_with_name (object_name); - - file_offset = offset; - for (file_ptr = first_file; - file_ptr != (efdr_t *) 0; - file_ptr = file_ptr->next_file) - { - if (debug) - { - fputs ("\twrite\tvp = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &file_ptr->fdr); - fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n", - file_offset, (unsigned long) sizeof (FDR), - "File header"); - } - - sys_write = fwrite (&file_ptr->fdr, - 1, - sizeof (FDR), - object_stream); - - if (sys_write < 0) - pfatal_with_name (object_name); - - else if (sys_write != sizeof (FDR)) - fatal ("Wrote %d bytes to %s, system returned %d", - (int) sizeof (FDR), - object_name, - sys_write); - - file_offset = offset += sizeof (FDR); - } - } - - if (symbolic_header.crfd > 0) /* relative file descriptors */ - { - long sys_write; - symint_t num_write = symbolic_header.crfd * sizeof (symint_t); - - if (file_offset != symbolic_header.cbRfdOffset - && fseek (object_stream, symbolic_header.cbRfdOffset, SEEK_SET) != 0) - pfatal_with_name (object_name); - - if (debug) - { - fputs ("\twrite\tvp = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &orig_rfds); - fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n", - (long) symbolic_header.cbRfdOffset, - num_write, "Relative file descriptors"); - } - - sys_write = fwrite (orig_rfds, - 1, - num_write, - object_stream); - - if (sys_write <= 0) - pfatal_with_name (object_name); - - else if (sys_write != (long)num_write) - fatal ("Wrote %lu bytes to %s, system returned %ld", - num_write, - object_name, - sys_write); - - file_offset = symbolic_header.cbRfdOffset + num_write; - } - - if (symbolic_header.issExtMax > 0) /* external symbols */ - write_varray (&ext_symbols, (off_t)symbolic_header.cbExtOffset, "External symbols"); - - if (fclose (object_stream) != 0) - pfatal_with_name (object_name); -} - - -/* Read some bytes at a specified location, and return a pointer. */ - -STATIC page_t * -read_seek (size, offset, str) - Size_t size; /* # bytes to read */ - off_t offset; /* offset to read at */ - const char *str; /* name for tracing */ -{ - page_t *ptr; - long sys_read = 0; - - if (size == 0) /* nothing to read */ - return (page_t *) 0; - - if (debug) - fprintf (stderr, - "\trseek\tsize = %7lu, offset = %7lu, currently at %7lu, %s\n", - (unsigned long) size, (unsigned long) offset, file_offset, str); - -#ifndef MALLOC_CHECK - ptr = allocate_multiple_pages ((size + PAGE_USIZE - 1) / PAGE_USIZE); -#else - ptr = (page_t *) xcalloc (1, size); -#endif - - /* If we need to seek, and the distance is nearby, just do some reads, - to speed things up. */ - if (file_offset != offset) - { - symint_t difference = offset - file_offset; - - if (difference < 8) - { - char small_buffer[8]; - - sys_read = fread (small_buffer, 1, difference, obj_in_stream); - if (sys_read <= 0) - pfatal_with_name (obj_in_name); - - if ((symint_t)sys_read != difference) - fatal ("Wanted to read %lu bytes from %s, system returned %ld", - (unsigned long) size, - obj_in_name, - sys_read); - } - else if (fseek (obj_in_stream, offset, SEEK_SET) < 0) - pfatal_with_name (obj_in_name); - } - - sys_read = fread ((PTR_T)ptr, 1, size, obj_in_stream); - if (sys_read <= 0) - pfatal_with_name (obj_in_name); - - if (sys_read != (long) size) - fatal ("Wanted to read %lu bytes from %s, system returned %ld", - (unsigned long) size, - obj_in_name, - sys_read); - - file_offset = offset + size; - - if (file_offset > max_file_offset) - max_file_offset = file_offset; - - return ptr; -} - - -/* Read the existing object file (and copy to the output object file - if it is different from the input object file), and remove the old - symbol table. */ - -STATIC void -copy_object __proto((void)) -{ - char buffer[ PAGE_SIZE ]; - register int sys_read; - register int remaining; - register int num_write; - register int sys_write; - register int fd, es; - register int delete_ifd = 0; - register int *remap_file_number; - struct stat stat_buf; - - if (debug) - fprintf (stderr, "\tcopy\n"); - - if (fstat (fileno (obj_in_stream), &stat_buf) != 0 - || fseek (obj_in_stream, 0L, SEEK_SET) != 0) - pfatal_with_name (obj_in_name); - - sys_read = fread ((PTR_T) &orig_file_header, - 1, - sizeof (struct filehdr), - obj_in_stream); - - if (sys_read < 0) - pfatal_with_name (obj_in_name); - - else if (sys_read == 0 && feof (obj_in_stream)) - return; /* create a .T file sans file header */ - - else if (sys_read < (int) sizeof (struct filehdr)) - fatal ("Wanted to read %d bytes from %s, system returned %d", - (int) sizeof (struct filehdr), - obj_in_name, - sys_read); - - - if (orig_file_header.f_nsyms != sizeof (HDRR)) - fatal ("%s symbolic header wrong size (%d bytes, should be %d)", - input_name, orig_file_header.f_nsyms, (int) sizeof (HDRR)); - - - /* Read in the current symbolic header. */ - if (fseek (obj_in_stream, (long) orig_file_header.f_symptr, SEEK_SET) != 0) - pfatal_with_name (input_name); - - sys_read = fread ((PTR_T) &orig_sym_hdr, - 1, - sizeof (orig_sym_hdr), - obj_in_stream); - - if (sys_read < 0) - pfatal_with_name (object_name); - - else if (sys_read < (int) sizeof (struct filehdr)) - fatal ("Wanted to read %d bytes from %s, system returned %d", - (int) sizeof (struct filehdr), - obj_in_name, - sys_read); - - - /* Read in each of the sections if they exist in the object file. - We read things in in the order the mips assembler creates the - sections, so in theory no extra seeks are done. - - For simplicity sake, round each read up to a page boundary, - we may want to revisit this later.... */ - - file_offset = orig_file_header.f_symptr + sizeof (struct filehdr); - - if (orig_sym_hdr.cbLine > 0) /* line numbers */ - orig_linenum = (char *) read_seek ((Size_t)orig_sym_hdr.cbLine, - orig_sym_hdr.cbLineOffset, - "Line numbers"); - - if (orig_sym_hdr.ipdMax > 0) /* procedure tables */ - orig_procs = (PDR *) read_seek ((Size_t)orig_sym_hdr.ipdMax * sizeof (PDR), - orig_sym_hdr.cbPdOffset, - "Procedure tables"); - - if (orig_sym_hdr.isymMax > 0) /* local symbols */ - orig_local_syms = (SYMR *) read_seek ((Size_t)orig_sym_hdr.isymMax * sizeof (SYMR), - orig_sym_hdr.cbSymOffset, - "Local symbols"); - - if (orig_sym_hdr.iauxMax > 0) /* aux symbols */ - orig_aux_syms = (AUXU *) read_seek ((Size_t)orig_sym_hdr.iauxMax * sizeof (AUXU), - orig_sym_hdr.cbAuxOffset, - "Aux. symbols"); - - if (orig_sym_hdr.issMax > 0) /* local strings */ - orig_local_strs = (char *) read_seek ((Size_t)orig_sym_hdr.issMax, - orig_sym_hdr.cbSsOffset, - "Local strings"); - - if (orig_sym_hdr.issExtMax > 0) /* external strings */ - orig_ext_strs = (char *) read_seek ((Size_t)orig_sym_hdr.issExtMax, - orig_sym_hdr.cbSsExtOffset, - "External strings"); - - if (orig_sym_hdr.ifdMax > 0) /* file tables */ - orig_files = (FDR *) read_seek ((Size_t)orig_sym_hdr.ifdMax * sizeof (FDR), - orig_sym_hdr.cbFdOffset, - "File tables"); - - if (orig_sym_hdr.crfd > 0) /* relative file descriptors */ - orig_rfds = (symint_t *) read_seek ((Size_t)orig_sym_hdr.crfd * sizeof (symint_t), - orig_sym_hdr.cbRfdOffset, - "Relative file descriptors"); - - if (orig_sym_hdr.issExtMax > 0) /* external symbols */ - orig_ext_syms = (EXTR *) read_seek ((Size_t)orig_sym_hdr.iextMax * sizeof (EXTR), - orig_sym_hdr.cbExtOffset, - "External symbols"); - - if (orig_sym_hdr.idnMax > 0) /* dense numbers */ - { - orig_dense = (DNR *) read_seek ((Size_t)orig_sym_hdr.idnMax * sizeof (DNR), - orig_sym_hdr.cbDnOffset, - "Dense numbers"); - - add_bytes (&dense_num, (char *) orig_dense, (Size_t)orig_sym_hdr.idnMax); - } - - if (orig_sym_hdr.ioptMax > 0) /* opt symbols */ - orig_opt_syms = (OPTR *) read_seek ((Size_t)orig_sym_hdr.ioptMax * sizeof (OPTR), - orig_sym_hdr.cbOptOffset, - "Optimizer symbols"); - - - - /* Abort if the symbol table is not last. */ - if (max_file_offset != stat_buf.st_size) - fatal ("Symbol table is not last (symbol table ends at %ld, .o ends at %ld", - max_file_offset, - stat_buf.st_size); - - - /* If the first original file descriptor is a dummy which the assembler - put out, but there are no symbols in it, skip it now. */ - if (orig_sym_hdr.ifdMax > 1 - && orig_files->csym == 2 - && orig_files->caux == 0) - { - char *filename = orig_local_strs + (orig_files->issBase + orig_files->rss); - char *suffix = local_rindex (filename, '.'); - - if (suffix != (char *) 0 && strcmp (suffix, ".s") == 0) - delete_ifd = 1; - } - - - /* Create array to map original file numbers to the new file numbers - (in case there are duplicate filenames, we collapse them into one - file section, the MIPS assembler may or may not collapse them). */ - - remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax); - - for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++) - { - register FDR *fd_ptr = ORIG_FILES (fd); - register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss); - - /* file support itself. */ - add_file (filename, filename + strlen (filename)); - remap_file_number[fd] = cur_file_ptr->file_index; - } - - if (delete_ifd > 0) /* just in case */ - remap_file_number[0] = remap_file_number[1]; - - - /* Loop, adding each of the external symbols. These must be in - order or otherwise we would have to change the relocation - entries. We don't just call add_bytes, because we need to have - the names put into the external hash table. We set the type to - 'void' for now, and parse_def will fill in the correct type if it - is in the symbol table. We must add the external symbols before - the locals, since the locals do lookups against the externals. */ - - if (debug) - fprintf (stderr, "\tehash\n"); - - for (es = 0; es < orig_sym_hdr.iextMax; es++) - { - register EXTR *eptr = orig_ext_syms + es; - register char *ename = ORIG_ESTRS (eptr->asym.iss); - register unsigned ifd = eptr->ifd; - - (void) add_ext_symbol (ename, - ename + strlen (ename), - (st_t) eptr->asym.st, - (sc_t) eptr->asym.sc, - eptr->asym.value, - (symint_t) ((eptr->asym.index == indexNil) ? indexNil : 0), - ((long) ifd < orig_sym_hdr.ifdMax) ? remap_file_number[ ifd ] : ifd); - } - - - /* For each of the files in the object file, copy the symbols, and such - into the varrays for the new object file. */ - - for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++) - { - register FDR *fd_ptr = ORIG_FILES (fd); - register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss); - register SYMR *sym_start; - register SYMR *sym; - register SYMR *sym_end_p1; - register PDR *proc_start; - register PDR *proc; - register PDR *proc_end_p1; - - /* file support itself. */ - add_file (filename, filename + strlen (filename)); - cur_file_ptr->orig_fdr = fd_ptr; - - /* Copy stuff that's just passed through (such as line #'s) */ - cur_file_ptr->fdr.adr = fd_ptr->adr; - cur_file_ptr->fdr.ilineBase = fd_ptr->ilineBase; - cur_file_ptr->fdr.cline = fd_ptr->cline; - cur_file_ptr->fdr.rfdBase = fd_ptr->rfdBase; - cur_file_ptr->fdr.crfd = fd_ptr->crfd; - cur_file_ptr->fdr.cbLineOffset = fd_ptr->cbLineOffset; - cur_file_ptr->fdr.cbLine = fd_ptr->cbLine; - cur_file_ptr->fdr.fMerge = fd_ptr->fMerge; - cur_file_ptr->fdr.fReadin = fd_ptr->fReadin; - cur_file_ptr->fdr.glevel = fd_ptr->glevel; - - if (debug) - fprintf (stderr, "\thash\tstart, filename %s\n", filename); - - /* For each of the static and global symbols defined, add them - to the hash table of original symbols, so we can look up - their values. */ - - sym_start = ORIG_LSYMS (fd_ptr->isymBase); - sym_end_p1 = sym_start + fd_ptr->csym; - for (sym = sym_start; sym < sym_end_p1; sym++) - { - switch ((st_t) sym->st) - { - default: - break; - - case st_Global: - case st_Static: - case st_Label: - case st_Proc: - case st_StaticProc: - { - auto symint_t hash_index; - register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss); - register Size_t len = strlen (str); - register shash_t *shash_ptr = hash_string (str, - (Ptrdiff_t)len, - &orig_str_hash[0], - &hash_index); - - if (shash_ptr != (shash_t *) 0) - error ("internal error, %s is already in original symbol table", str); - - else - { - shash_ptr = allocate_shash (); - shash_ptr->next = orig_str_hash[hash_index]; - orig_str_hash[hash_index] = shash_ptr; - - shash_ptr->len = len; - shash_ptr->indx = indexNil; - shash_ptr->string = str; - shash_ptr->sym_ptr = sym; - } - } - break; - - case st_End: - if ((sc_t) sym->sc == sc_Text) - { - register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss); - - if (*str != '\0') - { - register Size_t len = strlen (str); - register shash_t *shash_ptr = hash_string (str, - (Ptrdiff_t)len, - &orig_str_hash[0], - (symint_t *) 0); - - if (shash_ptr != (shash_t *) 0) - shash_ptr->end_ptr = sym; - } - } - break; - - } - } - - if (debug) - { - fprintf (stderr, "\thash\tdone, filename %s\n", filename); - fprintf (stderr, "\tproc\tstart, filename %s\n", filename); - } - - /* Go through each of the procedures in this file, and add the - procedure pointer to the hash entry for the given name. */ - - proc_start = ORIG_PROCS (fd_ptr->ipdFirst); - proc_end_p1 = proc_start + fd_ptr->cpd; - for (proc = proc_start; proc < proc_end_p1; proc++) - { - register SYMR *proc_sym = ORIG_LSYMS (fd_ptr->isymBase + proc->isym); - register char *str = ORIG_LSTRS (fd_ptr->issBase + proc_sym->iss); - register Size_t len = strlen (str); - register shash_t *shash_ptr = hash_string (str, - (Ptrdiff_t)len, - &orig_str_hash[0], - (symint_t *) 0); - - if (shash_ptr == (shash_t *) 0) - error ("internal error, function %s is not in original symbol table", str); - - else - shash_ptr->proc_ptr = proc; - } - - if (debug) - fprintf (stderr, "\tproc\tdone, filename %s\n", filename); - - } - cur_file_ptr = first_file; - - - /* Copy all of the object file up to the symbol table. Originally - we were going to use ftruncate, but that doesn't seem to work - on Ultrix 3.1.... */ - - if (fseek (obj_in_stream, (long) 0, SEEK_SET) != 0) - pfatal_with_name (obj_in_name); - - if (fseek (object_stream, (long) 0, SEEK_SET) != 0) - pfatal_with_name (object_name); - - for (remaining = orig_file_header.f_symptr; - remaining > 0; - remaining -= num_write) - { - num_write = - (remaining <= (int) sizeof (buffer)) ? remaining : sizeof (buffer); - sys_read = fread ((PTR_T) buffer, 1, num_write, obj_in_stream); - if (sys_read <= 0) - pfatal_with_name (obj_in_name); - - else if (sys_read != num_write) - fatal ("Wanted to read %d bytes from %s, system returned %d", - num_write, - obj_in_name, - sys_read); - - sys_write = fwrite (buffer, 1, num_write, object_stream); - if (sys_write <= 0) - pfatal_with_name (object_name); - - else if (sys_write != num_write) - fatal ("Wrote %d bytes to %s, system returned %d", - num_write, - object_name, - sys_write); - } -} - - -/* Ye olde main program. */ - -int -main (argc, argv) - int argc; - char *argv[]; -{ - int iflag = 0; - char *p = local_rindex (argv[0], '/'); - char *num_end; - int option; - int i; - - progname = (p != 0) ? p+1 : argv[0]; - - (void) signal (SIGSEGV, catch_signal); - (void) signal (SIGBUS, catch_signal); - (void) signal (SIGABRT, catch_signal); - -#if !defined(__SABER__) && !defined(lint) - if (sizeof (efdr_t) > PAGE_USIZE) - fatal ("Efdr_t has a sizeof %d bytes, when it should be less than %d", - (int) sizeof (efdr_t), - (int) PAGE_USIZE); - - if (sizeof (page_t) != PAGE_USIZE) - fatal ("Page_t has a sizeof %d bytes, when it should be %d", - (int) sizeof (page_t), - (int) PAGE_USIZE); - -#endif - - alloc_counts[ alloc_type_none ].alloc_name = "none"; - alloc_counts[ alloc_type_scope ].alloc_name = "scope"; - alloc_counts[ alloc_type_vlinks ].alloc_name = "vlinks"; - alloc_counts[ alloc_type_shash ].alloc_name = "shash"; - alloc_counts[ alloc_type_thash ].alloc_name = "thash"; - alloc_counts[ alloc_type_tag ].alloc_name = "tag"; - alloc_counts[ alloc_type_forward ].alloc_name = "forward"; - alloc_counts[ alloc_type_thead ].alloc_name = "thead"; - alloc_counts[ alloc_type_varray ].alloc_name = "varray"; - - int_type_info = type_info_init; - int_type_info.basic_type = bt_Int; - - void_type_info = type_info_init; - void_type_info.basic_type = bt_Void; - - while ((option = getopt (argc, argv, "d:i:I:o:v")) != EOF) - switch (option) - { - default: - had_errors++; - break; - - case 'd': - debug = strtol (optarg, &num_end, 0); - if ((unsigned)debug > 4 || num_end == optarg) - had_errors++; - - break; - - case 'I': - if (rename_output || obj_in_name != (char *) 0) - had_errors++; - else - rename_output = 1; - - /* fall through to 'i' case. */ - - case 'i': - if (obj_in_name == (char *) 0) - { - obj_in_name = optarg; - iflag++; - } - else - had_errors++; - break; - - case 'o': - if (object_name == (char *) 0) - object_name = optarg; - else - had_errors++; - break; - - case 'v': - version++; - break; - } - - if (obj_in_name == (char *) 0 && optind <= argc - 2) - obj_in_name = argv[--argc]; - - if (object_name == (char *) 0 && optind <= argc - 2) - object_name = argv[--argc]; - - /* If there is an output name, but no input name use - the same file for both, deleting the name between - opening it for input and opening it for output. */ - if (obj_in_name == (char *) 0 && object_name != (char *)0) - { - obj_in_name = object_name; - delete_input = 1; - } - - if (object_name == (char *) 0 || had_errors || optind != argc - 1) - { - fprintf (stderr, "Calling Sequence:\n"); - fprintf (stderr, "\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n"); - fprintf (stderr, "\tmips-tfile [-d <num>] [-v] [-I <o-in-file>] -o <o-out-file> <s-file> (or)\n"); - fprintf (stderr, "\tmips-tfile [-d <num>] [-v] <s-file> <o-in-file> <o-out-file>\n"); - fprintf (stderr, "\n"); - fprintf (stderr, "Debug levels are:\n"); - fprintf (stderr, " 1\tGeneral debug + trace functions/blocks.\n"); - fprintf (stderr, " 2\tDebug level 1 + trace externals.\n"); - fprintf (stderr, " 3\tDebug level 2 + trace all symbols.\n"); - fprintf (stderr, " 4\tDebug level 3 + trace memory allocations.\n"); - return 1; - } - - - if (version) - { - fprintf (stderr, "mips-tfile version %s", version_string); -#ifdef TARGET_VERSION - TARGET_VERSION; -#endif - fputc ('\n', stderr); - } - - if (obj_in_name == (char *) 0) - obj_in_name = object_name; - - if (rename_output && rename (object_name, obj_in_name) != 0) - { - char *buffer = (char *) allocate_multiple_pages (4); - int len; - int len2; - int in_fd; - int out_fd; - - /* Rename failed, copy input file */ - in_fd = open (object_name, O_RDONLY, 0666); - if (in_fd < 0) - pfatal_with_name (object_name); - - out_fd = open (obj_in_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); - if (out_fd < 0) - pfatal_with_name (obj_in_name); - - while ((len = read (in_fd, buffer, 4*PAGE_SIZE)) > 0) - { - len2 = write (out_fd, buffer, len); - if (len2 < 0) - pfatal_with_name (object_name); - - if (len != len2) - fatal ("wrote %d bytes to %s, expected to write %d", len2, obj_in_name, len); - } - - free_multiple_pages ((page_t *)buffer, 4); - - if (len < 0) - pfatal_with_name (object_name); - - if (close (in_fd) < 0) - pfatal_with_name (object_name); - - if (close (out_fd) < 0) - pfatal_with_name (obj_in_name); - } - - /* Must open input before output, since the output may be the same file, and - we need to get the input handle before truncating it. */ - obj_in_stream = fopen (obj_in_name, "r"); - if (obj_in_stream == (FILE *) 0) - pfatal_with_name (obj_in_name); - - if (delete_input && unlink (obj_in_name) != 0) - pfatal_with_name (obj_in_name); - - object_stream = fopen (object_name, "w"); - if (object_stream == (FILE *) 0) - pfatal_with_name (object_name); - - if (strcmp (argv[optind], "-") != 0) - { - input_name = argv[optind]; - if (freopen (argv[optind], "r", stdin) != stdin) - pfatal_with_name (argv[optind]); - } - - copy_object (); /* scan & copy object file */ - parse_input (); /* scan all of input */ - - update_headers (); /* write out tfile */ - write_object (); - - if (debug) - { - fprintf (stderr, "\n\tAllocation summary:\n\n"); - for (i = (int)alloc_type_none; i < (int)alloc_type_last; i++) - if (alloc_counts[i].total_alloc) - { - fprintf (stderr, - "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n", - alloc_counts[i].alloc_name, - alloc_counts[i].total_alloc, - alloc_counts[i].total_free, - alloc_counts[i].total_pages); - } - } - - return (had_errors) ? 1 : 0; -} - - -STATIC const char * -my_strsignal (s) - int s; -{ -#ifdef HAVE_STRSIGNAL - return strsignal (s); -#else - if (s >= 0 && s < NSIG) - { -# ifdef NO_SYS_SIGLIST - static char buffer[30]; - - sprintf (buffer, "Unknown signal %d", s); - return buffer; -# else - return sys_siglist[s]; -# endif - } - else - return NULL; -#endif /* HAVE_STRSIGNAL */ -} - -/* Catch a signal and exit without dumping core. */ - -STATIC void -catch_signal (signum) - int signum; -{ - (void) signal (signum, SIG_DFL); /* just in case... */ - fatal (my_strsignal(signum)); -} - -/* Print a fatal error message. NAME is the text. - Also include a system error message based on `errno'. */ - -void -pfatal_with_name (msg) - const char *msg; -{ - int save_errno = errno; /* just in case.... */ - if (line_number > 0) - fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number); - else - fprintf (stderr, "%s:", progname); - - errno = save_errno; - if (errno == 0) - fprintf (stderr, "[errno = 0] %s\n", msg); - else - perror (msg); - - exit (1); -} - - -/* Procedure to abort with an out of bounds error message. It has - type int, so it can be used with an ?: expression within the - ORIG_xxx macros, but the function never returns. */ - -static int -out_of_bounds (indx, max, str, prog_line) - symint_t indx; /* index that is out of bounds */ - symint_t max; /* maximum index */ - const char *str; /* string to print out */ - int prog_line; /* line number within mips-tfile.c */ -{ - if (indx < max) /* just in case */ - return 0; - - fprintf (stderr, "%s, %s:%ld index %lu is out of bounds for %s, max is %lu, mips-tfile.c line# %d\n", - progname, input_name, line_number, indx, str, max, prog_line); - - exit (1); - return 0; /* turn off warning messages */ -} - - -/* Allocate a cluster of pages. USE_MALLOC says that malloc does not - like sbrk's behind its back (or sbrk isn't available). If we use - sbrk, we assume it gives us zeroed pages. */ - -#ifndef MALLOC_CHECK -#ifdef USE_MALLOC - -STATIC page_t * -allocate_cluster (npages) - Size_t npages; -{ - register page_t *value = (page_t *) calloc (npages, PAGE_USIZE); - - if (value == 0) - fatal ("Virtual memory exhausted."); - - if (debug > 3) - fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value); - - return value; -} - -#else /* USE_MALLOC */ - -STATIC page_t * -allocate_cluster (npages) - Size_t npages; -{ - register page_t *ptr = (page_t *) sbrk (0); /* current sbreak */ - unsigned long offset = ((unsigned long) ptr) & (PAGE_SIZE - 1); - - if (offset != 0) /* align to a page boundary */ - { - if (sbrk (PAGE_USIZE - offset) == (char *)-1) - pfatal_with_name ("allocate_cluster"); - - ptr = (page_t *) (((char *)ptr) + PAGE_SIZE - offset); - } - - if (sbrk (npages * PAGE_USIZE) == (char *)-1) - pfatal_with_name ("allocate_cluster"); - - if (debug > 3) - { - fprintf (stderr, "\talloc\tnpages = %lu, value = ", - (unsigned long) npages); - fprintf (stderr, HOST_PTR_PRINTF, ptr); - fputs ("\n", stderr); - } - - return ptr; -} - -#endif /* USE_MALLOC */ - - -static page_t *cluster_ptr = NULL; -static unsigned pages_left = 0; - -#endif /* MALLOC_CHECK */ - - -/* Allocate some pages (which is initialized to 0). */ - -STATIC page_t * -allocate_multiple_pages (npages) - Size_t npages; -{ -#ifndef MALLOC_CHECK - if (pages_left == 0 && npages < MAX_CLUSTER_PAGES) - { - pages_left = MAX_CLUSTER_PAGES; - cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES); - } - - if (npages <= pages_left) - { - page_t *ptr = cluster_ptr; - cluster_ptr += npages; - pages_left -= npages; - return ptr; - } - - return allocate_cluster (npages); - -#else /* MALLOC_CHECK */ - return (page_t *) xcalloc (npages, PAGE_SIZE); - -#endif /* MALLOC_CHECK */ -} - - -/* Release some pages. */ - -STATIC void -free_multiple_pages (page_ptr, npages) - page_t *page_ptr; - Size_t npages; -{ -#ifndef MALLOC_CHECK - if (pages_left == 0) - { - cluster_ptr = page_ptr; - pages_left = npages; - } - - else if ((page_ptr + npages) == cluster_ptr) - { - cluster_ptr -= npages; - pages_left += npages; - } - - /* otherwise the page is not freed. If more than call is - done, we probably should worry about it, but at present, - the free pages is done right after an allocate. */ - -#else /* MALLOC_CHECK */ - free ((char *) page_ptr); - -#endif /* MALLOC_CHECK */ -} - - -/* Allocate one page (which is initialized to 0). */ - -STATIC page_t * -allocate_page __proto((void)) -{ -#ifndef MALLOC_CHECK - if (pages_left == 0) - { - pages_left = MAX_CLUSTER_PAGES; - cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES); - } - - pages_left--; - return cluster_ptr++; - -#else /* MALLOC_CHECK */ - return (page_t *) xcalloc (1, PAGE_SIZE); - -#endif /* MALLOC_CHECK */ -} - - -/* Allocate scoping information. */ - -STATIC scope_t * -allocate_scope __proto((void)) -{ - register scope_t *ptr; - static scope_t initial_scope; - -#ifndef MALLOC_CHECK - ptr = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope; - if (ptr != (scope_t *) 0) - alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr->free; - - else - { - register int unallocated = alloc_counts[ (int)alloc_type_scope ].unallocated; - register page_t *cur_page = alloc_counts[ (int)alloc_type_scope ].cur_page; - - if (unallocated == 0) - { - unallocated = PAGE_SIZE / sizeof (scope_t); - alloc_counts[ (int)alloc_type_scope ].cur_page = cur_page = allocate_page (); - alloc_counts[ (int)alloc_type_scope ].total_pages++; - } - - ptr = &cur_page->scope[ --unallocated ]; - alloc_counts[ (int)alloc_type_scope ].unallocated = unallocated; - } - -#else - ptr = (scope_t *) xmalloc (sizeof (scope_t)); - -#endif - - alloc_counts[ (int)alloc_type_scope ].total_alloc++; - *ptr = initial_scope; - return ptr; -} - -/* Free scoping information. */ - -STATIC void -free_scope (ptr) - scope_t *ptr; -{ - alloc_counts[ (int)alloc_type_scope ].total_free++; - -#ifndef MALLOC_CHECK - ptr->free = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope; - alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr; - -#else - xfree ((PTR_T) ptr); -#endif - -} - - -/* Allocate links for pages in a virtual array. */ - -STATIC vlinks_t * -allocate_vlinks __proto((void)) -{ - register vlinks_t *ptr; - static vlinks_t initial_vlinks; - -#ifndef MALLOC_CHECK - register int unallocated = alloc_counts[ (int)alloc_type_vlinks ].unallocated; - register page_t *cur_page = alloc_counts[ (int)alloc_type_vlinks ].cur_page; - - if (unallocated == 0) - { - unallocated = PAGE_SIZE / sizeof (vlinks_t); - alloc_counts[ (int)alloc_type_vlinks ].cur_page = cur_page = allocate_page (); - alloc_counts[ (int)alloc_type_vlinks ].total_pages++; - } - - ptr = &cur_page->vlinks[ --unallocated ]; - alloc_counts[ (int)alloc_type_vlinks ].unallocated = unallocated; - -#else - ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t)); - -#endif - - alloc_counts[ (int)alloc_type_vlinks ].total_alloc++; - *ptr = initial_vlinks; - return ptr; -} - - -/* Allocate string hash buckets. */ - -STATIC shash_t * -allocate_shash __proto((void)) -{ - register shash_t *ptr; - static shash_t initial_shash; - -#ifndef MALLOC_CHECK - register int unallocated = alloc_counts[ (int)alloc_type_shash ].unallocated; - register page_t *cur_page = alloc_counts[ (int)alloc_type_shash ].cur_page; - - if (unallocated == 0) - { - unallocated = PAGE_SIZE / sizeof (shash_t); - alloc_counts[ (int)alloc_type_shash ].cur_page = cur_page = allocate_page (); - alloc_counts[ (int)alloc_type_shash ].total_pages++; - } - - ptr = &cur_page->shash[ --unallocated ]; - alloc_counts[ (int)alloc_type_shash ].unallocated = unallocated; - -#else - ptr = (shash_t *) xmalloc (sizeof (shash_t)); - -#endif - - alloc_counts[ (int)alloc_type_shash ].total_alloc++; - *ptr = initial_shash; - return ptr; -} - - -/* Allocate type hash buckets. */ - -STATIC thash_t * -allocate_thash __proto((void)) -{ - register thash_t *ptr; - static thash_t initial_thash; - -#ifndef MALLOC_CHECK - register int unallocated = alloc_counts[ (int)alloc_type_thash ].unallocated; - register page_t *cur_page = alloc_counts[ (int)alloc_type_thash ].cur_page; - - if (unallocated == 0) - { - unallocated = PAGE_SIZE / sizeof (thash_t); - alloc_counts[ (int)alloc_type_thash ].cur_page = cur_page = allocate_page (); - alloc_counts[ (int)alloc_type_thash ].total_pages++; - } - - ptr = &cur_page->thash[ --unallocated ]; - alloc_counts[ (int)alloc_type_thash ].unallocated = unallocated; - -#else - ptr = (thash_t *) xmalloc (sizeof (thash_t)); - -#endif - - alloc_counts[ (int)alloc_type_thash ].total_alloc++; - *ptr = initial_thash; - return ptr; -} - - -/* Allocate structure, union, or enum tag information. */ - -STATIC tag_t * -allocate_tag __proto((void)) -{ - register tag_t *ptr; - static tag_t initial_tag; - -#ifndef MALLOC_CHECK - ptr = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag; - if (ptr != (tag_t *) 0) - alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr->free; - - else - { - register int unallocated = alloc_counts[ (int)alloc_type_tag ].unallocated; - register page_t *cur_page = alloc_counts[ (int)alloc_type_tag ].cur_page; - - if (unallocated == 0) - { - unallocated = PAGE_SIZE / sizeof (tag_t); - alloc_counts[ (int)alloc_type_tag ].cur_page = cur_page = allocate_page (); - alloc_counts[ (int)alloc_type_tag ].total_pages++; - } - - ptr = &cur_page->tag[ --unallocated ]; - alloc_counts[ (int)alloc_type_tag ].unallocated = unallocated; - } - -#else - ptr = (tag_t *) xmalloc (sizeof (tag_t)); - -#endif - - alloc_counts[ (int)alloc_type_tag ].total_alloc++; - *ptr = initial_tag; - return ptr; -} - -/* Free scoping information. */ - -STATIC void -free_tag (ptr) - tag_t *ptr; -{ - alloc_counts[ (int)alloc_type_tag ].total_free++; - -#ifndef MALLOC_CHECK - ptr->free = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag; - alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr; - -#else - xfree ((PTR_T) ptr); -#endif - -} - - -/* Allocate forward reference to a yet unknown tag. */ - -STATIC forward_t * -allocate_forward __proto((void)) -{ - register forward_t *ptr; - static forward_t initial_forward; - -#ifndef MALLOC_CHECK - ptr = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward; - if (ptr != (forward_t *) 0) - alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr->free; - - else - { - register int unallocated = alloc_counts[ (int)alloc_type_forward ].unallocated; - register page_t *cur_page = alloc_counts[ (int)alloc_type_forward ].cur_page; - - if (unallocated == 0) - { - unallocated = PAGE_SIZE / sizeof (forward_t); - alloc_counts[ (int)alloc_type_forward ].cur_page = cur_page = allocate_page (); - alloc_counts[ (int)alloc_type_forward ].total_pages++; - } - - ptr = &cur_page->forward[ --unallocated ]; - alloc_counts[ (int)alloc_type_forward ].unallocated = unallocated; - } - -#else - ptr = (forward_t *) xmalloc (sizeof (forward_t)); - -#endif - - alloc_counts[ (int)alloc_type_forward ].total_alloc++; - *ptr = initial_forward; - return ptr; -} - -/* Free scoping information. */ - -STATIC void -free_forward (ptr) - forward_t *ptr; -{ - alloc_counts[ (int)alloc_type_forward ].total_free++; - -#ifndef MALLOC_CHECK - ptr->free = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward; - alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr; - -#else - xfree ((PTR_T) ptr); -#endif - -} - - -/* Allocate head of type hash list. */ - -STATIC thead_t * -allocate_thead __proto((void)) -{ - register thead_t *ptr; - static thead_t initial_thead; - -#ifndef MALLOC_CHECK - ptr = alloc_counts[ (int)alloc_type_thead ].free_list.f_thead; - if (ptr != (thead_t *) 0) - alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr->free; - - else - { - register int unallocated = alloc_counts[ (int)alloc_type_thead ].unallocated; - register page_t *cur_page = alloc_counts[ (int)alloc_type_thead ].cur_page; - - if (unallocated == 0) - { - unallocated = PAGE_SIZE / sizeof (thead_t); - alloc_counts[ (int)alloc_type_thead ].cur_page = cur_page = allocate_page (); - alloc_counts[ (int)alloc_type_thead ].total_pages++; - } - - ptr = &cur_page->thead[ --unallocated ]; - alloc_counts[ (int)alloc_type_thead ].unallocated = unallocated; - } - -#else - ptr = (thead_t *) xmalloc (sizeof (thead_t)); - -#endif - - alloc_counts[ (int)alloc_type_thead ].total_alloc++; - *ptr = initial_thead; - return ptr; -} - -/* Free scoping information. */ - -STATIC void -free_thead (ptr) - thead_t *ptr; -{ - alloc_counts[ (int)alloc_type_thead ].total_free++; - -#ifndef MALLOC_CHECK - ptr->free = (thead_t *) alloc_counts[ (int)alloc_type_thead ].free_list.f_thead; - alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr; - -#else - xfree ((PTR_T) ptr); -#endif - -} - -#endif /* MIPS_DEBUGGING_INFO */ - - -/* Output an error message and exit */ - -/*VARARGS*/ -void -fatal VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - const char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, const char *); -#endif - - if (line_number > 0) - fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number); - else - fprintf (stderr, "%s:", progname); - - vfprintf (stderr, format, ap); - va_end (ap); - fprintf (stderr, "\n"); - if (line_number > 0) - fprintf (stderr, "line:\t%s\n", cur_line_start); - - saber_stop (); - exit (1); -} - -/*VARARGS*/ -void -error VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - if (line_number > 0) - fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number); - else - fprintf (stderr, "%s:", progname); - - vfprintf (stderr, format, ap); - fprintf (stderr, "\n"); - if (line_number > 0) - fprintf (stderr, "line:\t%s\n", cur_line_start); - - had_errors++; - va_end (ap); - - saber_stop (); -} - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal abort."); -} - - -/* When `malloc.c' is compiled with `rcheck' defined, - it calls this function to report clobberage. */ - -void -botch (s) - const char *s; -{ - fatal (s); -} - -/* Same as `malloc' but report error if no memory available. */ - -PTR -xmalloc (size) - size_t size; -{ - register PTR value = (PTR) malloc (size); - if (value == 0) - fatal ("Virtual memory exhausted."); - - if (debug > 3) - { - fputs ("\tmalloc\tptr = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, value); - fprintf (stderr, ", size = %10lu\n", (unsigned long) size); - } - - return value; -} - -/* Same as `calloc' but report error if no memory available. */ - -PTR -xcalloc (size1, size2) - size_t size1, size2; -{ - register PTR value = (PTR) calloc (size1, size2); - if (value == 0) - fatal ("Virtual memory exhausted."); - - if (debug > 3) - { - fputs ("\tcalloc\tptr = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, value); - fprintf (stderr, ", size1 = %10lu, size2 = %10lu [%lu]\n", - (unsigned long) size1, (unsigned long) size2, - (unsigned long) size1*size2); - } - - return value; -} - -/* Same as `realloc' but report error if no memory available. */ - -PTR -xrealloc (ptr, size) - PTR ptr; - size_t size; -{ - register PTR result; - if (ptr) - result = (PTR) realloc (ptr, size); - else - result = (PTR) malloc (size); - if (!result) - fatal ("Virtual memory exhausted."); - - if (debug > 3) - { - fputs ("\trealloc\tptr = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, result); - fprintf (stderr, ", size = %10lu, orig = ", size); - fprintf (stderr, HOST_PTR_PRINTF, ptr); - fputs ("\n", stderr); - } - - return result; -} - -void -xfree (ptr) - PTR ptr; -{ - if (debug > 3) - { - fputs ("\tfree\tptr = ", stderr); - fprintf (stderr, HOST_PTR_PRINTF, ptr); - fputs ("\n", stderr); - } - - free (ptr); -} - - -/* Define our own index/rindex, since the local and global symbol - structures as defined by MIPS has an 'index' field. */ - -STATIC char * -local_index (str, sentinel) - const char *str; - int sentinel; -{ - int ch; - - for ( ; (ch = *str) != sentinel; str++) - { - if (ch == '\0') - return (char *) 0; - } - - return (char *)str; -} - -STATIC char * -local_rindex (str, sentinel) - const char *str; - int sentinel; -{ - int ch; - const char *ret = (const char *) 0; - - for ( ; (ch = *str) != '\0'; str++) - { - if (ch == sentinel) - ret = str; - } - - return (char *)ret; -} diff --git a/gcc/patch-apollo-includes b/gcc/patch-apollo-includes deleted file mode 100755 index 8daf88c..0000000 --- a/gcc/patch-apollo-includes +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh -# patch-apollo-includes -- fix some (but not all!) Apollo brain damage. - -FILES_TO_PATCH='sys/types.h setjmp.h' - -mkdir sys - -for i in $FILES_TO_PATCH; -do - cp /bsd4.3/usr/include/$i ./$i -done - -patch -b -apollo <<'EOP' -*** /bsd4.3/usr/include/sys/types.h Fri Apr 8 20:29:06 1988 ---- sys/types.h Wed Feb 26 21:17:57 1992 -*************** -*** 38,44 **** ---- 38,47 ---- - typedef char * caddr_t; - typedef u_long ino_t; - typedef long swblk_t; -+ #ifndef _SIZE_T -+ #define _SIZE_T - typedef long size_t; -+ #endif - typedef long time_t; - typedef long dev_t; - typedef long off_t; -*** /bsd4.3/usr/include/setjmp.h Fri Feb 3 21:40:21 1989 ---- setjmp.h Sun Feb 23 19:06:55 1992 -*************** -*** 24,30 **** ---- 24,39 ---- - #endif - - -+ #ifdef __GNUC__ - #ifdef _PROTOTYPES -+ extern int sigsetjmp (sigjmp_buf env, int savemask); -+ extern void siglongjmp (sigjmp_buf env, int val); -+ #else -+ extern int sigsetjmp(); -+ extern void siglongjmp(); -+ #endif /* _PROTOTYPES */ -+ #else /* not __GNUC__ */ -+ #ifdef _PROTOTYPES - extern int sigsetjmp( - sigjmp_buf env, - int savemask -*************** -*** 37,43 **** - extern int sigsetjmp() #options(abnormal); - extern void siglongjmp() #options(noreturn); - #endif /* _PROTOTYPES */ -! - #undef _PROTOTYPES - - #ifdef __cplusplus ---- 46,52 ---- - extern int sigsetjmp() #options(abnormal); - extern void siglongjmp() #options(noreturn); - #endif /* _PROTOTYPES */ -! #endif /* not __GNUC__ */ - #undef _PROTOTYPES - - #ifdef __cplusplus -EOP - -exit 0 diff --git a/gcc/pself.c b/gcc/pself.c deleted file mode 100755 index d8471da..0000000 --- a/gcc/pself.c +++ /dev/null @@ -1 +0,0 @@ -main(){char*p="main(){char*p=%c%s%c;(void)printf(p,34,p,34,10);}%c";(void)printf(p,34,p,34,10);} diff --git a/gcc/pself1.c b/gcc/pself1.c deleted file mode 100755 index acdfc65..0000000 --- a/gcc/pself1.c +++ /dev/null @@ -1 +0,0 @@ -main(a){a="main(a){a=%c%s%c;printf(a,34,a,34);}";printf(a,34,a,34);}
\ No newline at end of file diff --git a/gcc/pself2.c b/gcc/pself2.c deleted file mode 100755 index c88a8c1..0000000 --- a/gcc/pself2.c +++ /dev/null @@ -1 +0,0 @@ -main(){char*a="main(){char*a=%c%s%c;int b='%c';printf(a,b,a,b,b);}";int b='"';printf(a,b,a,b,b);} diff --git a/gcc/pself3.c b/gcc/pself3.c deleted file mode 100755 index dbdeac6..0000000 --- a/gcc/pself3.c +++ /dev/null @@ -1 +0,0 @@ -main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);} diff --git a/gcc/range.c b/gcc/range.c index d96caca..1a76b43 100755 --- a/gcc/range.c +++ b/gcc/range.c @@ -1292,8 +1292,7 @@ range_finish (stream, first_insn, count, range_max_regno) rtx before; int new_scope_p = (write_symbols != NO_DEBUG /* create new scope */ && flag_live_range_scope /* block for vars? */ - && (write_symbols != DBX_DEBUG - || !LIVE_RANGE_GDBSTAB_P ())); + ); after = range_start; before = range_end; diff --git a/gcc/range.h b/gcc/range.h index 20d1d4f..9a48458 100755 --- a/gcc/range.h +++ b/gcc/range.h @@ -37,17 +37,9 @@ extern int range_max_unique; /* Allow copies from constant integers */ #define LIVE_RANGE_COPYIN_CONST 0x4 -/* Default value for using GDB specific stabs to denote live ranges */ -#define LIVE_RANGE_GDB_DEFAULT 1 - /* Default value for creating scoping blocks for live ranges */ #define LIVE_RANGE_SCOPE_DEFAULT 0 -/* Determine whether or not to use new style stabs for live range debugging. - Assumes that write_symbols == DBX_DEBUG has already been checked for. */ -#define LIVE_RANGE_GDBSTAB_P() (use_gnu_debug_info_extensions \ - && flag_live_range_gdb) - /* Live range functions */ #ifdef BUFSIZ extern void live_range_print PROTO((FILE *, rtx, char *, char *)); diff --git a/gcc/sdbout.c b/gcc/sdbout.c deleted file mode 100755 index 1823155..0000000 --- a/gcc/sdbout.c +++ /dev/null @@ -1,1674 +0,0 @@ -/* Output sdb-format symbol table information from GNU compiler. - Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* mike@tredysvr.Tredydev.Unisys.COM says: -I modified the struct.c example and have a nm of a .o resulting from the -AT&T C compiler. From the example below I would conclude the following: - -1. All .defs from structures are emitted as scanned. The example below - clearly shows the symbol table entries for BoxRec2 are after the first - function. - -2. All functions and their locals (including statics) are emitted as scanned. - -3. All nested unnamed union and structure .defs must be emitted before - the structure in which they are nested. The AT&T assembler is a - one pass beast as far as symbolics are concerned. - -4. All structure .defs are emitted before the typedefs that refer to them. - -5. All top level static and external variable definitions are moved to the - end of file with all top level statics occurring first before externs. - -6. All undefined references are at the end of the file. -*/ - -#include "config.h" - -#ifdef SDB_DEBUGGING_INFO - -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "regs.h" -#include "defaults.h" -#include "flags.h" -#include "insn-config.h" -#include "reload.h" -#include "output.h" -#include "toplev.h" - -/* Mips systems use the SDB functions to dump out symbols, but do not - supply usable syms.h include files. Which syms.h file to use is a - target parameter so don't use the native one if we're cross compiling. */ - -#if defined(USG) && !defined(MIPS) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__) && !defined(CROSS_COMPILE) -#include <syms.h> -/* Use T_INT if we don't have T_VOID. */ -#ifndef T_VOID -#define T_VOID T_INT -#endif -#else -#include "gsyms.h" -#endif - -/* #include <storclass.h> used to be this instead of syms.h. */ - -/* 1 if PARM is passed to this function in memory. */ - -#define PARM_PASSED_IN_MEMORY(PARM) \ - (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM) - -/* A C expression for the integer offset value of an automatic variable - (C_AUTO) having address X (an RTX). */ -#ifndef DEBUGGER_AUTO_OFFSET -#define DEBUGGER_AUTO_OFFSET(X) \ - (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) -#endif - -/* A C expression for the integer offset value of an argument (C_ARG) - having address X (an RTX). The nominal offset is OFFSET. */ -#ifndef DEBUGGER_ARG_OFFSET -#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET) -#endif - -/* Line number of beginning of current function, minus one. - Negative means not in a function or not using sdb. */ - -int sdb_begin_function_line = -1; - -/* Counter to generate unique "names" for nameless struct members. */ - -static int unnamed_struct_number = 0; - -extern FILE *asm_out_file; - -extern tree current_function_decl; - -#include "sdbout.h" - -static char *gen_fake_label PROTO((void)); -static int plain_type PROTO((tree)); -static int template_name_p PROTO((tree)); -static void sdbout_record_type_name PROTO((tree)); -static int plain_type_1 PROTO((tree, int)); -static void sdbout_block PROTO((tree)); -static void sdbout_syms PROTO((tree)); -static void sdbout_queue_anonymous_type PROTO((tree)); -static void sdbout_dequeue_anonymous_types PROTO((void)); -static void sdbout_type PROTO((tree)); -static void sdbout_field_types PROTO((tree)); -static void sdbout_one_type PROTO((tree)); -static void sdbout_parms PROTO((tree)); -static void sdbout_reg_parms PROTO((tree)); - -/* Define the default sizes for various types. */ - -#ifndef CHAR_TYPE_SIZE -#define CHAR_TYPE_SIZE BITS_PER_UNIT -#endif - -#ifndef SHORT_TYPE_SIZE -#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) -#endif - -#ifndef INT_TYPE_SIZE -#define INT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_TYPE_SIZE -#define LONG_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef LONG_LONG_TYPE_SIZE -#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef FLOAT_TYPE_SIZE -#define FLOAT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef DOUBLE_TYPE_SIZE -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -/* Random macros describing parts of SDB data. */ - -/* Put something here if lines get too long */ -#define CONTIN - -/* Default value of delimiter is ";". */ -#ifndef SDB_DELIM -#define SDB_DELIM ";" -#endif - -/* Maximum number of dimensions the assembler will allow. */ -#ifndef SDB_MAX_DIM -#define SDB_MAX_DIM 4 -#endif - -#ifndef PUT_SDB_SCL -#define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d%s", (a), SDB_DELIM) -#endif - -#ifndef PUT_SDB_INT_VAL -#define PUT_SDB_INT_VAL(a) \ - do { \ - fputs ("\t.val\t", asm_out_file); \ - fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a)); \ - fprintf (asm_out_file, "%s", SDB_DELIM); \ - } while (0) - -#endif - -#ifndef PUT_SDB_VAL -#define PUT_SDB_VAL(a) \ -( fputs ("\t.val\t", asm_out_file), \ - output_addr_const (asm_out_file, (a)), \ - fprintf (asm_out_file, SDB_DELIM)) -#endif - -#ifndef PUT_SDB_DEF -#define PUT_SDB_DEF(a) \ -do { fprintf (asm_out_file, "\t.def\t"); \ - ASM_OUTPUT_LABELREF (asm_out_file, a); \ - fprintf (asm_out_file, SDB_DELIM); } while (0) -#endif - -#ifndef PUT_SDB_PLAIN_DEF -#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s%s",a, SDB_DELIM) -#endif - -#ifndef PUT_SDB_ENDEF -#define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file) -#endif - -#ifndef PUT_SDB_TYPE -#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o%s", a, SDB_DELIM) -#endif - -#ifndef PUT_SDB_SIZE -#define PUT_SDB_SIZE(a) \ - do { \ - fputs ("\t.size\t", asm_out_file); \ - fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a)); \ - fprintf (asm_out_file, "%s", SDB_DELIM); \ - } while(0) -#endif - -#ifndef PUT_SDB_START_DIM -#define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t") -#endif - -#ifndef PUT_SDB_NEXT_DIM -#define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a) -#endif - -#ifndef PUT_SDB_LAST_DIM -#define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d%s", a, SDB_DELIM) -#endif - -#ifndef PUT_SDB_TAG -#define PUT_SDB_TAG(a) \ -do { fprintf (asm_out_file, "\t.tag\t"); \ - ASM_OUTPUT_LABELREF (asm_out_file, a); \ - fprintf (asm_out_file, SDB_DELIM); } while (0) -#endif - -#ifndef PUT_SDB_BLOCK_START -#define PUT_SDB_BLOCK_START(LINE) \ - fprintf (asm_out_file, \ - "\t.def\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ - SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) -#endif - -#ifndef PUT_SDB_BLOCK_END -#define PUT_SDB_BLOCK_END(LINE) \ - fprintf (asm_out_file, \ - "\t.def\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ - SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) -#endif - -#ifndef PUT_SDB_FUNCTION_START -#define PUT_SDB_FUNCTION_START(LINE) \ - fprintf (asm_out_file, \ - "\t.def\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ - SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) -#endif - -#ifndef PUT_SDB_FUNCTION_END -#define PUT_SDB_FUNCTION_END(LINE) \ - fprintf (asm_out_file, \ - "\t.def\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ - SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) -#endif - -#ifndef PUT_SDB_EPILOGUE_END -#define PUT_SDB_EPILOGUE_END(NAME) \ -do { fprintf (asm_out_file, "\t.def\t"); \ - ASM_OUTPUT_LABELREF (asm_out_file, NAME); \ - fprintf (asm_out_file, \ - "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n", \ - SDB_DELIM, SDB_DELIM, SDB_DELIM); } while (0) -#endif - -#ifndef SDB_GENERATE_FAKE -#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \ - sprintf ((BUFFER), ".%dfake", (NUMBER)); -#endif - -/* Return the sdb tag identifier string for TYPE - if TYPE has already been defined; otherwise return a null pointer. */ - -#define KNOWN_TYPE_TAG(type) TYPE_SYMTAB_POINTER (type) - -/* Set the sdb tag identifier string for TYPE to NAME. */ - -#define SET_KNOWN_TYPE_TAG(TYPE, NAME) \ - TYPE_SYMTAB_POINTER (TYPE) = (NAME) - -/* Return the name (a string) of the struct, union or enum tag - described by the TREE_LIST node LINK. This is 0 for an anonymous one. */ - -#define TAG_NAME(link) \ - (((link) && TREE_PURPOSE ((link)) \ - && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \ - ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0) - -/* Ensure we don't output a negative line number. */ -#define MAKE_LINE_SAFE(line) \ - if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1 - -/* Perform linker optimization of merging header file definitions together - for targets with MIPS_DEBUGGING_INFO defined. This won't work without a - post 960826 version of GAS. Nothing breaks with earlier versions of GAS, - the optimization just won't be done. The native assembler already has the - necessary support. */ - -#ifdef MIPS_DEBUGGING_INFO - -#ifndef PUT_SDB_SRC_FILE -#define PUT_SDB_SRC_FILE(FILENAME) \ -output_file_directive (asm_out_file, (FILENAME)) -#endif - -/* ECOFF linkers have an optimization that does the same kind of thing as - N_BINCL/E_INCL in stabs: eliminate duplicate debug information in the - executable. To achieve this, GCC must output a .file for each file - name change. */ - -/* This is a stack of input files. */ - -struct sdb_file -{ - struct sdb_file *next; - char *name; -}; - -/* This is the top of the stack. */ - -static struct sdb_file *current_file; - -#endif /* MIPS_DEBUGGING_INFO */ - -/* Set up for SDB output at the start of compilation. */ - -void -sdbout_init (asm_file, input_file_name, syms) - FILE *asm_file; - char *input_file_name; - tree syms; -{ -#ifdef MIPS_DEBUGGING_INFO - current_file = (struct sdb_file *) xmalloc (sizeof *current_file); - current_file->next = NULL; - current_file->name = input_file_name; -#endif - -#ifdef RMS_QUICK_HACK_1 - tree t; - for (t = syms; t; t = TREE_CHAIN (t)) - if (DECL_NAME (t) && IDENTIFIER_POINTER (DECL_NAME (t)) != 0 - && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__vtbl_ptr_type")) - sdbout_symbol (t, 0); -#endif -} - -#if 0 - -/* return the tag identifier for type - */ - -char * -tag_of_ru_type (type,link) - tree type,link; -{ - if (TYPE_SYMTAB_ADDRESS (type)) - return TYPE_SYMTAB_ADDRESS (type); - if (link && TREE_PURPOSE (link) - && IDENTIFIER_POINTER (TREE_PURPOSE (link))) - TYPE_SYMTAB_ADDRESS (type) = IDENTIFIER_POINTER (TREE_PURPOSE (link)); - else - return (char *) TYPE_SYMTAB_ADDRESS (type); -} -#endif - -/* Return a unique string to name an anonymous type. */ - -static char * -gen_fake_label () -{ - char label[10]; - char *labelstr; - SDB_GENERATE_FAKE (label, unnamed_struct_number); - unnamed_struct_number++; - labelstr = (char *) permalloc (strlen (label) + 1); - strcpy (labelstr, label); - return labelstr; -} - -/* Return the number which describes TYPE for SDB. - For pointers, etc., this function is recursive. - Each record, union or enumeral type must already have had a - tag number output. */ - -/* The number is given by d6d5d4d3d2d1bbbb - where bbbb is 4 bit basic type, and di indicate one of notype,ptr,fn,array. - Thus, char *foo () has bbbb=T_CHAR - d1=D_FCN - d2=D_PTR - N_BTMASK= 017 1111 basic type field. - N_TSHIFT= 2 derived type shift - N_BTSHFT= 4 Basic type shift */ - -/* Produce the number that describes a pointer, function or array type. - PREV is the number describing the target, value or element type. - DT_type describes how to transform that type. */ -#define PUSH_DERIVED_LEVEL(DT_type,PREV) \ - ((((PREV) & ~(int)N_BTMASK) << (int)N_TSHIFT) \ - | ((int)DT_type << (int)N_BTSHFT) \ - | ((PREV) & (int)N_BTMASK)) - -/* Number of elements used in sdb_dims. */ -static int sdb_n_dims = 0; - -/* Table of array dimensions of current type. */ -static int sdb_dims[SDB_MAX_DIM]; - -/* Size of outermost array currently being processed. */ -static int sdb_type_size = -1; - -static int -plain_type (type) - tree type; -{ - int val = plain_type_1 (type, 0); - - /* If we have already saved up some array dimensions, print them now. */ - if (sdb_n_dims > 0) - { - int i; - PUT_SDB_START_DIM; - for (i = sdb_n_dims - 1; i > 0; i--) - PUT_SDB_NEXT_DIM (sdb_dims[i]); - PUT_SDB_LAST_DIM (sdb_dims[0]); - sdb_n_dims = 0; - - sdb_type_size = int_size_in_bytes (type); - /* Don't kill sdb if type is not laid out or has variable size. */ - if (sdb_type_size < 0) - sdb_type_size = 0; - } - /* If we have computed the size of an array containing this type, - print it now. */ - if (sdb_type_size >= 0) - { - PUT_SDB_SIZE (sdb_type_size); - sdb_type_size = -1; - } - return val; -} - -static int -template_name_p (name) - tree name; -{ - register char *ptr = IDENTIFIER_POINTER (name); - while (*ptr && *ptr != '<') - ptr++; - - return *ptr != '\0'; -} - -static void -sdbout_record_type_name (type) - tree type; -{ - char *name = 0; - int no_name; - - if (KNOWN_TYPE_TAG (type)) - return; - - if (TYPE_NAME (type) != 0) - { - tree t = 0; - /* Find the IDENTIFIER_NODE for the type name. */ - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - t = TYPE_NAME (type); - else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) - { - t = DECL_NAME (TYPE_NAME (type)); - /* The DECL_NAME for templates includes "<>", which breaks - most assemblers. Use its assembler name instead, which - has been mangled into being safe. */ - if (t && template_name_p (t)) - t = DECL_ASSEMBLER_NAME (TYPE_NAME (type)); - } - - /* Now get the name as a string, or invent one. */ - if (t != NULL_TREE) - name = IDENTIFIER_POINTER (t); - } - - no_name = (name == 0 || *name == 0); - if (no_name) - name = gen_fake_label (); - - SET_KNOWN_TYPE_TAG (type, name); -#ifdef SDB_ALLOW_FORWARD_REFERENCES - if (no_name) - sdbout_queue_anonymous_type (type); -#endif -} - -/* Return the .type value for type TYPE. - - LEVEL indicates how many levels deep we have recursed into the type. - The SDB debug format can only represent 6 derived levels of types. - After that, we must output inaccurate debug info. We deliberately - stop before the 7th level, so that ADA recursive types will not give an - infinite loop. */ - -static int -plain_type_1 (type, level) - tree type; - int level; -{ - if (type == 0) - type = void_type_node; - else if (type == error_mark_node) - type = integer_type_node; - else - type = TYPE_MAIN_VARIANT (type); - - switch (TREE_CODE (type)) - { - case VOID_TYPE: - return T_VOID; - case INTEGER_TYPE: - { - int size = int_size_in_bytes (type) * BITS_PER_UNIT; - - /* Carefully distinguish all the standard types of C, - without messing up if the language is not C. - Note that we check only for the names that contain spaces; - other names might occur by coincidence in other languages. */ - if (TYPE_NAME (type) != 0 - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (type)) != 0 - && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) - { - char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); - - if (!strcmp (name, "char")) - return T_CHAR; - if (!strcmp (name, "unsigned char")) - return T_UCHAR; - if (!strcmp (name, "signed char")) - return T_CHAR; - if (!strcmp (name, "int")) - return T_INT; - if (!strcmp (name, "unsigned int")) - return T_UINT; - if (!strcmp (name, "short int")) - return T_SHORT; - if (!strcmp (name, "short unsigned int")) - return T_USHORT; - if (!strcmp (name, "long int")) - return T_LONG; - if (!strcmp (name, "long unsigned int")) - return T_ULONG; - } - - if (size == INT_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? T_UINT : T_INT); - if (size == CHAR_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR); - if (size == SHORT_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT); - if (size == LONG_TYPE_SIZE) - return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG); - if (size == LONG_LONG_TYPE_SIZE) /* better than nothing */ - return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG); - return 0; - } - - case REAL_TYPE: - { - int precision = TYPE_PRECISION (type); - if (precision == FLOAT_TYPE_SIZE) - return T_FLOAT; - if (precision == DOUBLE_TYPE_SIZE) - return T_DOUBLE; -#ifdef EXTENDED_SDB_BASIC_TYPES - if (precision == LONG_DOUBLE_TYPE_SIZE) - return T_LNGDBL; -#else - if (precision == LONG_DOUBLE_TYPE_SIZE) - return T_DOUBLE; /* better than nothing */ -#endif - return 0; - } - - case ARRAY_TYPE: - { - int m; - if (level >= 6) - return T_VOID; - else - m = plain_type_1 (TREE_TYPE (type), level+1); - if (sdb_n_dims < SDB_MAX_DIM) - sdb_dims[sdb_n_dims++] - = (TYPE_DOMAIN (type) - && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) - && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST - && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST - ? (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) - - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1) - : 0); - return PUSH_DERIVED_LEVEL (DT_ARY, m); - } - - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - case ENUMERAL_TYPE: - { - char *tag; -#ifdef SDB_ALLOW_FORWARD_REFERENCES - sdbout_record_type_name (type); -#endif -#ifndef SDB_ALLOW_UNKNOWN_REFERENCES - if ((TREE_ASM_WRITTEN (type) && KNOWN_TYPE_TAG (type) != 0) -#ifdef SDB_ALLOW_FORWARD_REFERENCES - || TYPE_MODE (type) != VOIDmode -#endif - ) -#endif - { - /* Output the referenced structure tag name - only if the .def has already been finished. - At least on 386, the Unix assembler - cannot handle forward references to tags. */ - /* But the 88100, it requires them, sigh... */ - /* And the MIPS requires unknown refs as well... */ - tag = KNOWN_TYPE_TAG (type); - PUT_SDB_TAG (tag); - /* These 3 lines used to follow the close brace. - However, a size of 0 without a tag implies a tag of 0, - so if we don't know a tag, we can't mention the size. */ - sdb_type_size = int_size_in_bytes (type); - if (sdb_type_size < 0) - sdb_type_size = 0; - } - return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT - : (TREE_CODE (type) == UNION_TYPE) ? T_UNION - : (TREE_CODE (type) == QUAL_UNION_TYPE) ? T_UNION - : T_ENUM); - } - case POINTER_TYPE: - case REFERENCE_TYPE: - { - int m; - if (level >= 6) - return T_VOID; - else - m = plain_type_1 (TREE_TYPE (type), level+1); - return PUSH_DERIVED_LEVEL (DT_PTR, m); - } - case FUNCTION_TYPE: - case METHOD_TYPE: - { - int m; - if (level >= 6) - return T_VOID; - else - m = plain_type_1 (TREE_TYPE (type), level+1); - return PUSH_DERIVED_LEVEL (DT_FCN, m); - } - default: - return 0; - } -} - -/* Output the symbols defined in block number DO_BLOCK. - Set NEXT_BLOCK_NUMBER to 0 before calling. - - This function works by walking the tree structure of blocks, - counting blocks until it finds the desired block. */ - -static int do_block = 0; - -static int next_block_number; - -static void -sdbout_block (block) - register tree block; -{ - while (block) - { - /* Ignore blocks never expanded or otherwise marked as real. */ - if (TREE_USED (block)) - { - /* When we reach the specified block, output its symbols. */ - if (next_block_number == do_block) - { - sdbout_syms (BLOCK_VARS (block)); - } - - /* If we are past the specified block, stop the scan. */ - if (next_block_number > do_block) - return; - - next_block_number++; - - /* Scan the blocks within this block. */ - sdbout_block (BLOCK_SUBBLOCKS (block)); - } - - block = BLOCK_CHAIN (block); - } -} - -/* Call sdbout_symbol on each decl in the chain SYMS. */ - -static void -sdbout_syms (syms) - tree syms; -{ - while (syms) - { - if (TREE_CODE (syms) != LABEL_DECL) - sdbout_symbol (syms, 1); - syms = TREE_CHAIN (syms); - } -} - -/* Output SDB information for a symbol described by DECL. - LOCAL is nonzero if the symbol is not file-scope. */ - -void -sdbout_symbol (decl, local) - tree decl; - int local; -{ - tree type = TREE_TYPE (decl); - tree context = NULL_TREE; - rtx value; - int regno = -1; - char *name; - - sdbout_one_type (type); - -#if 0 /* This loses when functions are marked to be ignored, - which happens in the C++ front end. */ - if (DECL_IGNORED_P (decl)) - return; -#endif - - switch (TREE_CODE (decl)) - { - case CONST_DECL: - /* Enum values are defined by defining the enum type. */ - return; - - case FUNCTION_DECL: - /* Don't mention a nested function under its parent. */ - context = decl_function_context (decl); - if (context == current_function_decl) - return; - /* Check DECL_INITIAL to distinguish declarations from definitions. - Don't output debug info here for declarations; they will have - a DECL_INITIAL value of 0. */ - if (! DECL_INITIAL (decl)) - return; - if (GET_CODE (DECL_RTL (decl)) != MEM - || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) - return; - PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); - PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); - PUT_SDB_SCL (TREE_PUBLIC (decl) ? C_EXT : C_STAT); - break; - - case TYPE_DECL: - /* Done with tagged types. */ - if (DECL_NAME (decl) == 0) - return; - if (DECL_IGNORED_P (decl)) - return; - - /* Output typedef name. */ - if (template_name_p (DECL_NAME (decl))) - PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); - else - PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl))); - PUT_SDB_SCL (C_TPDEF); - break; - - case PARM_DECL: - /* Parm decls go in their own separate chains - and are output by sdbout_reg_parms and sdbout_parms. */ - abort (); - - case VAR_DECL: - /* Don't mention a variable that is external. - Let the file that defines it describe it. */ - if (DECL_EXTERNAL (decl)) - return; - - /* Ignore __FUNCTION__, etc. */ - if (DECL_IGNORED_P (decl)) - return; - - /* If there was an error in the declaration, don't dump core - if there is no RTL associated with the variable doesn't - exist. */ - if (DECL_RTL (decl) == 0) - return; - - DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX); -#ifdef LEAF_REG_REMAP - if (leaf_function) - leaf_renumber_regs_insn (DECL_RTL (decl)); -#endif - value = DECL_RTL (decl); - - /* Don't mention a variable at all - if it was completely optimized into nothingness. - - If DECL was from an inline function, then its rtl - is not identically the rtl that was used in this - particular compilation. */ - if (GET_CODE (value) == REG) - { - regno = REGNO (DECL_RTL (decl)); - if (regno >= FIRST_PSEUDO_REGISTER) - return; - } - else if (GET_CODE (value) == SUBREG) - { - int offset = 0; - while (GET_CODE (value) == SUBREG) - { - offset += SUBREG_WORD (value); - value = SUBREG_REG (value); - } - if (GET_CODE (value) == REG) - { - regno = REGNO (value); - if (regno >= FIRST_PSEUDO_REGISTER) - return; - regno += offset; - } - alter_subreg (DECL_RTL (decl)); - value = DECL_RTL (decl); - } - /* Don't output anything if an auto variable - gets RTL that is static. - GAS version 2.2 can't handle such output. */ - else if (GET_CODE (value) == MEM && CONSTANT_P (XEXP (value, 0)) - && ! TREE_STATIC (decl)) - return; - - /* Emit any structure, union, or enum type that has not been output. - This occurs for tag-less structs (et al) used to declare variables - within functions. */ - if (TREE_CODE (type) == ENUMERAL_TYPE - || TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE) - { - if (TYPE_SIZE (type) != 0 /* not a forward reference */ - && KNOWN_TYPE_TAG (type) == 0) /* not yet declared */ - sdbout_one_type (type); - } - - /* Defer SDB information for top-level initialized variables! */ - if (! local - && GET_CODE (value) == MEM - && DECL_INITIAL (decl)) - return; - - /* C++ in 2.3 makes nameless symbols. That will be fixed later. - For now, avoid crashing. */ - if (DECL_NAME (decl) == NULL_TREE) - return; - - /* Record the name for, starting a symtab entry. */ - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - - if (GET_CODE (value) == MEM - && GET_CODE (XEXP (value, 0)) == SYMBOL_REF) - { - PUT_SDB_DEF (name); - if (TREE_PUBLIC (decl)) - { - PUT_SDB_VAL (XEXP (value, 0)); - PUT_SDB_SCL (C_EXT); - } - else - { - PUT_SDB_VAL (XEXP (value, 0)); - PUT_SDB_SCL (C_STAT); - } - } - else if (regno >= 0) - { - PUT_SDB_DEF (name); - PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno)); - PUT_SDB_SCL (C_REG); - } - else if (GET_CODE (value) == MEM - && (GET_CODE (XEXP (value, 0)) == MEM - || (GET_CODE (XEXP (value, 0)) == REG - && REGNO (XEXP (value, 0)) != HARD_FRAME_POINTER_REGNUM - && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM))) - /* If the value is indirect by memory or by a register - that isn't the frame pointer - then it means the object is variable-sized and address through - that register or stack slot. COFF has no way to represent this - so all we can do is output the variable as a pointer. */ - { - PUT_SDB_DEF (name); - if (GET_CODE (XEXP (value, 0)) == REG) - { - PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0)))); - PUT_SDB_SCL (C_REG); - } - else - { - /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) - (CONST_INT...)))). - We want the value of that CONST_INT. */ - /* Encore compiler hates a newline in a macro arg, it seems. */ - PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET - (XEXP (XEXP (value, 0), 0))); - PUT_SDB_SCL (C_AUTO); - } - - type = build_pointer_type (TREE_TYPE (decl)); - } - else if (GET_CODE (value) == MEM - && ((GET_CODE (XEXP (value, 0)) == PLUS - && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG - && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT) - /* This is for variables which are at offset zero from - the frame pointer. This happens on the Alpha. - Non-frame pointer registers are excluded above. */ - || (GET_CODE (XEXP (value, 0)) == REG))) - { - /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))) - or (MEM (REG...)). We want the value of that CONST_INT - or zero. */ - PUT_SDB_DEF (name); - PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0))); - PUT_SDB_SCL (C_AUTO); - } - else if (GET_CODE (value) == MEM && GET_CODE (XEXP (value, 0)) == CONST) - { - /* Handle an obscure case which can arise when optimizing and - when there are few available registers. (This is *always* - the case for i386/i486 targets). The DECL_RTL looks like - (MEM (CONST ...)) even though this variable is a local `auto' - or a local `register' variable. In effect, what has happened - is that the reload pass has seen that all assignments and - references for one such a local variable can be replaced by - equivalent assignments and references to some static storage - variable, thereby avoiding the need for a register. In such - cases we're forced to lie to debuggers and tell them that - this variable was itself `static'. */ - PUT_SDB_DEF (name); - PUT_SDB_VAL (XEXP (XEXP (value, 0), 0)); - PUT_SDB_SCL (C_STAT); - } - else - { - /* It is something we don't know how to represent for SDB. */ - return; - } - break; - - default: - break; - } - PUT_SDB_TYPE (plain_type (type)); - PUT_SDB_ENDEF; -} - -/* Output SDB information for a top-level initialized variable - that has been delayed. */ - -void -sdbout_toplevel_data (decl) - tree decl; -{ - tree type = TREE_TYPE (decl); - - if (DECL_IGNORED_P (decl)) - return; - - if (! (TREE_CODE (decl) == VAR_DECL - && GET_CODE (DECL_RTL (decl)) == MEM - && DECL_INITIAL (decl))) - abort (); - - PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); - PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); - if (TREE_PUBLIC (decl)) - { - PUT_SDB_SCL (C_EXT); - } - else - { - PUT_SDB_SCL (C_STAT); - } - PUT_SDB_TYPE (plain_type (type)); - PUT_SDB_ENDEF; -} - -#ifdef SDB_ALLOW_FORWARD_REFERENCES - -/* Machinery to record and output anonymous types. */ - -static tree anonymous_types; - -static void -sdbout_queue_anonymous_type (type) - tree type; -{ - anonymous_types = saveable_tree_cons (NULL_TREE, type, anonymous_types); -} - -static void -sdbout_dequeue_anonymous_types () -{ - register tree types, link; - - while (anonymous_types) - { - types = nreverse (anonymous_types); - anonymous_types = NULL_TREE; - - for (link = types; link; link = TREE_CHAIN (link)) - { - register tree type = TREE_VALUE (link); - - if (type && ! TREE_ASM_WRITTEN (type)) - sdbout_one_type (type); - } - } -} - -#endif - -/* Given a chain of ..._TYPE nodes, all of which have names, - output definitions of those names, as typedefs. */ - -void -sdbout_types (types) - register tree types; -{ - register tree link; - - for (link = types; link; link = TREE_CHAIN (link)) - sdbout_one_type (link); - -#ifdef SDB_ALLOW_FORWARD_REFERENCES - sdbout_dequeue_anonymous_types (); -#endif -} - -static void -sdbout_type (type) - tree type; -{ - if (type == error_mark_node) - type = integer_type_node; - PUT_SDB_TYPE (plain_type (type)); -} - -/* Output types of the fields of type TYPE, if they are structs. - - Formerly did not chase through pointer types, since that could be circular. - They must come before TYPE, since forward refs are not allowed. - Now james@bigtex.cactus.org says to try them. */ - -static void -sdbout_field_types (type) - tree type; -{ - tree tail; - - for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail)) - /* This condition should match the one for emitting the actual members - below. */ - if (TREE_CODE (tail) == FIELD_DECL - && DECL_NAME (tail) != 0 - && TREE_CODE (DECL_SIZE (tail)) == INTEGER_CST - && TREE_CODE (DECL_FIELD_BITPOS (tail)) == INTEGER_CST) - { - if (POINTER_TYPE_P (TREE_TYPE (tail))) - sdbout_one_type (TREE_TYPE (TREE_TYPE (tail))); - else - sdbout_one_type (TREE_TYPE (tail)); - } -} - -/* Use this to put out the top level defined record and union types - for later reference. If this is a struct with a name, then put that - name out. Other unnamed structs will have .xxfake labels generated so - that they may be referred to later. - The label will be stored in the KNOWN_TYPE_TAG slot of a type. - It may NOT be called recursively. */ - -static void -sdbout_one_type (type) - tree type; -{ - if (current_function_decl != NULL_TREE - && DECL_SECTION_NAME (current_function_decl) != NULL_TREE) - ; /* Don't change section amid function. */ - else - text_section (); - - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - case ENUMERAL_TYPE: - type = TYPE_MAIN_VARIANT (type); - /* Don't output a type twice. */ - if (TREE_ASM_WRITTEN (type)) - /* James said test TREE_ASM_BEING_WRITTEN here. */ - return; - - /* Output nothing if type is not yet defined. */ - if (TYPE_SIZE (type) == 0) - return; - - TREE_ASM_WRITTEN (type) = 1; -#if 1 - /* This is reputed to cause trouble with the following case, - but perhaps checking TYPE_SIZE above will fix it. */ - - /* Here is a test case: - - struct foo { - struct badstr *bbb; - } forwardref; - - typedef struct intermediate { - int aaaa; - } intermediate_ref; - - typedef struct badstr { - int ccccc; - } badtype; */ - -#if 0 - TREE_ASM_BEING_WRITTEN (type) = 1; -#endif - /* This change, which ought to make better output, - used to make the COFF assembler unhappy. - Changes involving KNOWN_TYPE_TAG may fix the problem. */ - /* Before really doing anything, output types we want to refer to. */ - /* Note that in version 1 the following two lines - are not used if forward references are in use. */ - if (TREE_CODE (type) != ENUMERAL_TYPE) - sdbout_field_types (type); -#if 0 - TREE_ASM_WRITTEN (type) = 1; -#endif -#endif - - /* Output a structure type. */ - { - int size = int_size_in_bytes (type); - int member_scl; - tree tem; - int i, n_baseclasses = 0; - - /* Record the type tag, but not in its permanent place just yet. */ - sdbout_record_type_name (type); - - PUT_SDB_DEF (KNOWN_TYPE_TAG (type)); - - switch (TREE_CODE (type)) - { - case UNION_TYPE: - case QUAL_UNION_TYPE: - PUT_SDB_SCL (C_UNTAG); - PUT_SDB_TYPE (T_UNION); - member_scl = C_MOU; - break; - - case RECORD_TYPE: - PUT_SDB_SCL (C_STRTAG); - PUT_SDB_TYPE (T_STRUCT); - member_scl = C_MOS; - break; - - case ENUMERAL_TYPE: - PUT_SDB_SCL (C_ENTAG); - PUT_SDB_TYPE (T_ENUM); - member_scl = C_MOE; - break; - - default: - break; - } - - PUT_SDB_SIZE (size); - PUT_SDB_ENDEF; - - /* Print out the base class information with fields - named after the types they hold. */ - /* This is only relevent to aggregate types. TYPE_BINFO is used - for other purposes in an ENUMERAL_TYPE, so we must exclude that - case. */ - if (TREE_CODE (type) != ENUMERAL_TYPE) - { - if (TYPE_BINFO (type) - && TYPE_BINFO_BASETYPES (type)) - n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); - for (i = 0; i < n_baseclasses; i++) - { - tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), - i); - tree child_type = BINFO_TYPE (child); - tree child_type_name; - if (TYPE_NAME (child_type) == 0) - continue; - if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE) - child_type_name = TYPE_NAME (child_type); - else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL) - { - child_type_name = DECL_NAME (TYPE_NAME (child_type)); - if (child_type_name && template_name_p (child_type_name)) - child_type_name - = DECL_ASSEMBLER_NAME (TYPE_NAME (child_type)); - } - else - continue; - - CONTIN; - PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name)); - PUT_SDB_INT_VAL (TREE_INT_CST_LOW (BINFO_OFFSET (child))); - PUT_SDB_SCL (member_scl); - sdbout_type (BINFO_TYPE (child)); - PUT_SDB_ENDEF; - } - } - - /* output the individual fields */ - - if (TREE_CODE (type) == ENUMERAL_TYPE) - for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) - { - PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem))); - PUT_SDB_INT_VAL (TREE_INT_CST_LOW (TREE_VALUE (tem))); - PUT_SDB_SCL (C_MOE); - PUT_SDB_TYPE (T_MOE); - PUT_SDB_ENDEF; - } - - else /* record or union type */ - for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) - /* Output the name, type, position (in bits), size (in bits) - of each field. */ - - /* Omit here the nameless fields that are used to skip bits. - Also omit fields with variable size or position. - Also omit non FIELD_DECL nodes that GNU C++ may put here. */ - if (TREE_CODE (tem) == FIELD_DECL - && DECL_NAME (tem) != 0 - && TREE_CODE (DECL_SIZE (tem)) == INTEGER_CST - && TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST) - { - char *name; - - CONTIN; - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)); - PUT_SDB_DEF (name); - if (DECL_BIT_FIELD_TYPE (tem)) - { - PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))); - PUT_SDB_SCL (C_FIELD); - sdbout_type (DECL_BIT_FIELD_TYPE (tem)); - PUT_SDB_SIZE (TREE_INT_CST_LOW (DECL_SIZE (tem))); - } - else - { - PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)) - / BITS_PER_UNIT); - PUT_SDB_SCL (member_scl); - sdbout_type (TREE_TYPE (tem)); - } - PUT_SDB_ENDEF; - } - /* output end of a structure,union, or enumeral definition */ - - PUT_SDB_PLAIN_DEF ("eos"); - PUT_SDB_INT_VAL (size); - PUT_SDB_SCL (C_EOS); - PUT_SDB_TAG (KNOWN_TYPE_TAG (type)); - PUT_SDB_SIZE (size); - PUT_SDB_ENDEF; - break; - - default: - break; - } - } -} - -/* The following two functions output definitions of function parameters. - Each parameter gets a definition locating it in the parameter list. - Each parameter that is a register variable gets a second definition - locating it in the register. - - Printing or argument lists in gdb uses the definitions that - locate in the parameter list. But reference to the variable in - expressions uses preferentially the definition as a register. */ - -/* Output definitions, referring to storage in the parmlist, - of all the parms in PARMS, which is a chain of PARM_DECL nodes. */ - -static void -sdbout_parms (parms) - tree parms; -{ - for (; parms; parms = TREE_CHAIN (parms)) - if (DECL_NAME (parms)) - { - int current_sym_value = 0; - char *name = IDENTIFIER_POINTER (DECL_NAME (parms)); - - if (name == 0 || *name == 0) - name = gen_fake_label (); - - /* Perform any necessary register eliminations on the parameter's rtl, - so that the debugging output will be accurate. */ - DECL_INCOMING_RTL (parms) - = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX); - DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX); - - if (PARM_PASSED_IN_MEMORY (parms)) - { - rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0); - tree type; - - /* ??? Here we assume that the parm address is indexed - off the frame pointer or arg pointer. - If that is not true, we produce meaningless results, - but do not crash. */ - if (GET_CODE (addr) == PLUS - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - current_sym_value = INTVAL (XEXP (addr, 1)); - else - current_sym_value = 0; - - if (GET_CODE (DECL_RTL (parms)) == REG - && REGNO (DECL_RTL (parms)) >= 0 - && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) - type = DECL_ARG_TYPE (parms); - else - { - int original_sym_value = current_sym_value; - - /* This is the case where the parm is passed as an int or - double and it is converted to a char, short or float - and stored back in the parmlist. In this case, describe - the parm with the variable's declared type, and adjust - the address if the least significant bytes (which we are - using) are not the first ones. */ - if (BYTES_BIG_ENDIAN - && TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) - current_sym_value += - (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) - - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); - - if (GET_CODE (DECL_RTL (parms)) == MEM - && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS - && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) - == CONST_INT) - && (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) - == current_sym_value)) - type = TREE_TYPE (parms); - else - { - current_sym_value = original_sym_value; - type = DECL_ARG_TYPE (parms); - } - } - - PUT_SDB_DEF (name); - PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, addr)); - PUT_SDB_SCL (C_ARG); - PUT_SDB_TYPE (plain_type (type)); - PUT_SDB_ENDEF; - } - else if (GET_CODE (DECL_RTL (parms)) == REG) - { - rtx best_rtl; - /* Parm passed in registers and lives in registers or nowhere. */ - - /* If parm lives in a register, use that register; - pretend the parm was passed there. It would be more consistent - to describe the register where the parm was passed, - but in practice that register usually holds something else. */ - if (REGNO (DECL_RTL (parms)) >= 0 - && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) - best_rtl = DECL_RTL (parms); - /* If the parm lives nowhere, - use the register where it was passed. */ - else - best_rtl = DECL_INCOMING_RTL (parms); - - PUT_SDB_DEF (name); - PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl))); - PUT_SDB_SCL (C_REGPARM); - PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); - PUT_SDB_ENDEF; - } - else if (GET_CODE (DECL_RTL (parms)) == MEM - && XEXP (DECL_RTL (parms), 0) != const0_rtx) - { - /* Parm was passed in registers but lives on the stack. */ - - /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))), - in which case we want the value of that CONST_INT, - or (MEM (REG ...)) or (MEM (MEM ...)), - in which case we use a value of zero. */ - if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG - || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM) - current_sym_value = 0; - else - current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)); - - /* Again, this assumes the offset is based on the arg pointer. */ - PUT_SDB_DEF (name); - PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, - XEXP (DECL_RTL (parms), 0))); - PUT_SDB_SCL (C_ARG); - PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); - PUT_SDB_ENDEF; - } - } -} - -/* Output definitions for the places where parms live during the function, - when different from where they were passed, when the parms were passed - in memory. - - It is not useful to do this for parms passed in registers - that live during the function in different registers, because it is - impossible to look in the passed register for the passed value, - so we use the within-the-function register to begin with. - - PARMS is a chain of PARM_DECL nodes. */ - -static void -sdbout_reg_parms (parms) - tree parms; -{ - for (; parms; parms = TREE_CHAIN (parms)) - if (DECL_NAME (parms)) - { - char *name = IDENTIFIER_POINTER (DECL_NAME (parms)); - - /* Report parms that live in registers during the function - but were passed in memory. */ - if (GET_CODE (DECL_RTL (parms)) == REG - && REGNO (DECL_RTL (parms)) >= 0 - && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER - && PARM_PASSED_IN_MEMORY (parms)) - { - if (name == 0 || *name == 0) - name = gen_fake_label (); - PUT_SDB_DEF (name); - PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)))); - PUT_SDB_SCL (C_REG); - PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); - PUT_SDB_ENDEF; - } - /* Report parms that live in memory but not where they were passed. */ - else if (GET_CODE (DECL_RTL (parms)) == MEM - && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS - && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT - && PARM_PASSED_IN_MEMORY (parms) - && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms))) - { -#if 0 /* ??? It is not clear yet what should replace this. */ - int offset = DECL_OFFSET (parms) / BITS_PER_UNIT; - /* A parm declared char is really passed as an int, - so it occupies the least significant bytes. - On a big-endian machine those are not the low-numbered ones. */ - if (BYTES_BIG_ENDIAN - && offset != -1 - && TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) - offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) - - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); - if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...} -#endif - { - if (name == 0 || *name == 0) - name = gen_fake_label (); - PUT_SDB_DEF (name); - PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET - (XEXP (DECL_RTL (parms), 0))); - PUT_SDB_SCL (C_AUTO); - PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); - PUT_SDB_ENDEF; - } - } - } -} - -/* Describe the beginning of an internal block within a function. - Also output descriptions of variables defined in this block. - - N is the number of the block, by order of beginning, counting from 1, - and not counting the outermost (function top-level) block. - The blocks match the BLOCKs in DECL_INITIAL (current_function_decl), - if the count starts at 0 for the outermost one. */ - -void -sdbout_begin_block (file, line, n) - FILE *file; - int line; - int n; -{ - tree decl = current_function_decl; - MAKE_LINE_SAFE (line); - - /* The SCO compiler does not emit a separate block for the function level - scope, so we avoid it here also. However, mips ECOFF compilers do emit - a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined. */ -#ifndef MIPS_DEBUGGING_INFO - if (n != 1) -#endif - PUT_SDB_BLOCK_START (line - sdb_begin_function_line); - - if (n == 1) - { - /* Include the outermost BLOCK's variables in block 1. */ - next_block_number = 0; - do_block = 0; - sdbout_block (DECL_INITIAL (decl)); - } - /* If -g1, suppress all the internal symbols of functions - except for arguments. */ - if (debug_info_level != DINFO_LEVEL_TERSE) - { - next_block_number = 0; - do_block = n; - sdbout_block (DECL_INITIAL (decl)); - } - -#ifdef SDB_ALLOW_FORWARD_REFERENCES - sdbout_dequeue_anonymous_types (); -#endif -} - -/* Describe the end line-number of an internal block within a function. */ - -void -sdbout_end_block (file, line, n) - FILE *file; - int line; - int n; -{ - MAKE_LINE_SAFE (line); - - /* The SCO compiler does not emit a separate block for the function level - scope, so we avoid it here also. However, mips ECOFF compilers do emit - a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined. */ -#ifndef MIPS_DEBUGGING_INFO - if (n != 1) -#endif - PUT_SDB_BLOCK_END (line - sdb_begin_function_line); -} - -/* Output sdb info for the current function name. - Called from assemble_start_function. */ - -void -sdbout_mark_begin_function () -{ - sdbout_symbol (current_function_decl, 0); -} - -/* Called at beginning of function body (after prologue). - Record the function's starting line number, so we can output - relative line numbers for the other lines. - Describe beginning of outermost block. - Also describe the parameter list. */ - -void -sdbout_begin_function (line) - int line; -{ - sdb_begin_function_line = line - 1; - PUT_SDB_FUNCTION_START (line); - sdbout_parms (DECL_ARGUMENTS (current_function_decl)); - sdbout_reg_parms (DECL_ARGUMENTS (current_function_decl)); -} - -/* Called at end of function (before epilogue). - Describe end of outermost block. */ - -void -sdbout_end_function (line) - int line; -{ -#ifdef SDB_ALLOW_FORWARD_REFERENCES - sdbout_dequeue_anonymous_types (); -#endif - - MAKE_LINE_SAFE (line); - PUT_SDB_FUNCTION_END (line - sdb_begin_function_line); - - /* Indicate we are between functions, for line-number output. */ - sdb_begin_function_line = -1; -} - -/* Output sdb info for the absolute end of a function. - Called after the epilogue is output. */ - -void -sdbout_end_epilogue () -{ - char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)); - PUT_SDB_EPILOGUE_END (name); -} - -/* Output sdb info for the given label. Called only if LABEL_NAME (insn) - is present. */ - -void -sdbout_label (insn) - register rtx insn; -{ - PUT_SDB_DEF (LABEL_NAME (insn)); - PUT_SDB_VAL (insn); - PUT_SDB_SCL (C_LABEL); - PUT_SDB_TYPE (T_NULL); - PUT_SDB_ENDEF; -} - -/* Change to reading from a new source file. */ - -void -sdbout_start_new_source_file (filename) - char *filename; -{ -#ifdef MIPS_DEBUGGING_INFO - struct sdb_file *n = (struct sdb_file *) xmalloc (sizeof *n); - - n->next = current_file; - n->name = filename; - current_file = n; - PUT_SDB_SRC_FILE (filename); -#endif -} - -/* Revert to reading a previous source file. */ - -void -sdbout_resume_previous_source_file () -{ -#ifdef MIPS_DEBUGGING_INFO - struct sdb_file *next; - - next = current_file->next; - free (current_file); - current_file = next; - PUT_SDB_SRC_FILE (current_file->name); -#endif -} - -#endif /* SDB_DEBUGGING_INFO */ diff --git a/gcc/sdbout.h b/gcc/sdbout.h deleted file mode 100755 index dcbd6c1..0000000 --- a/gcc/sdbout.h +++ /dev/null @@ -1,39 +0,0 @@ -/* sdbout.h - Various declarations for functions found in sdbout.c - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -extern void sdbout_init PROTO ((FILE *, char*, tree)); - -extern void sdbout_begin_function PROTO ((int)); -extern void sdbout_end_function PROTO ((int)); - -extern void sdbout_begin_block PROTO ((FILE *, int, int)); -extern void sdbout_end_block PROTO ((FILE *, int, int)); - -extern void sdbout_label PROTO ((rtx)); -extern void sdbout_symbol PROTO ((tree, int)); -extern void sdbout_toplevel_data PROTO ((tree)); -extern void sdbout_types PROTO ((tree)); - -extern void sdbout_end_epilogue PROTO ((void)); - -extern void sdbout_start_new_source_file PROTO ((char *)); -extern void sdbout_resume_previous_source_file PROTO ((void)); -extern void sdbout_mark_begin_function PROTO ((void)); - diff --git a/gcc/stab.def b/gcc/stab.def deleted file mode 100755 index 81d442a..0000000 --- a/gcc/stab.def +++ /dev/null @@ -1,234 +0,0 @@ -/* Table of DBX symbol codes for the GNU system. - Copyright (C) 1988, 1997, 1998 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* This contains contribution from Cygnus Support. */ - -/* Global variable. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_GSYM, 0x20, "GSYM") - -/* Function name for BSD Fortran. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_FNAME, 0x22, "FNAME") - -/* Function name or text-segment variable for C. Value is its address. - Desc is supposedly starting line number, but GCC doesn't set it - and DBX seems not to miss it. */ -__define_stab (N_FUN, 0x24, "FUN") - -/* Data-segment variable with internal linkage. Value is its address. - "Static Sym". */ -__define_stab (N_STSYM, 0x26, "STSYM") - -/* BSS-segment variable with internal linkage. Value is its address. */ -__define_stab (N_LCSYM, 0x28, "LCSYM") - -/* Name of main routine. Only the name is significant. - This is not used in C. */ -__define_stab (N_MAIN, 0x2a, "MAIN") - -/* Global symbol in Pascal. - Supposedly the value is its line number; I'm skeptical. */ -__define_stab (N_PC, 0x30, "PC") - -/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */ -__define_stab (N_NSYMS, 0x32, "NSYMS") - -/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */ -__define_stab (N_NOMAP, 0x34, "NOMAP") - -/* New stab from Solaris. I don't know what it means, but it - don't seem to contain useful information. */ -__define_stab (N_OBJ, 0x38, "OBJ") - -/* New stab from Solaris. I don't know what it means, but it - don't seem to contain useful information. Possibly related to the - optimization flags used in this module. */ -__define_stab (N_OPT, 0x3c, "OPT") - -/* Register variable. Value is number of register. */ -__define_stab (N_RSYM, 0x40, "RSYM") - -/* Modula-2 compilation unit. Can someone say what info it contains? */ -__define_stab (N_M2C, 0x42, "M2C") - -/* Line number in text segment. Desc is the line number; - value is corresponding address. */ -__define_stab (N_SLINE, 0x44, "SLINE") - -/* Similar, for data segment. */ -__define_stab (N_DSLINE, 0x46, "DSLINE") - -/* Similar, for bss segment. */ -__define_stab (N_BSLINE, 0x48, "BSLINE") - -/* Sun's source-code browser stabs. ?? Don't know what the fields are. - Supposedly the field is "path to associated .cb file". THIS VALUE - OVERLAPS WITH N_BSLINE! */ -__define_stab (N_BROWS, 0x48, "BROWS") - -/* GNU Modula-2 definition module dependency. Value is the modification time - of the definition file. Other is non-zero if it is imported with the - GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there - are enough empty fields? */ -__define_stab(N_DEFD, 0x4a, "DEFD") - -/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2 - and one is for C++. Still,... */ -/* GNU C++ exception variable. Name is variable name. */ -__define_stab (N_EHDECL, 0x50, "EHDECL") -/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */ -__define_stab (N_MOD2, 0x50, "MOD2") - -/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if - this entry is immediately followed by a CAUGHT stab saying what exception - was caught. Multiple CAUGHT stabs means that multiple exceptions - can be caught here. If Desc is 0, it means all exceptions are caught - here. */ -__define_stab (N_CATCH, 0x54, "CATCH") - -/* Structure or union element. Value is offset in the structure. */ -__define_stab (N_SSYM, 0x60, "SSYM") - -/* Name of main source file. - Value is starting text address of the compilation. */ -__define_stab (N_SO, 0x64, "SO") - -/* Automatic variable in the stack. Value is offset from frame pointer. - Also used for type descriptions. */ -__define_stab (N_LSYM, 0x80, "LSYM") - -/* Beginning of an include file. Only Sun uses this. - In an object file, only the name is significant. - The Sun linker puts data into some of the other fields. */ -__define_stab (N_BINCL, 0x82, "BINCL") - -/* Name of sub-source file (#include file). - Value is starting text address of the compilation. */ -__define_stab (N_SOL, 0x84, "SOL") - -/* Parameter variable. Value is offset from argument pointer. - (On most machines the argument pointer is the same as the frame pointer. */ -__define_stab (N_PSYM, 0xa0, "PSYM") - -/* End of an include file. No name. - This and N_BINCL act as brackets around the file's output. - In an object file, there is no significant data in this entry. - The Sun linker puts data into some of the fields. */ -__define_stab (N_EINCL, 0xa2, "EINCL") - -/* Alternate entry point. Value is its address. */ -__define_stab (N_ENTRY, 0xa4, "ENTRY") - -/* Beginning of lexical block. - The desc is the nesting level in lexical blocks. - The value is the address of the start of the text for the block. - The variables declared inside the block *precede* the N_LBRAC symbol. */ -__define_stab (N_LBRAC, 0xc0, "LBRAC") - -/* Place holder for deleted include file. Replaces a N_BINCL and everything - up to the corresponding N_EINCL. The Sun linker generates these when - it finds multiple identical copies of the symbols from an include file. - This appears only in output from the Sun linker. */ -__define_stab (N_EXCL, 0xc2, "EXCL") - -/* Modula-2 scope information. Can someone say what info it contains? */ -__define_stab (N_SCOPE, 0xc4, "SCOPE") - -/* End of a lexical block. Desc matches the N_LBRAC's desc. - The value is the address of the end of the text for the block. */ -__define_stab (N_RBRAC, 0xe0, "RBRAC") - -/* Begin named common block. Only the name is significant. */ -__define_stab (N_BCOMM, 0xe2, "BCOMM") - -/* End named common block. Only the name is significant - (and it should match the N_BCOMM). */ -__define_stab (N_ECOMM, 0xe4, "ECOMM") - -/* End common (local name): value is address. - I'm not sure how this is used. */ -__define_stab (N_ECOML, 0xe8, "ECOML") - -/* These STAB's are used on Gould systems for Non-Base register symbols - or something like that. FIXME. I have assigned the values at random - since I don't have a Gould here. Fixups from Gould folk welcome... */ -__define_stab (N_NBTEXT, 0xF0, "NBTEXT") -__define_stab (N_NBDATA, 0xF2, "NBDATA") -__define_stab (N_NBBSS, 0xF4, "NBBSS") -__define_stab (N_NBSTS, 0xF6, "NBSTS") -__define_stab (N_NBLCS, 0xF8, "NBLCS") - -/* Second symbol entry containing a length-value for the preceding entry. - The value is the length. */ -__define_stab (N_LENG, 0xfe, "LENG") - -/* The above information, in matrix format. - - STAB MATRIX - _________________________________________________ - | 00 - 1F are not dbx stab symbols | - | In most cases, the low bit is the EXTernal bit| - - | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA | - | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT | - - | 08 BSS | 0A INDR | 0C FN_SEQ | 0E | - | 09 |EXT | 0B | 0D | 0F | - - | 10 | 12 COMM | 14 SETA | 16 SETT | - | 11 | 13 | 15 | 17 | - - | 18 SETD | 1A SETB | 1C SETV | 1E WARNING| - | 19 | 1B | 1D | 1F FN | - - |_______________________________________________| - | Debug entries with bit 01 set are unused. | - | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM | - | 28 LCSYM | 2A MAIN | 2C | 2E | - | 30 PC | 32 NSYMS | 34 NOMAP | 36 | - | 38 OBJ | 3A | 3C OPT | 3E | - | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE | - | 48 BSLINE*| 4A DEFD | 4C | 4E | - | 50 EHDECL*| 52 | 54 CATCH | 56 | - | 58 | 5A | 5C | 5E | - | 60 SSYM | 62 | 64 SO | 66 | - | 68 | 6A | 6C | 6E | - | 70 | 72 | 74 | 76 | - | 78 | 7A | 7C | 7E | - | 80 LSYM | 82 BINCL | 84 SOL | 86 | - | 88 | 8A | 8C | 8E | - | 90 | 92 | 94 | 96 | - | 98 | 9A | 9C | 9E | - | A0 PSYM | A2 EINCL | A4 ENTRY | A6 | - | A8 | AA | AC | AE | - | B0 | B2 | B4 | B6 | - | B8 | BA | BC | BE | - | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 | - | C8 | CA | CC | CE | - | D0 | D2 | D4 | D6 | - | D8 | DA | DC | DE | - | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 | - | E8 ECOML | EA | EC | EE | - | F0 | F2 | F4 | F6 | - | F8 | FA | FC | FE LENG | - +-----------------------------------------------+ - * 50 EHDECL is also MOD2. - * 48 BSLINE is also BROWS. - */ diff --git a/gcc/toplev.c b/gcc/toplev.c index 41a4459..3582b76 100755 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -55,57 +55,13 @@ Boston, MA 02111-1307, USA. */ #include "range.h" /* END CYGNUS LOCAL */ -#ifdef DWARF_DEBUGGING_INFO -#include "dwarfout.h" -#endif - #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) #include "dwarf2out.h" #endif -#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) -#include "dbxout.h" -#endif - -#ifdef SDB_DEBUGGING_INFO -#include "sdbout.h" -#endif - -#ifdef XCOFF_DEBUGGING_INFO -#include "xcoffout.h" -#endif - - -#ifndef DEFAULT_GDB_EXTENSIONS -#define DEFAULT_GDB_EXTENSIONS 1 -#endif - -/* If more than one debugging type is supported, you must define - PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way. - - This is one long line cause VAXC can't handle a \-newline. */ -#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO)) -#ifndef PREFERRED_DEBUGGING_TYPE -You Lose! You must define PREFERRED_DEBUGGING_TYPE! -#endif /* no PREFERRED_DEBUGGING_TYPE */ -#else /* Only one debugging format supported. Define PREFERRED_DEBUGGING_TYPE - so the following code needn't care. */ -#ifdef DBX_DEBUGGING_INFO -#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG -#endif -#ifdef SDB_DEBUGGING_INFO -#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG -#endif -#ifdef DWARF_DEBUGGING_INFO -#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG -#endif #ifdef DWARF2_DEBUGGING_INFO #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG #endif -#ifdef XCOFF_DEBUGGING_INFO -#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG -#endif -#endif /* More than one debugger format enabled. */ /* If still not defined, must have been because no debugging formats are supported. */ @@ -298,12 +254,6 @@ enum debug_info_type write_symbols = NO_DEBUG; for the definitions of the different possible levels. */ enum debug_info_level debug_info_level = DINFO_LEVEL_NONE; -/* Nonzero means use GNU-only extensions in the generated symbolic - debugging information. */ -/* Currently, this only has an effect when write_symbols is set to - DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */ -int use_gnu_debug_info_extensions = 0; - /* Nonzero means do optimizations. -O. Particular numeric values stand for particular amounts of optimization; thus, -O2 stores 2 here. However, the optimizations beyond the basic @@ -698,9 +648,6 @@ int flag_unaligned_pointers = 0; /* Enable live range splitting. */ int flag_live_range = 0; -/* Enable/disable using GDB extensions for denoting live ranges. */ -int flag_live_range_gdb = LIVE_RANGE_GDB_DEFAULT; - /* Create scoping blocks for live ranges when debugging. */ int flag_live_range_scope = LIVE_RANGE_SCOPE_DEFAULT; /* END CYGNUS LOCAL */ @@ -747,32 +694,13 @@ static struct /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a constant expression, we use NO_DEBUG in its place. */ enum debug_info_type debug_type; - int use_extensions_p; char * description; } *da, debug_args[] = { - { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS, - "Generate default debug format output" }, - { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" }, -#ifdef DBX_DEBUGGING_INFO - { "gstabs", DBX_DEBUG, 0, "Generate STABS format debug output" }, - { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" }, -#endif -#ifdef DWARF_DEBUGGING_INFO - { "gdwarf", DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"}, - { "gdwarf+", DWARF_DEBUG, 1, - "Generated extended DWARF-1 format debug output" }, -#endif + { "g", NO_DEBUG, "Generate default debug format output" }, #ifdef DWARF2_DEBUGGING_INFO - { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" }, -#endif -#ifdef XCOFF_DEBUGGING_INFO - { "gxcoff", XCOFF_DEBUG, 0, "Generate XCOFF format debug output" }, - { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" }, -#endif -#ifdef SDB_DEBUGGING_INFO - { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" }, + { "gdwarf-2", DWARF2_DEBUG, "Enable DWARF-2 debug output" }, #endif { 0, 0, 0, 0 } }; @@ -931,8 +859,6 @@ lang_independent_options f_options[] = /* CYGNUS LOCAL LRS */ {"live-range", &flag_live_range, 1, "Enable live range splitting" }, - {"live-range-gdb", &flag_live_range_gdb, 1, - "Use GDB extensions to denote live ranges" }, {"live-range-scope", &flag_live_range_scope, 1, "Create scope blocks for debugging live ranges"}, /* END CYGNUS LOCAL */ @@ -2868,20 +2794,6 @@ compile_file (name) /* If dbx symbol table desired, initialize writing it and output the predefined types. */ -#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) - if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) - TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename, - getdecls ())); -#endif -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG) - TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename, - getdecls ())); -#endif -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename)); -#endif #ifdef DWARF2_UNWIND_INFO if (dwarf2out_do_frame ()) dwarf2out_frame_init (); @@ -3073,37 +2985,6 @@ compile_file (name) && ! TREE_USED (DECL_NAME (decl))) warning_with_decl (decl, "`%s' defined but not used"); -#ifdef SDB_DEBUGGING_INFO - /* The COFF linker can move initialized global vars to the end. - And that can screw up the symbol ordering. - By putting the symbols in that order to begin with, - we avoid a problem. mcsun!unido!fauern!tumuc!pes@uunet.uu.net. */ - if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL - && TREE_PUBLIC (decl) && DECL_INITIAL (decl) - && ! DECL_EXTERNAL (decl) - && DECL_RTL (decl) != 0) - TIMEVAR (symout_time, sdbout_symbol (decl, 0)); - - /* Output COFF information for non-global - file-scope initialized variables. */ - if (write_symbols == SDB_DEBUG - && TREE_CODE (decl) == VAR_DECL - && DECL_INITIAL (decl) - && ! DECL_EXTERNAL (decl) - && DECL_RTL (decl) != 0 - && GET_CODE (DECL_RTL (decl)) == MEM) - TIMEVAR (symout_time, sdbout_toplevel_data (decl)); -#endif /* SDB_DEBUGGING_INFO */ -#ifdef DWARF_DEBUGGING_INFO - /* Output DWARF information for file-scope tentative data object - declarations, file-scope (extern) function declarations (which - had no corresponding body) and file-scope tagged type declarations - and definitions which have not yet been forced out. */ - - if (write_symbols == DWARF_DEBUG - && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) - TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1)); -#endif #ifdef DWARF2_DEBUGGING_INFO /* Output DWARF2 information for file-scope tentative data object declarations, file-scope (extern) function declarations (which @@ -3122,21 +3003,7 @@ compile_file (name) weak_finish (); /* Do dbx symbols */ -#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) - if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) - TIMEVAR (symout_time, - { - dbxout_finish (asm_out_file, main_input_filename); - }); -#endif -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - TIMEVAR (symout_time, - { - dwarfout_finish (); - }); -#endif #ifdef DWARF2_UNWIND_INFO if (dwarf2out_do_frame ()) @@ -3345,38 +3212,15 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end) else error ("invalid register name `%s' for register variable", asmspec); } -#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) - else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) - && TREE_CODE (decl) == TYPE_DECL) - TIMEVAR (symout_time, dbxout_symbol (decl, 0)); -#endif -#ifdef SDB_DEBUGGING_INFO - else if (write_symbols == SDB_DEBUG && top_level - && TREE_CODE (decl) == TYPE_DECL) - TIMEVAR (symout_time, sdbout_symbol (decl, 0)); -#endif } /* Called after finishing a record, union or enumeral type. */ void rest_of_type_compilation (type, toplev) -#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO) - tree type; - int toplev; -#else tree type ATTRIBUTE_UNUSED; int toplev ATTRIBUTE_UNUSED; -#endif { -#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) - if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) - TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev)); -#endif -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG) - TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev)); -#endif } /* This is called from finish_function (within yyparse) @@ -3501,17 +3345,6 @@ rest_of_compilation (decl) optimize = saved_optimize; } -#ifdef DWARF_DEBUGGING_INFO - /* Generate the DWARF info for the "abstract" instance - of a function which we may later generate inlined and/or - out-of-line instances of. */ - if (write_symbols == DWARF_DEBUG) - { - set_decl_abstract_flags (decl, 1); - TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); - set_decl_abstract_flags (decl, 0); - } -#endif #ifdef DWARF2_DEBUGGING_INFO /* Generate the DWARF2 info for the "abstract" instance of a function which we may later generate inlined and/or @@ -3532,18 +3365,6 @@ rest_of_compilation (decl) so that its compilation will not affect what others get. */ if (inlinable || DECL_DEFER_OUTPUT (decl)) { -#ifdef DWARF_DEBUGGING_INFO - /* Generate the DWARF info for the "abstract" instance of - a function which we will generate an out-of-line instance - of almost immediately (and which we may also later generate - various inlined instances of). */ - if (write_symbols == DWARF_DEBUG) - { - set_decl_abstract_flags (decl, 1); - TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); - set_decl_abstract_flags (decl, 0); - } -#endif #ifdef DWARF2_DEBUGGING_INFO /* Generate the DWARF2 info for the "abstract" instance of a function which we will generate an out-of-line instance @@ -4204,15 +4025,7 @@ rest_of_compilation (decl) for those inline functions that need to have out-of-line copies generated. During that call, we *will* be routed past here. */ -#ifdef DBX_DEBUGGING_INFO - if (write_symbols == DBX_DEBUG) - TIMEVAR (symout_time, dbxout_function (decl)); -#endif -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); -#endif #ifdef DWARF2_DEBUGGING_INFO if (write_symbols == DWARF2_DEBUG) @@ -4226,10 +4039,6 @@ rest_of_compilation (decl) /* In case the function was not output, don't leave any temporary anonymous types queued up for sdb output. */ -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG) - sdbout_types (NULL_TREE); -#endif /* Put back the tree of subblocks and list of arguments from before we copied them. @@ -5082,9 +4891,6 @@ main (argc, argv) #if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2) type = DWARF2_DEBUG; #else -#ifdef DBX_DEBUGGING_INFO - type = DBX_DEBUG; -#endif #endif } } @@ -5115,7 +4921,6 @@ main (argc, argv) write_symbols = (level == 0 ? NO_DEBUG : selected_debug_type); - use_gnu_debug_info_extensions = da->use_extensions_p; debug_info_level = (enum debug_info_level) level; } break; @@ -5442,24 +5247,11 @@ void debug_start_source_file (filename) register char *filename; { -#ifdef DBX_DEBUGGING_INFO - if (write_symbols == DBX_DEBUG) - dbxout_start_new_source_file (filename); -#endif -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_start_new_source_file (filename); -#endif /* DWARF_DEBUGGING_INFO */ #ifdef DWARF2_DEBUGGING_INFO if (debug_info_level == DINFO_LEVEL_VERBOSE && write_symbols == DWARF2_DEBUG) dwarf2out_start_source_file (filename); #endif /* DWARF2_DEBUGGING_INFO */ -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG) - sdbout_start_new_source_file (filename); -#endif } /* Record the resumption of a source file. LINENO is the line number in @@ -5469,24 +5261,11 @@ void debug_end_source_file (lineno) register unsigned lineno ATTRIBUTE_UNUSED; { -#ifdef DBX_DEBUGGING_INFO - if (write_symbols == DBX_DEBUG) - dbxout_resume_previous_source_file (); -#endif -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_resume_previous_source_file (lineno); -#endif /* DWARF_DEBUGGING_INFO */ #ifdef DWARF2_DEBUGGING_INFO if (debug_info_level == DINFO_LEVEL_VERBOSE && write_symbols == DWARF2_DEBUG) dwarf2out_end_source_file (); #endif /* DWARF2_DEBUGGING_INFO */ -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG) - sdbout_resume_previous_source_file (); -#endif } /* Called from check_newline in c-parse.y. The `buffer' parameter contains @@ -5498,11 +5277,6 @@ debug_define (lineno, buffer) register unsigned lineno; register char *buffer; { -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_define (lineno, buffer); -#endif /* DWARF_DEBUGGING_INFO */ #ifdef DWARF2_DEBUGGING_INFO if (debug_info_level == DINFO_LEVEL_VERBOSE && write_symbols == DWARF2_DEBUG) @@ -5519,11 +5293,6 @@ debug_undef (lineno, buffer) register unsigned lineno; register char *buffer; { -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_undef (lineno, buffer); -#endif /* DWARF_DEBUGGING_INFO */ #ifdef DWARF2_DEBUGGING_INFO if (debug_info_level == DINFO_LEVEL_VERBOSE && write_symbols == DWARF2_DEBUG) diff --git a/gcc/varasm.c b/gcc/varasm.c index 04cd04f..a06ac6f 100755 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" #include <setjmp.h> -/* #include <stab.h> */ #include "rtl.h" #include "tree.h" #include "flags.h" @@ -42,15 +41,9 @@ Boston, MA 02111-1307, USA. */ #include "defaults.h" #include "real.h" #include "toplev.h" -#include "dbxout.h" -#include "sdbout.h" - #include "obstack.h" #include "c-pragma.h" -#ifdef XCOFF_DEBUGGING_INFO -#include "xcoffout.h" -#endif #ifndef TRAMPOLINE_ALIGNMENT #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY @@ -865,14 +858,12 @@ assemble_asm (string) flag_gnu_linker should be 0 on these systems, which should prevent any output if ASM_OUTPUT_CONSTRUCTOR and ASM_OUTPUT_DESTRUCTOR are absent. */ -#if !(defined(DBX_DEBUGGING_INFO) && !defined(FASCIST_ASSEMBLER)) #ifndef ASM_OUTPUT_CONSTRUCTOR #define ASM_OUTPUT_CONSTRUCTOR(file, name) #endif #ifndef ASM_OUTPUT_DESTRUCTOR #define ASM_OUTPUT_DESTRUCTOR(file, name) #endif -#endif #endif /* 0 */ /* Record an element in the table of global destructors. @@ -998,17 +989,7 @@ assemble_start_function (decl, fnname) ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname); #endif -#ifdef SDB_DEBUGGING_INFO - /* Output SDB definition of the function. */ - if (write_symbols == SDB_DEBUG) - sdbout_mark_begin_function (); -#endif -#ifdef DBX_DEBUGGING_INFO - /* Output DBX definition of the function. */ - if (write_symbols == DBX_DEBUG) - dbxout_begin_function (decl); -#endif /* Make function name accessible from other files, if appropriate. */ @@ -1294,19 +1275,6 @@ assemble_variable (decl, top_level, at_end, dont_output_data) return; TREE_ASM_WRITTEN (decl) = 1; -#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) - /* File-scope global variables are output here. */ - if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) - && top_level) - dbxout_symbol (decl, 0); -#endif -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG && top_level - /* Leave initialized global vars for end of compilation; - see comment in compile_file. */ - && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0)) - sdbout_symbol (decl, 0); -#endif /* Don't output any DWARF debugging information for variables here. In the case of local variables, the information for them is output @@ -1464,18 +1432,6 @@ assemble_variable (decl, top_level, at_end, dont_output_data) (decl, "requested alignment for %s is greater than implemented alignment of %d.",rounded); #endif -#ifdef DBX_DEBUGGING_INFO - /* File-scope global variables are output here. */ - if (write_symbols == DBX_DEBUG && top_level) - dbxout_symbol (decl, 0); -#endif -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG && top_level - /* Leave initialized global vars for end of compilation; - see comment in compile_file. */ - && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0)) - sdbout_symbol (decl, 0); -#endif /* Don't output any DWARF debugging information for variables here. In the case of local variables, the information for them is output @@ -1545,18 +1501,6 @@ assemble_variable (decl, top_level, at_end, dont_output_data) /* Output the dbx info now that we have chosen the section. */ -#ifdef DBX_DEBUGGING_INFO - /* File-scope global variables are output here. */ - if (write_symbols == DBX_DEBUG && top_level) - dbxout_symbol (decl, 0); -#endif -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG && top_level - /* Leave initialized global vars for end of compilation; - see comment in compile_file. */ - && (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0)) - sdbout_symbol (decl, 0); -#endif /* Don't output any DWARF debugging information for variables here. In the case of local variables, the information for them is output @@ -1596,27 +1540,8 @@ assemble_variable (decl, top_level, at_end, dont_output_data) } finish: -#ifdef XCOFF_DEBUGGING_INFO - /* Unfortunately, the IBM assembler cannot handle stabx before the actual - declaration. When something like ".stabx "aa:S-2",aa,133,0" is emitted - and `aa' hasn't been output yet, the assembler generates a stab entry with - a value of zero, in addition to creating an unnecessary external entry - for `aa'. Hence, we must postpone dbxout_symbol to here at the end. */ - - /* File-scope global variables are output here. */ - if (write_symbols == XCOFF_DEBUG && top_level) - { - saved_in_section = in_section; - - dbxout_symbol (decl, 0); - - if (in_section != saved_in_section) - variable_section (decl, reloc); - } -#else /* There must be a statement after a label. */ ; -#endif } /* Return 1 if type TYPE contains any pointers. */ diff --git a/gcc/version_000513.c b/gcc/version_000513.c deleted file mode 100755 index 50fbca1..0000000 --- a/gcc/version_000513.c +++ /dev/null @@ -1 +0,0 @@ -char *version_string = "2.9-arm-000512"; diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c deleted file mode 100755 index fb33f28..0000000 --- a/gcc/xcoffout.c +++ /dev/null @@ -1,545 +0,0 @@ -/* Output xcoff-format symbol table information from GNU compiler. - Copyright (C) 1992, 1994, 1995, 1997, 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Output xcoff-format symbol table data. The main functionality is contained - in dbxout.c. This file implements the sdbout-like parts of the xcoff - interface. Many functions are very similar to their counterparts in - sdbout.c. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "flags.h" -#include "toplev.h" -#include "output.h" - -#ifdef XCOFF_DEBUGGING_INFO - -/* This defines the C_* storage classes. */ -#include <dbxstclass.h> - -#include "xcoffout.h" -#include "dbxout.h" - -#if defined (USG) || !defined (HAVE_STAB_H) -#include "gstab.h" -#else -#include <stab.h> - -/* This is a GNU extension we need to reference in this file. */ -#ifndef N_CATCH -#define N_CATCH 0x54 -#endif -#endif - -/* Line number of beginning of current function, minus one. - Negative means not in a function or not using xcoff. */ - -static int xcoff_begin_function_line = -1; -static int xcoff_inlining = 0; - -/* Name of the current include file. */ - -char *xcoff_current_include_file; - -/* Name of the current function file. This is the file the `.bf' is - emitted from. In case a line is emitted from a different file, - (by including that file of course), then the line number will be - absolute. */ - -static char *xcoff_current_function_file; - -/* Names of bss and data sections. These should be unique names for each - compilation unit. */ - -char *xcoff_bss_section_name; -char *xcoff_private_data_section_name; -char *xcoff_read_only_section_name; - -/* Last source file name mentioned in a NOTE insn. */ - -char *xcoff_lastfile; - -/* Macro definitions used below. */ - -#define ABS_OR_RELATIVE_LINENO(LINENO) \ -((xcoff_inlining) ? (LINENO) : (LINENO) - xcoff_begin_function_line) - -/* Output source line numbers via ".line" rather than ".stabd". */ -#define ASM_OUTPUT_SOURCE_LINE(FILE,LINENUM) \ - do { \ - if (xcoff_begin_function_line >= 0) \ - fprintf (FILE, "\t.line\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)); \ - } while (0) - -#define ASM_OUTPUT_LFB(FILE,LINENUM) \ -{ \ - if (xcoff_begin_function_line == -1) \ - { \ - xcoff_begin_function_line = (LINENUM) - 1;\ - fprintf (FILE, "\t.bf\t%d\n", (LINENUM)); \ - } \ - xcoff_current_function_file \ - = (xcoff_current_include_file \ - ? xcoff_current_include_file : main_input_filename); \ -} - -#define ASM_OUTPUT_LFE(FILE,LINENUM) \ - do { \ - fprintf (FILE, "\t.ef\t%d\n", (LINENUM)); \ - xcoff_begin_function_line = -1; \ - } while (0) - -#define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \ - fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)) - -#define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \ - fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)) - -static void assign_type_number PROTO((tree, char *, int)); -static void xcoffout_block PROTO((tree, int, tree)); - -/* Support routines for XCOFF debugging info. */ - -/* Assign NUMBER as the stabx type number for the type described by NAME. - Search all decls in the list SYMS to find the type NAME. */ - -static void -assign_type_number (syms, name, number) - tree syms; - char *name; - int number; -{ - tree decl; - - for (decl = syms; decl; decl = TREE_CHAIN (decl)) - if (DECL_NAME (decl) - && strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name) == 0) - { - TREE_ASM_WRITTEN (decl) = 1; - TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number; - } -} - -/* Setup gcc primitive types to use the XCOFF built-in type numbers where - possible. */ - -void -xcoff_output_standard_types (syms) - tree syms; -{ - /* Handle built-in C types here. */ - - assign_type_number (syms, "int", -1); - assign_type_number (syms, "char", -2); - assign_type_number (syms, "short int", -3); - assign_type_number (syms, "long int", (TARGET_64BIT ? -31 : -4)); - assign_type_number (syms, "unsigned char", -5); - assign_type_number (syms, "signed char", -6); - assign_type_number (syms, "short unsigned int", -7); - assign_type_number (syms, "unsigned int", -8); - /* No such type "unsigned". */ - assign_type_number (syms, "long unsigned int", (TARGET_64BIT ? -32 : -10)); - assign_type_number (syms, "void", -11); - assign_type_number (syms, "float", -12); - assign_type_number (syms, "double", -13); - assign_type_number (syms, "long double", -14); - /* Pascal and Fortran types run from -15 to -29. */ - assign_type_number (syms, "wchar", -30); - assign_type_number (syms, "long long int", -31); - assign_type_number (syms, "long long unsigned int", -32); - /* Additional Fortran types run from -33 to -37. */ - - /* ??? Should also handle built-in C++ and Obj-C types. There perhaps - aren't any that C doesn't already have. */ -} - -/* Print an error message for unrecognized stab codes. */ - -#define UNKNOWN_STAB(STR) \ - do { \ - fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \ - fflush (stderr); \ - } while (0) - -/* Conversion routine from BSD stabs to AIX storage classes. */ - -int -stab_to_sclass (stab) - int stab; -{ - switch (stab) - { - case N_GSYM: - return C_GSYM; - - case N_FNAME: - UNKNOWN_STAB ("N_FNAME"); - abort(); - - case N_FUN: - return C_FUN; - - case N_STSYM: - case N_LCSYM: - return C_STSYM; - -#ifdef N_MAIN - case N_MAIN: - UNKNOWN_STAB ("N_MAIN"); - abort (); -#endif - - case N_RSYM: - return C_RSYM; - - case N_SSYM: - UNKNOWN_STAB ("N_SSYM"); - abort (); - - case N_RPSYM: - return C_RPSYM; - - case N_PSYM: - return C_PSYM; - case N_LSYM: - return C_LSYM; - case N_DECL: - return C_DECL; - case N_ENTRY: - return C_ENTRY; - - case N_SO: - UNKNOWN_STAB ("N_SO"); - abort (); - - case N_SOL: - UNKNOWN_STAB ("N_SOL"); - abort (); - - case N_SLINE: - UNKNOWN_STAB ("N_SLINE"); - abort (); - -#ifdef N_DSLINE - case N_DSLINE: - UNKNOWN_STAB ("N_DSLINE"); - abort (); -#endif - -#ifdef N_BSLINE - case N_BSLINE: - UNKNOWN_STAB ("N_BSLINE"); - abort (); -#endif -#if 0 - /* This has the same value as N_BSLINE. */ - case N_BROWS: - UNKNOWN_STAB ("N_BROWS"); - abort (); -#endif - -#ifdef N_BINCL - case N_BINCL: - UNKNOWN_STAB ("N_BINCL"); - abort (); -#endif - -#ifdef N_EINCL - case N_EINCL: - UNKNOWN_STAB ("N_EINCL"); - abort (); -#endif - -#ifdef N_EXCL - case N_EXCL: - UNKNOWN_STAB ("N_EXCL"); - abort (); -#endif - - case N_LBRAC: - UNKNOWN_STAB ("N_LBRAC"); - abort (); - - case N_RBRAC: - UNKNOWN_STAB ("N_RBRAC"); - abort (); - - case N_BCOMM: - return C_BCOMM; - case N_ECOMM: - return C_ECOMM; - case N_ECOML: - return C_ECOML; - - case N_LENG: - UNKNOWN_STAB ("N_LENG"); - abort (); - - case N_PC: - UNKNOWN_STAB ("N_PC"); - abort (); - -#ifdef N_M2C - case N_M2C: - UNKNOWN_STAB ("N_M2C"); - abort (); -#endif - -#ifdef N_SCOPE - case N_SCOPE: - UNKNOWN_STAB ("N_SCOPE"); - abort (); -#endif - - case N_CATCH: - UNKNOWN_STAB ("N_CATCH"); - abort (); - - default: - UNKNOWN_STAB ("default"); - abort (); - } -} - -/* Output debugging info to FILE to switch to sourcefile FILENAME. - INLINE_P is true if this is from an inlined function. */ - -void -xcoffout_source_file (file, filename, inline_p) - FILE *file; - char *filename; - int inline_p; -{ - if (filename - && (xcoff_lastfile == 0 || strcmp (filename, xcoff_lastfile) - || (inline_p && ! xcoff_inlining) - || (! inline_p && xcoff_inlining))) - { - if (xcoff_current_include_file) - { - fprintf (file, "\t.ei\t"); - output_quoted_string (file, xcoff_current_include_file); - fprintf (file, "\n"); - xcoff_current_include_file = NULL; - } - xcoff_inlining=inline_p; - if (strcmp (main_input_filename, filename) || inline_p) - { - fprintf (file, "\t.bi\t"); - output_quoted_string (file, filename); - fprintf (file, "\n"); - xcoff_current_include_file = filename; - } - - xcoff_lastfile = filename; - } -} - -/* Output a line number symbol entry into output stream FILE, - for source file FILENAME and line number NOTE. */ - -void -xcoffout_source_line (file, filename, note) - FILE *file; - char *filename; - rtx note; -{ - xcoffout_source_file (file, filename, RTX_INTEGRATED_P (note)); - - ASM_OUTPUT_SOURCE_LINE (file, NOTE_LINE_NUMBER (note)); -} - -/* Output the symbols defined in block number DO_BLOCK. - Set NEXT_BLOCK_NUMBER to 0 before calling. - - This function works by walking the tree structure of blocks, - counting blocks until it finds the desired block. */ - -static int do_block = 0; - -static int next_block_number; - -static void -xcoffout_block (block, depth, args) - register tree block; - int depth; - tree args; -{ - while (block) - { - /* Ignore blocks never expanded or otherwise marked as real. */ - if (TREE_USED (block)) - { - /* When we reach the specified block, output its symbols. */ - if (next_block_number == do_block) - { - /* Output the syms of the block. */ - if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) - dbxout_syms (BLOCK_VARS (block)); - if (args) - dbxout_reg_parms (args); - - /* We are now done with the block. Don't go to inner blocks. */ - return; - } - /* If we are past the specified block, stop the scan. */ - else if (next_block_number >= do_block) - return; - - next_block_number++; - - /* Output the subblocks. */ - xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE); - } - block = BLOCK_CHAIN (block); - } -} - -/* Describe the beginning of an internal block within a function. - Also output descriptions of variables defined in this block. - - N is the number of the block, by order of beginning, counting from 1, - and not counting the outermost (function top-level) block. - The blocks match the BLOCKs in DECL_INITIAL (current_function_decl), - if the count starts at 0 for the outermost one. */ - -void -xcoffout_begin_block (file, line, n) - FILE *file; - int line; - int n; -{ - tree decl = current_function_decl; - - - /* The IBM AIX compiler does not emit a .bb for the function level scope, - so we avoid it here also. */ - if (n != 1) - ASM_OUTPUT_LBB (file, line, n); - - do_block = n; - next_block_number = 0; - xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); -} - -/* Describe the end line-number of an internal block within a function. */ - -void -xcoffout_end_block (file, line, n) - FILE *file; - int line; - int n; -{ - if (n != 1) - ASM_OUTPUT_LBE (file, line, n); -} - -/* Called at beginning of function (before prologue). - Declare function as needed for debugging. */ - -void -xcoffout_declare_function (file, decl, name) - FILE *file; - tree decl; - char *name; -{ - char *n = name; - int i; - - if (*n == '*') - n++; - else - for (i = 0; name[i]; ++i) - { - if (name[i] == '[') - { - n = (char *) alloca (i + 1); - strncpy (n, name, i); - n[i] = '\0'; - break; - } - } - - /* Any pending .bi or .ei must occur before the .function pseudo op. - Otherwise debuggers will think that the function is in the previous - file and/or at the wrong line number. */ - xcoffout_source_file (file, DECL_SOURCE_FILE (decl), 0); - dbxout_symbol (decl, 0); - fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", n, n, n, n); -} - -/* Called at beginning of function body (after prologue). - Record the function's starting line number, so we can output - relative line numbers for the other lines. - Record the file name that this function is contained in. */ - -void -xcoffout_begin_function (file, last_linenum) - FILE *file; - int last_linenum; -{ - ASM_OUTPUT_LFB (file, last_linenum); - dbxout_parms (DECL_ARGUMENTS (current_function_decl)); - - /* Emit the symbols for the outermost BLOCK's variables. sdbout.c does this - in sdbout_begin_block, but there is no guarantee that there will be any - inner block 1, so we must do it here. This gives a result similar to - dbxout, so it does make some sense. */ - do_block = 0; - next_block_number = 0; - xcoffout_block (DECL_INITIAL (current_function_decl), 0, - DECL_ARGUMENTS (current_function_decl)); - - ASM_OUTPUT_SOURCE_LINE (file, last_linenum); -} - -/* Called at end of function (before epilogue). - Describe end of outermost block. */ - -void -xcoffout_end_function (file, last_linenum) - FILE *file; - int last_linenum; -{ - ASM_OUTPUT_LFE (file, last_linenum); -} - -/* Output xcoff info for the absolute end of a function. - Called after the epilogue is output. */ - -void -xcoffout_end_epilogue (file) - FILE *file; -{ - /* We need to pass the correct function size to .function, otherwise, - the xas assembler can't figure out the correct size for the function - aux entry. So, we emit a label after the last instruction which can - be used by the .function pseudo op to calculate the function size. */ - - char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); - if (*fname == '*') - ++fname; - fprintf (file, "FE.."); - ASM_OUTPUT_LABEL (file, fname); -} -#endif /* XCOFF_DEBUGGING_INFO */ diff --git a/gcc/xcoffout.h b/gcc/xcoffout.h deleted file mode 100755 index 1683a88..0000000 --- a/gcc/xcoffout.h +++ /dev/null @@ -1,211 +0,0 @@ -/* XCOFF definitions. These are needed in dbxout.c, final.c, - and xcoffout.h. - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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 2, or (at your option) -any later version. - -GNU CC 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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#define ASM_STABS_OP ".stabx" - -/* Tags and typedefs are C_DECL in XCOFF, not C_LSYM. */ - -#define DBX_TYPE_DECL_STABS_CODE N_DECL - -/* Use the XCOFF predefined type numbers. */ - -/* ??? According to metin, typedef stabx must go in text control section, - but he did not make this changes everywhere where such typedef stabx - can be emitted, so it is really needed or not? */ - -#define DBX_OUTPUT_STANDARD_TYPES(SYMS) \ -{ \ - text_section (); \ - xcoff_output_standard_types (SYMS); \ -} - -/* Any type with a negative type index has already been output. */ - -#define DBX_TYPE_DEFINED(TYPE) (TYPE_SYMTAB_ADDRESS (TYPE) < 0) - -/* Must use N_STSYM for static const variables (those in the text section) - instead of N_FUN. */ - -#define DBX_STATIC_CONST_VAR_CODE N_STSYM - -/* For static variables, output code to define the start of a static block. - - ??? The IBM rs6000/AIX assembler has a bug that causes bss block debug - info to be occasionally lost. A simple example is this: - int a; static int b; - The commands `gcc -g -c tmp.c; dump -t tmp.o' gives -[10] m 0x00000016 1 0 0x8f 0x0000 .bs -[11] m 0x00000000 1 0 0x90 0x0000 .es -... -[21] m 0x00000000 -2 0 0x85 0x0000 b:S-1 - which is wrong. The `b:S-1' must be between the `.bs' and `.es'. - We can apparently work around the problem by forcing the text section - (even if we are already in the text section) immediately before outputting - the `.bs'. This should be fixed in the next major AIX release (3.3?). */ - -#define DBX_STATIC_BLOCK_START(ASMFILE,CODE) \ -{ \ - if ((CODE) == N_STSYM) \ - fprintf ((ASMFILE), "\t.bs\t%s[RW]\n", xcoff_private_data_section_name);\ - else if ((CODE) == N_LCSYM) \ - { \ - fprintf ((ASMFILE), "%s\n", TEXT_SECTION_ASM_OP); \ - fprintf ((ASMFILE), "\t.bs\t%s\n", xcoff_bss_section_name); \ - } \ -} - -/* For static variables, output code to define the end of a static block. */ - -#define DBX_STATIC_BLOCK_END(ASMFILE,CODE) \ -{ \ - if ((CODE) == N_STSYM || (CODE) == N_LCSYM) \ - fputs ("\t.es\n", (ASMFILE)); \ -} - -/* We must use N_RPYSM instead of N_RSYM for register parameters. */ - -#define DBX_REGPARM_STABS_CODE N_RPSYM - -/* We must use 'R' instead of 'P' for register parameters. */ - -#define DBX_REGPARM_STABS_LETTER 'R' - -/* Define our own finish symbol function, since xcoff stabs have their - own different format. */ - -#define DBX_FINISH_SYMBOL(SYM) \ -{ \ - if (current_sym_addr && current_sym_code == N_FUN) \ - fprintf (asmfile, "\",."); \ - else \ - fprintf (asmfile, "\","); \ - /* If we are writing a function name, we must ensure that \ - there is no storage-class suffix on the name. */ \ - if (current_sym_addr && current_sym_code == N_FUN \ - && GET_CODE (current_sym_addr) == SYMBOL_REF) \ - { \ - char *_p = XSTR (current_sym_addr, 0); \ - if (*_p == '*') \ - fprintf (asmfile, "%s", _p+1); \ - else \ - for (; *_p != '[' && *_p; _p++) \ - fprintf (asmfile, "%c", *_p); \ - } \ - else if (current_sym_addr) \ - output_addr_const (asmfile, current_sym_addr); \ - else if (current_sym_code == N_GSYM) \ - assemble_name (asmfile, XSTR (XEXP (DECL_RTL (sym), 0), 0)); \ - else \ - fprintf (asmfile, "%d", current_sym_value); \ - fprintf (asmfile, ",%d,0\n", stab_to_sclass (current_sym_code)); \ -} - -/* These are IBM XCOFF extensions we need to reference in dbxout.c - and xcoffout.c. */ - -/* AIX XCOFF uses this for typedefs. This can have any value, since it is - only used for translation into a C_DECL storage class. */ -#ifndef N_DECL -#define N_DECL 0x8c -#endif -/* AIX XCOFF uses this for parameters passed in registers. This can have - any value, since it is only used for translation into a C_RPSYM storage - class. */ -#ifndef N_RPSYM -#define N_RPSYM 0x8e -#endif - -/* Name of the current include file. */ - -extern char *xcoff_current_include_file; - -/* Names of bss and data sections. These should be unique names for each - compilation unit. */ - -extern char *xcoff_bss_section_name; -extern char *xcoff_private_data_section_name; -extern char *xcoff_read_only_section_name; - -/* Last source file name mentioned in a NOTE insn. */ - -extern char *xcoff_lastfile; - -/* Don't write out path name for main source file. */ -#define DBX_OUTPUT_MAIN_SOURCE_DIRECTORY(FILE,FILENAME) - -/* Write out main source file name using ".file" rather than ".stabs". - We don't actually do this here, because the assembler gets confused if there - is more than one .file directive. ASM_FILE_START in config/rs6000/rs6000.h - is already emitting a .file directory, so we don't output one here also. - Initialize xcoff_lastfile. */ -#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(FILE,FILENAME) \ - xcoff_lastfile = (FILENAME) - -/* If we are still in an include file, its end must be marked. */ -#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \ -{ \ - if (xcoff_current_include_file) \ - { \ - fputs ("\t.ei\t", (FILE)); \ - output_quoted_string ((FILE), xcoff_current_include_file); \ - putc ('\n', (FILE)); \ - xcoff_current_include_file = NULL; \ - } \ -} - -/* Do not break .stabs pseudos into continuations. */ -#define DBX_CONTIN_LENGTH 0 - -/* Don't try to use the `x' type-cross-reference character in DBX data. - Also has the consequence of putting each struct, union or enum - into a separate .stabs, containing only cross-refs to the others. */ -#define DBX_NO_XREFS - -/* We must put stabs in the text section. If we don't the assembler - won't handle them correctly; it will sometimes put stabs where gdb - can't find them. */ - -#define DEBUG_SYMS_TEXT - -/* Prototype functions in xcoffout.c. */ - -extern int stab_to_sclass PROTO ((int)); -#ifdef BUFSIZ -extern void xcoffout_begin_function PROTO ((FILE *, int)); -extern void xcoffout_begin_block PROTO ((FILE *, int, int)); -extern void xcoffout_end_epilogue PROTO ((FILE *)); -extern void xcoffout_end_function PROTO ((FILE *, int)); -extern void xcoffout_end_block PROTO ((FILE *, int, int)); -#endif /* BUFSIZ */ - -#ifdef TREE_CODE -extern void xcoff_output_standard_types PROTO ((tree)); -#ifdef BUFSIZ -extern void xcoffout_declare_function PROTO ((FILE *, tree, char *)); -#endif /* BUFSIZ */ -#endif /* TREE_CODE */ - -#ifdef RTX_CODE -#ifdef BUFSIZ -extern void xcoffout_source_line PROTO ((FILE *, char *, rtx)); -#endif /* BUFSIZ */ -#endif /* RTX_CODE */ |