[comp.unix.aux] GCC/GAS problem

liam@cs.qmw.ac.uk (William Roberts) (10/05/90)

There is a nasty problem with gcc/gas as converted for A/UX to produce COFF
object files. There is an element of history involved so bear with me.

A/UX /bin/as uses the SGS mnemonics for 680x0 assembler, which allows
for an overspecified parser with special characters to donote labels and
register names, i.e. &fred is a label and %d0 is a register.

Other mnemonic systems don't have such special characters, so their languages
are actually ambiguous in that register names are effectively "reserved words"
or predefined names in the symbol table. This is true of the standard
Motorola mnemonics and the variant which the m68k.c file in gas understands.
Most other UNIX C compilers get round this by a convention which puts an
underscore on the beginning of all C variable names and labels, so that the
ambiguity is removed. This in turn leads to strange perversions in the
linker which has to believe that "lable" matches "_lable".

A/UX /bin/ld doesn't need to do this because it goes with an assembler
that doesn't suffer the ambiguity problem in the first place.....
.... except, that is, until various good people managed to add COFF support
to gas and produce a matched pair of gcc and gas for A/UX. The gcc changes
included changing the assembler format into the normal gas syntax and removing
the extra "_" from the beginnings of labels, so that gas wouldn't emit
COFF files with symbols prefixed with "_" that the /bin/ld wouldn't resolve.

Consider the following bit of code (you can guess what's coming...)

int a1, a2, a3, a4, a5, a6, a7;
int d0, d1, d2, d3, d4, d5, d6;
int cc;

main(argc,argv)
int argc;
char *argv[];
{
   a1=a2=a3=a4=a5=a6=a7=55;
   d0=d1=d2=d3=d4=d5=d6=57;
   cc =34;

   foo(&a1, &a2, &a3, &a4, &a5, &a6, &a7);
   foo(&d0, &d1, &d2, &d3, &d4, &d5, &d6);

   foo(&cc);
}

This produces error messages from gas such as

    "instruction/operands mismatch" -- Statement 'movel d1,cc' ignored
    "instruction/operands mismatch" -- Statement 'pea a7' ignored

and so on.

Question: Does the GNU version of ld handle COFF and do _foo=foo matching?

If it doesn't, then I think the following needs to be done:

1) Modify gcc again so that there is a prefix character on labels
2) Modify gas to use the prefix character to disambiguate labels/registers

I don't have a gas manual or a spec for the standard Motorola syntax, so
I don't know what character would be a good choice. I'm prepared to do
the work (eventually) if necessary.

-- 

William Roberts                 ARPA: liam@cs.qmw.ac.uk
Queen Mary & Westfield College  UUCP: liam@qmw-cs.UUCP
Mile End Road                   AppleLink: UK0087
LONDON, E1 4NS, UK              Tel:  071-975 5250 (Fax: 081-980 6533)

rmtodd@uokmax.ecn.uoknor.edu (Richard Michael Todd) (10/05/90)

liam@cs.qmw.ac.uk (William Roberts) writes:
>Motorola mnemonics and the variant which the m68k.c file in gas understands.
>Most other UNIX C compilers get round this by a convention which puts an
>underscore on the beginning of all C variable names and labels, so that the
>ambiguity is removed. This in turn leads to strange perversions in the
>linker which has to believe that "lable" matches "_lable".

[A good many non-Unix C compilers do this too, either putting a _ in front
of or at the end of symbols declared in C code.  I recall Aztec C doing
this on a PC, and I had to do something similar when I got Small-C running
on my Model I, when I noticed that declaring an "char *sp;" did interesting
things :-).  I suspect almost every C compiler that produces assembly code
does this.  Don't recall *ever* seeing a linker that mapped "_label" to
"label" or vice versa, though; most of the ones I've seen assumed that
anyone writing assembly routines to be called from C would know where this
C compiler put the "_" in label names.]

>Consider the following bit of code (you can guess what's coming...)

[code segment that uses lots of variables with the same name as registers
deleted]

>If it doesn't, then I think the following needs to be done:

>1) Modify gcc again so that there is a prefix character on labels
>2) Modify gas to use the prefix character to disambiguate labels/registers

John Coolidge has already done this, on the version of gcc/gas available for
ftp from wuarchive.wustl.edu.  (I believe the charhe's using on aregister names
is '%').  I guess this newest version hasn't made it across the Atlantic
yet.  Anyway, your program compiles with no problems on the current version 
(except that the linker objects that you never provided a function "foo" :-).

-- 
Richard Todd   rmtodd@chinet.chi.il.us  or  rmtodd@uokmax.ecn.uoknor.edu