chip@tct.uucp (Chip Salzenberg) (08/07/90)
[ Contents: Patches for GCC under SCO Unix/386 using the SCO assembler and SDB debugging information. ] This article consists of a patch and a sharchive of new files for GCC 1.37.1 under SCO Unix/386. This patch, which is the second one I have released, works with the standard SCO assembler and CodeView debugger. It also provides configuration for G++, but the modifications to G++ code I have saved for a separate article. This set of patches might be a good candidate for incorporation into the standard GCC distribution. There are a lot of SCO Unix users out there. Besides the typical porting modifications, this patch includes code to support the Microsoft C "#pragma pack()" directive. This pragma controls structure packing on a structure-by-structure basis, which feature is important under SCO Unix, and quite useful in its own right. I lifted the code from Steve Bleazard's Xenix patches. Thanks, Steve. The use of shared libraries ("-lc_s") under SCO Unix requires that the linker be called, not with crt0.o as usual, but rather with crt1.o at as the first object file and crtn.o as the last. Therefore, I added a new entry to the "spec" string of gcc: "%E", for ENDFILE_SPEC. It is defined appropriately in the SCO Unix configuration file; all versions of Unix/386 should probably define it similarly. Miscellaneous changes: SysV-specific modifications to the Makefile do NOT appear in this patch, so everyone can apply these patches without trouble. The name "stamp-extract.c" is longer than 14 characters, so SCO Unix, in a fit of POSIX compliance, won't create it. Makefile now uses the name "stamp-extract". Even if /bin/ranlib exists, you may not want to use it. SCO Unix, for example, has a "ranlib" command, but it's just a holdover from the Xenix development system. The new make variable $(RANLIB) takes care of this little hiccup. Under SCO Unix, the type "va_list" is defined in <stdio.h>, and the preprocessor macro "_VA_LIST" is used to prevent duplicate definition. So this patch changes the GNU <stdarg.h> to use the same macro. This change should be harmless on other systems. Additional notes for SCO Unix users: SCO Unix sites should set "CC" and "OLDCC" to "rcc", the AT&T compiler, and make all other modifications to the Makefile that are suggested in the comments for SysV. Specifically, include -lPW. Don't install GNU <limits.h>; SCO's version is POSIX-compliant. SCO International Language support is included with the "-scointl" flag; otherwise, it is omitted. SHAR AND ENJOY. -- Chip Salzenberg, <chip@tct.uucp> or <chip%tct@pdn.paradyne.com> Index: Makefile *************** *** 28,31 **** --- 28,34 ---- AR = ar SHELL = /bin/sh + # on SysV, define this as ":" + RANLIB = /usr/bin/ranlib + #RANLIB = : # on sysV, define this as cp. INSTALL = install -c *************** *** 144,149 **** rtl.o rtlanal.o expr.o stmt.o expmed.o explow.o optabs.o varasm.o \ symout.o dbxout.o sdbout.o emit-rtl.o insn-emit.o \ ! integrate.o jump.o cse.o loop.o flow.o stupid.o combine.o \ ! regclass.o local-alloc.o global-alloc.o reload.o reload1.o caller-save.o \ insn-peep.o final.o recog.o insn-recog.o insn-extract.o insn-output.o --- 147,152 ---- rtl.o rtlanal.o expr.o stmt.o expmed.o explow.o optabs.o varasm.o \ symout.o dbxout.o sdbout.o emit-rtl.o insn-emit.o \ ! integrate.o jump.o cse.o loop.o flow.o stupid.o combine.o regclass.o \ ! local-alloc.o global-alloc.o reload.o reload1.o caller-save.o pragma.o \ insn-peep.o final.o recog.o insn-recog.o insn-extract.o insn-output.o *************** *** 153,157 **** insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \ stamp-flags.h stamp-config.h stamp-codes.h \ ! stamp-output.c stamp-recog.c stamp-emit.c stamp-extract.c stamp-peep.c \ genemit genoutput genrecog genextract genflags gencodes genconfig genpeep \ cc1 cpp cccp # cc1plus --- 156,160 ---- insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \ stamp-flags.h stamp-config.h stamp-codes.h \ ! stamp-output.c stamp-recog.c stamp-emit.c stamp-extract stamp-peep.c \ genemit genoutput genrecog genextract genflags gencodes genconfig genpeep \ cc1 cpp cccp # cc1plus *************** *** 230,234 **** rm -f $${name}.[co]; \ done ! if [ -f /usr/bin/ranlib -o -f /bin/ranlib ] ; then ranlib tmpgnulib ;fi # Actually build it in tmpgnulib above, then rename now, # so that gnulib itself remains nonexistent if compilation is aborted. --- 233,237 ---- rm -f $${name}.[co]; \ done ! $(RANLIB) tmpgnulib # Actually build it in tmpgnulib above, then rename now, # so that gnulib itself remains nonexistent if compilation is aborted. *************** *** 248,252 **** rm -f $${name}.o; \ done ! if [ -f /usr/bin/ranlib -o -f /bin/ranlib ] ; then ranlib gnulib ;fi # On HPUX, if you are working with the GNU assembler and linker, # the previous line must be commented out. --- 251,255 ---- rm -f $${name}.o; \ done ! $(RANLIB) gnulib # On HPUX, if you are working with the GNU assembler and linker, # the previous line must be commented out. *************** *** 432,440 **** $(CC) $(CFLAGS) $(INCLUDES) -c insn-extract.c ! insn-extract.c: stamp-extract.c ; ! stamp-extract.c : md genextract ./genextract md > tmp-extract.c $(srcdir)/move-if-change tmp-extract.c insn-extract.c ! touch stamp-extract.c insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) regs.h real.h --- 435,443 ---- $(CC) $(CFLAGS) $(INCLUDES) -c insn-extract.c ! insn-extract.c: stamp-extract ; ! stamp-extract : md genextract ./genextract md > tmp-extract.c $(srcdir)/move-if-change tmp-extract.c insn-extract.c ! touch stamp-extract insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) regs.h real.h *************** *** 561,565 **** -if [ -f cc1plus ] ; then $(INSTALL) cc1plus $(libdir)/gcc-cc1plus ;fi $(INSTALL) gnulib $(libdir)/gcc-gnulib ! -if [ -f /usr/bin/ranlib ] ; then (cd $(libdir); ranlib gcc-gnulib) ;fi $(INSTALL) cpp $(libdir)/gcc-cpp $(INSTALL) gcc $(bindir) --- 564,568 ---- -if [ -f cc1plus ] ; then $(INSTALL) cc1plus $(libdir)/gcc-cc1plus ;fi $(INSTALL) gnulib $(libdir)/gcc-gnulib ! (cd $(libdir); $(RANLIB) gcc-gnulib) $(INSTALL) cpp $(libdir)/gcc-cpp $(INSTALL) gcc $(bindir) *************** *** 610,614 **** -mv $(STAGESTUFF) $(STAGE_GCC) stage1 -rm -f stage1/gnulib ! -ln gnulib stage1 || (cp gnulib stage1 && ranlib stage1/gnulib) stage2: force --- 613,617 ---- -mv $(STAGESTUFF) $(STAGE_GCC) stage1 -rm -f stage1/gnulib ! -ln gnulib stage1 || (cp gnulib stage1 && $(RANLIB) stage1/gnulib) stage2: force *************** *** 616,620 **** -mv $(STAGESTUFF) $(STAGE_GCC) stage2 -rm -f stage2/gnulib ! -ln gnulib stage2 || (cp gnulib stage2 && ranlib stage2/gnulib) stage3: force --- 619,623 ---- -mv $(STAGESTUFF) $(STAGE_GCC) stage2 -rm -f stage2/gnulib ! -ln gnulib stage2 || (cp gnulib stage2 && $(RANLIB) stage2/gnulib) stage3: force *************** *** 622,626 **** -mv $(STAGESTUFF) $(STAGE_GCC) stage3 -rm -f stage3/gnulib ! -ln gnulib stage3 || (cp gnulib stage3 && ranlib stage3/gnulib) stage4: force --- 625,629 ---- -mv $(STAGESTUFF) $(STAGE_GCC) stage3 -rm -f stage3/gnulib ! -ln gnulib stage3 || (cp gnulib stage3 && $(RANLIB) stage3/gnulib) stage4: force *************** *** 628,632 **** -mv $(STAGESTUFF) $(STAGE_GCC) stage4 -rm -f stage4/gnulib ! -ln gnulib stage4 || (cp gnulib stage4 && ranlib stage4/gnulib) TAGS: force --- 631,635 ---- -mv $(STAGESTUFF) $(STAGE_GCC) stage4 -rm -f stage4/gnulib ! -ln gnulib stage4 || (cp gnulib stage4 && $(RANLIB) stage4/gnulib) TAGS: force Index: config/xm-i386v.h *************** *** 44,47 **** #ifdef __GNUC__ ! #define alloca(n) __builtin_alloca(n) #endif --- 44,47 ---- #ifdef __GNUC__ ! #define alloca __builtin_alloca #endif Index: gcc.c *************** *** 81,84 **** --- 81,85 ---- %L process LIB_SPEC as a spec. %S process STARTFILE_SPEC as a spec. A capital S is actually used here. + %E process ENDFILE_SPEC as a spec. A capital E is actually used here. %c process SIGNED_CHAR_SPEC as a spec. %C process CPP_SPEC as a spec. A capital C is actually used here. *************** *** 194,197 **** --- 195,203 ---- #endif + /* config.h can define ENDFILE_SPEC to override the default crtn files. */ + #ifndef ENDFILE_SPEC + #define ENDFILE_SPEC "" + #endif + /* This spec is used for telling cpp whether char is signed or not. */ #define SIGNED_CHAR_SPEC \ *************** *** 288,292 **** %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\ %{y*} %{!A:%{!nostdlib:%S}} \ ! %{L*} %o %{!nostdlib:gnulib%s %{g:-lg} %L gnulib%s}\n }}}}"; /* Accumulate a command (program name and args), and run it. */ --- 294,298 ---- %{A} %{d} %{e*} %{N} %{n} %{r} %{s} %{S} %{T*} %{t} %{u*} %{X} %{x} %{z}\ %{y*} %{!A:%{!nostdlib:%S}} \ ! %{L*} %o %{!nostdlib:gnulib%s %{g:-lg} %L gnulib%s %{!A:%E}}\n }}}}"; /* Accumulate a command (program name and args), and run it. */ *************** *** 1310,1313 **** --- 1316,1323 ---- case 'S': do_spec_1 (STARTFILE_SPEC, 0); + break; + + case 'E': + do_spec_1 (ENDFILE_SPEC, 0); break; Index: c-parse.tab.c *************** *** 2906,2911 **** && getc (finput) == 'm' && getc (finput) == 'a' ! && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) goto skipline; } --- 2906,2955 ---- && getc (finput) == 'm' && getc (finput) == 'a' ! && ((c = getc (finput)) == ' ' || c == '\t')) ! { ! #ifdef PRAGMA_PACK ! int i; ! ! while ((c = getc (finput)) == ' ' || c == '\t') ! ; ! ungetc (c, finput); ! for (i = 0; i < 32; ++i) /* arbitrary pragma directive size */ ! { ! if ((c = getc (finput)) < 'a' || c > 'z') ! { ! ungetc (c, finput); ! break; ! } ! token_buffer[i] = c; ! } ! token_buffer[i] = '\0'; ! ! if (strcmp(token_buffer, "pack") != 0) ! goto skipline; ! ! if ((c = getc (finput)) != '(') ! { ! ungetc (c, finput); ! error ("invalid #pragma pack"); ! goto skipline; ! } ! ! if ((c = getc (finput)) == '1' || c == '2' || c == '4') ! { ! pragma_pack (c - '0'); ! c = getc (finput); ! } ! else ! pragma_pack_default (); ! ! if (c != ')') ! { ! ungetc (c, finput); ! error ("invalid #pragma pack"); ! goto skipline; ! } ! #endif goto skipline; + } } Index: c-parse.y *************** *** 1783,1788 **** && getc (finput) == 'm' && getc (finput) == 'a' ! && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n')) goto skipline; } --- 1783,1832 ---- && getc (finput) == 'm' && getc (finput) == 'a' ! && ((c = getc (finput)) == ' ' || c == '\t')) ! { ! #ifdef PRAGMA_PACK ! int i; ! ! while ((c = getc (finput)) == ' ' || c == '\t') ! ; ! ungetc (c, finput); ! for (i = 0; i < 32; ++i) /* arbitrary pragma directive size */ ! { ! if ((c = getc (finput)) < 'a' || c > 'z') ! { ! ungetc (c, finput); ! break; ! } ! token_buffer[i] = c; ! } ! token_buffer[i] = '\0'; ! ! if (strcmp(token_buffer, "pack") != 0) ! goto skipline; ! ! if ((c = getc (finput)) != '(') ! { ! ungetc (c, finput); ! error ("invalid #pragma pack"); ! goto skipline; ! } ! ! if ((c = getc (finput)) == '1' || c == '2' || c == '4') ! { ! pragma_pack (c - '0'); ! c = getc (finput); ! } ! else ! pragma_pack_default (); ! ! if (c != ')') ! { ! ungetc (c, finput); ! error ("invalid #pragma pack"); ! goto skipline; ! } ! #endif goto skipline; + } } Index: hard-params.c *************** *** 195,198 **** --- 195,209 ---- #include <stdio.h> + /* Kludge around the possiblity that <stdio.h> includes <limits.h> */ + #ifdef CHAR_BIT + # undef CHAR_BIT + # undef CHAR_MAX + # undef CHAR_MIN + # undef SCHAR_MAX + # undef SCHAR_MIN + # undef UCHAR_MAX + # undef UCHAR_MIN + #endif + #ifdef VERIFY #include "limits.h" Index: stdarg.h *************** *** 2,6 **** --- 2,9 ---- #define _STDARG_H + #ifndef _VA_LIST + #define _VA_LIST typedef char *va_list; + #endif /* Amount of space required in an argument list for an arg of type TYPE. Index: stor-layout.c *************** *** 499,502 **** --- 499,506 ---- layout_decl (field, var_size ? size_unit : const_size); + #ifdef PRAGMA_PACK + if (pragma_pack_seen()) + DECL_ALIGN(field) = MIN(pragma_align_val(), DECL_ALIGN(field)); + #endif desired_align = DECL_ALIGN (field); #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: config/tm-i386v-sco.h pragma.c packtest.c # Wrapped by chip@tct on Wed Aug 1 10:36:32 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'config/tm-i386v-sco.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'config/tm-i386v-sco.h'\" else echo shar: Extracting \"'config/tm-i386v-sco.h'\" \(1820 characters\) sed "s/^X//" >'config/tm-i386v-sco.h' <<'END_OF_FILE' X/* Definitions for Intel 386 running SCO Unix System V. X Copyright (C) 1988 Free Software Foundation, Inc. X XThis file is part of GNU CC. X XGNU CC is free software; you can redistribute it and/or modify Xit under the terms of the GNU General Public License as published by Xthe Free Software Foundation; either version 1, or (at your option) Xany later version. X XGNU CC is distributed in the hope that it will be useful, Xbut WITHOUT ANY WARRANTY; without even the implied warranty of XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the XGNU General Public License for more details. X XYou should have received a copy of the GNU General Public License Xalong with GNU CC; see the file COPYING. If not, write to Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ X X X/* Mostly it's like AT&T Unix System V. */ X X#include "tm-i386v.h" X X/* Support the Microsloth "#pragma pack()" directive. */ X X#define PRAGMA_PACK X X/* Version string. */ X X#undef TARGET_VERSION X#ifdef PRAGMA_PACK X#define TARGET_VERSION \ X fprintf (stderr, " (SCO 80386, #pragma pack)"); X#else X#define TARGET_VERSION \ X fprintf (stderr, " (SCO 80386)"); X#endif X X/* Use crt1.o as a startup file and crtn.o as a closing file. */ X X#undef STARTFILE_SPEC X#define STARTFILE_SPEC \ X "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}" X X#undef ENDFILE_SPEC X#define ENDFILE_SPEC \ X "crtn.o%s" X X/* Library spec, including SCO international language support. */ X X#undef LIB_SPEC X#define LIB_SPEC \ X "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} %{scointl:libintl.a%s} -lc" X X/* Specify predefined symbols in preprocessor. */ X X#undef CPP_PREDEFINES X#define CPP_PREDEFINES \ X"-Dunix -Di386 -DM_UNIX -DM_I386 -DM_COFF -DM_WORDSWAP%{scointl: -DM_INTERNAT}" X X/* SCO's assember doesn't grok '$' in labels (for g++) */ X X#define NO_DOLLAR_IN_LABEL END_OF_FILE if test 1820 -ne `wc -c <'config/tm-i386v-sco.h'`; then echo shar: \"'config/tm-i386v-sco.h'\" unpacked with wrong size! fi # end of 'config/tm-i386v-sco.h' fi if test -f 'pragma.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pragma.c'\" else echo shar: Extracting \"'pragma.c'\" \(311 characters\) sed "s/^X//" >'pragma.c' <<'END_OF_FILE' X#define DEFAULT_ALIGN 32 X Xstatic int pack_align = DEFAULT_ALIGN; Xstatic int was_pragma = 0; X Xpragma_pack(val) Xint val; X{ X pack_align = 8 * val; X was_pragma = 1; X} X Xpragma_align_val() X{ X return pack_align; X} X Xpragma_pack_default() X{ X pack_align = DEFAULT_ALIGN; X} X Xint pragma_pack_seen() X{ X return was_pragma; X} END_OF_FILE if test 311 -ne `wc -c <'pragma.c'`; then echo shar: \"'pragma.c'\" unpacked with wrong size! fi # end of 'pragma.c' fi if test -f 'packtest.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'packtest.c'\" else echo shar: Extracting \"'packtest.c'\" \(2439 characters\) sed "s/^X//" >'packtest.c' <<'END_OF_FILE' Xstatic char *rcsid = "@(#)$Header: /pdsrc/Local/RCS/packtest.c,v 1.1 90/04/26 17:50:35 root Exp $"; X X/* X * Regression test to check that gcc's #pragma pack() support does the X * same thing as Microsoft C's. X * X * Run with this command from sh, not csh, since SCO's csh is BROKEN. X * cc packtest.c && ./a.out > m && gcc packtest.c && ./a.out > g && diff m g X * You should not see any output. X * X * $Log: packtest.c,v $ X * Revision 1.1 90/04/26 17:50:35 root X * Initial revision X * X */ X X#pragma pack(4) Xstruct s1 { X char one; X int two; X long three; X double four; X} s1; X#pragma pack(2) Xstruct s2 { X char one; X int two; X long three; X double four; X} s2; X#pragma pack(1) Xstruct s3 { X char one; X int two; X long three; X double four; X} s3; X#pragma pack() Xstruct s4 { X char one; X int two; X long three; X double four; X} s4; Xstruct biggie { X struct s3 x1; X struct s1 b1; X struct s3 x2; X struct s2 b2; X struct s3 x3; X struct s3 b3; X struct s3 x4; X struct s4 b4; X} b; X#define offsetof(TYPE, MEMBER) ((unsigned) &((TYPE *)0)->MEMBER) Xmain() X{ X printf("% 4d% 4d% 4d\n", X offsetof(struct s1, two), X offsetof(struct s1, three), X offsetof(struct s1, four)); X printf("% 4d% 4d% 4d\n", X offsetof(struct s2, two), X offsetof(struct s2, three), X offsetof(struct s2, four)); X printf("% 4d% 4d% 4d\n", X offsetof(struct s3, two), X offsetof(struct s3, three), X offsetof(struct s3, four)); X printf("% 4d% 4d% 4d\n", X offsetof(struct s4, two), X offsetof(struct s4, three), X offsetof(struct s4, four)); X printf("\n% 4d% 4d% 4d\n", X ((char *)&b.b1.two) - ((char *)&b.b1.one), X ((char *)&b.b1.three) - ((char *)&b.b1.one), X ((char *)&b.b1.four) - ((char *)&b.b1.one)); X printf("% 4d% 4d% 4d\n", X ((char *)&b.b2.two) - ((char *)&b.b2.one), X ((char *)&b.b2.three) - ((char *)&b.b2.one), X ((char *)&b.b2.four) - ((char *)&b.b2.one)); X printf("% 4d% 4d% 4d\n", X ((char *)&b.b3.two) - ((char *)&b.b3.one), X ((char *)&b.b3.three) - ((char *)&b.b3.one), X ((char *)&b.b3.four) - ((char *)&b.b3.one)); X printf("% 4d% 4d% 4d\n\n", X ((char *)&b.b4.two) - ((char *)&b.b4.one), X ((char *)&b.b4.three) - ((char *)&b.b4.one), X ((char *)&b.b4.four) - ((char *)&b.b4.one)); X printf(" % 4d% 4d\n", sizeof b.b1, (char *)&b.b1 - (char *)&b); X printf(" % 4d% 4d\n", sizeof b.b2, (char *)&b.b2 - (char *)&b); X printf(" % 4d% 4d\n", sizeof b.b3, (char *)&b.b3 - (char *)&b); X printf(" % 4d% 4d\n", sizeof b.b4, (char *)&b.b4 - (char *)&b); X exit(0); X} END_OF_FILE if test 2439 -ne `wc -c <'packtest.c'`; then echo shar: \"'packtest.c'\" unpacked with wrong size! fi # end of 'packtest.c' fi echo shar: End of shell archive. exit 0 -- Chip Salzenberg at ComDev/TCT <chip@tct.uucp>, <uunet!ateng!tct!chip>