(sparc-*-solaris2*): Include sol2.o and sol2-protos.h.
* config/sol2-c.c: Include "tm.h", "tm_p.h", "toplev.h",
"cpplib.h", "c-pragma.h", "c-common.h".
(solaris_pragma_align, solaris_pragma_init, solaris_pragma_fini)
(solaris_register_pragmas): New functions.
* config/sol2-protos.h: New file.
* config/sol2.c: New file.
* config/sol2.h (SOLARIS_ATTRIBUTE_TABLE, ASM_DECLARE_FUNCTION_SIZE)
(REGISTER_TARGET_PRAGMAS): New macros.
(solaris_pending_aligns, solaris_pending_inits)
(solaris_pending_finis): New variables.
* config/t-sol2 (sol2-c.o): Update dependencies.
(sol2.o): New rule.
* config/i386/i386.c (TARGET_INSERT_ATTRIBUTES): Define in terms of
SUBTARGET_INSERT_ATTRIBUTES.
(ix86_attribute_table): Include SUBTARGET_ATTRIBUTE_TABLE.
* config/i386/sol2.h (SUBTARGET_INSERT_ATTRIBUTES)
(SUBTARGET_ATTRIBUTE_TABLE, ASM_OUTPUT_CALL): Define.
* config/sparc/elf.h (ASM_DECLARE_FUNCTION_SIZE): Redefine.
* config/sparc/sp64-elf.h (ASM_DECLARE_FUNCTION_SIZE): Redefine.
* config/sparc/sol2.h (SUBTARGET_INSERT_ATTRIBUTES)
(SUBTARGET_ATTRIBUTE_TABLE, ASM_OUTPUT_CALL): Define.
* config/sparc/sparc.c (sparc_attribute_table): New.
(TARGET_INSERT_ATTRIBUTES): Define in terms of
SUBTARGET_INSERT_ATTRIBUTES.
(TARGET_ATTRIBUTE_TABLE): Define if SUBTARGET_ATTRIBUTE_TABLE
is defined.
* doc/extend.texi (Solaris Pragmas): New section.
From-SVN: r85155
+2004-07-25 Daniel Jacobowitz <dan@debian.org>
+
+ * config.gcc (i[34567]86-*-solaris2*, sparc64-*-solaris2*)
+ (sparc-*-solaris2*): Include sol2.o and sol2-protos.h.
+ * config/sol2-c.c: Include "tm.h", "tm_p.h", "toplev.h",
+ "cpplib.h", "c-pragma.h", "c-common.h".
+ (solaris_pragma_align, solaris_pragma_init, solaris_pragma_fini)
+ (solaris_register_pragmas): New functions.
+ * config/sol2-protos.h: New file.
+ * config/sol2.c: New file.
+ * config/sol2.h (SOLARIS_ATTRIBUTE_TABLE, ASM_DECLARE_FUNCTION_SIZE)
+ (REGISTER_TARGET_PRAGMAS): New macros.
+ (solaris_pending_aligns, solaris_pending_inits)
+ (solaris_pending_finis): New variables.
+ * config/t-sol2 (sol2-c.o): Update dependencies.
+ (sol2.o): New rule.
+ * config/i386/i386.c (TARGET_INSERT_ATTRIBUTES): Define in terms of
+ SUBTARGET_INSERT_ATTRIBUTES.
+ (ix86_attribute_table): Include SUBTARGET_ATTRIBUTE_TABLE.
+ * config/i386/sol2.h (SUBTARGET_INSERT_ATTRIBUTES)
+ (SUBTARGET_ATTRIBUTE_TABLE, ASM_OUTPUT_CALL): Define.
+ * config/sparc/elf.h (ASM_DECLARE_FUNCTION_SIZE): Redefine.
+ * config/sparc/sp64-elf.h (ASM_DECLARE_FUNCTION_SIZE): Redefine.
+ * config/sparc/sol2.h (SUBTARGET_INSERT_ATTRIBUTES)
+ (SUBTARGET_ATTRIBUTE_TABLE, ASM_OUTPUT_CALL): Define.
+ * config/sparc/sparc.c (sparc_attribute_table): New.
+ (TARGET_INSERT_ATTRIBUTES): Define in terms of
+ SUBTARGET_INSERT_ATTRIBUTES.
+ (TARGET_ATTRIBUTE_TABLE): Define if SUBTARGET_ATTRIBUTE_TABLE
+ is defined.
+ * doc/extend.texi (Solaris Pragmas): New section.
+
2004-07-25 Bernardo Innocenti <bernie@develer.com>
* c-common.c: Rename all identifiers named `class' to `cl'.
tmake_file="t-sol2 i386/t-sol2 t-svr4"
c_target_objs="sol2-c.o"
cxx_target_objs="sol2-c.o"
+ extra_objs="sol2.o"
+ tm_p_file="${tm_p_file} sol2-protos.h"
if test x$gnu_ld = xyes; then
tmake_file="$tmake_file t-slibgcc-elf-ver"
else
fi
c_target_objs="sol2-c.o"
cxx_target_objs="sol2-c.o"
+ extra_objs="sol2.o"
+ tm_p_file="${tm_p_file} sol2-protos.h"
extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o"
case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
no:*:*) ;;
esac
c_target_objs="sol2-c.o"
cxx_target_objs="sol2-c.o"
+ extra_objs="sol2.o"
+ tm_p_file="${tm_p_file} sol2-protos.h"
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
no:*:*) ;;
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
+#ifdef SUBTARGET_INSERT_ATTRIBUTES
+#undef TARGET_INSERT_ATTRIBUTES
+#define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
+#endif
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#endif
{ "ms_struct", 0, 0, false, false, false, ix86_handle_struct_attribute },
{ "gcc_struct", 0, 0, false, false, false, ix86_handle_struct_attribute },
+#ifdef SUBTARGET_ATTRIBUTE_TABLE
+ SUBTARGET_ATTRIBUTE_TABLE,
+#endif
{ NULL, 0, 0, false, false, false, NULL }
};
fprintf ((FILE), "\n"); \
} \
} while (0)
+
+/* Solaris-specific #pragmas are implemented on top of attributes. Hook in
+ the bits from config/sol2.c. */
+#define SUBTARGET_INSERT_ATTRIBUTES solaris_insert_attributes
+#define SUBTARGET_ATTRIBUTE_TABLE SOLARIS_ATTRIBUTE_TABLE
+
+/* Output a simple call for .init/.fini. */
+#define ASM_OUTPUT_CALL(FILE, NAME) \
+ fprintf (FILE, "\tcall\t%s\n", NAME)
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "tm.h"
+#include "tm_p.h"
+#include "toplev.h"
#include "c-format.h"
#include "intl.h"
+#include "cpplib.h"
+#include "c-pragma.h"
+#include "c-common.h"
+
/* cmn_err only accepts "l" and "ll". */
static const format_length_info cmn_err_length_specs[] =
{
&integer_type_node, &integer_type_node
}
};
+
+/* Handle #pragma align ALIGNMENT (VAR [, VAR]...) */
+
+static void
+solaris_pragma_align (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+ tree t, x;
+ enum cpp_ttype ttype;
+ HOST_WIDE_INT low;
+
+ if (c_lex (&x) != CPP_NUMBER
+ || c_lex (&t) != CPP_OPEN_PAREN)
+ {
+ warning ("malformed %<#pragma align%>, ignoring");
+ return;
+ }
+
+ low = TREE_INT_CST_LOW (x);
+ if (TREE_INT_CST_HIGH (x) != 0
+ || (low != 1 && low != 2 && low != 4 && low != 8 && low != 16
+ && low != 32 && low != 64 && low != 128))
+ {
+ warning ("invalid alignment for %<#pragma align%>, ignoring");
+ return;
+ }
+
+ ttype = c_lex (&t);
+ if (ttype != CPP_NAME)
+ {
+ warning ("malformed %<#pragma align%>, ignoring");
+ return;
+ }
+
+ while (1)
+ {
+ tree decl = identifier_global_value (t);
+ if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ warning ("%<#pragma align%> must appear before the declaration of "
+ "%D, ignoring", decl);
+ else
+ solaris_pending_aligns = tree_cons (t, build_tree_list (NULL, x),
+ solaris_pending_aligns);
+
+ ttype = c_lex (&t);
+ if (ttype == CPP_COMMA)
+ {
+ ttype = c_lex (&t);
+ if (ttype != CPP_NAME)
+ {
+ warning ("malformed %<#pragma align%>");
+ return;
+ }
+ }
+ else if (ttype == CPP_CLOSE_PAREN)
+ {
+ if (c_lex (&t) != CPP_EOF)
+ warning ("junk at end of %<#pragma align%>");
+ return;
+ }
+ else
+ {
+ warning ("malformed %<#pragma align%>");
+ return;
+ }
+ }
+}
+
+/* Handle #pragma init (function [, function]...) */
+
+static void
+solaris_pragma_init (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+ tree t;
+ enum cpp_ttype ttype;
+
+ if (c_lex (&t) != CPP_OPEN_PAREN)
+ {
+ warning ("malformed %<#pragma init%>, ignoring");
+ return;
+ }
+
+ ttype = c_lex (&t);
+ if (ttype != CPP_NAME)
+ {
+ warning ("malformed %<#pragma init%>, ignoring");
+ return;
+ }
+
+ while (1)
+ {
+ tree decl = identifier_global_value (t);
+ if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ {
+ tree init_list = build_tree_list (get_identifier ("init"),
+ NULL);
+ tree attrs = tree_cons (get_identifier ("used"), NULL, init_list);
+ decl_attributes (&decl, attrs, 0);
+ }
+ else
+ solaris_pending_inits = tree_cons (t, NULL, solaris_pending_inits);
+
+ ttype = c_lex (&t);
+ if (ttype == CPP_COMMA)
+ {
+ ttype = c_lex (&t);
+ if (ttype != CPP_NAME)
+ {
+ warning ("malformed %<#pragma init%>");
+ return;
+ }
+ }
+ else if (ttype == CPP_CLOSE_PAREN)
+ {
+ if (c_lex (&t) != CPP_EOF)
+ warning ("junk at end of %<#pragma init%>");
+ return;
+ }
+ else
+ {
+ warning ("malformed %<#pragma init%>");
+ return;
+ }
+ }
+}
+
+/* Handle #pragma fini (function [, function]...) */
+
+static void
+solaris_pragma_fini (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+ tree t;
+ enum cpp_ttype ttype;
+
+ if (c_lex (&t) != CPP_OPEN_PAREN)
+ {
+ warning ("malformed %<#pragma fini%>, ignoring");
+ return;
+ }
+
+ ttype = c_lex (&t);
+ if (ttype != CPP_NAME)
+ {
+ warning ("malformed %<#pragma fini%>, ignoring");
+ return;
+ }
+
+ while (1)
+ {
+ tree decl = identifier_global_value (t);
+ if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ {
+ tree fini_list = build_tree_list (get_identifier ("fini"),
+ NULL);
+ tree attrs = tree_cons (get_identifier ("used"), NULL, fini_list);
+ decl_attributes (&decl, attrs, 0);
+ }
+ else
+ solaris_pending_finis = tree_cons (t, NULL, solaris_pending_finis);
+
+ ttype = c_lex (&t);
+ if (ttype == CPP_COMMA)
+ {
+ ttype = c_lex (&t);
+ if (ttype != CPP_NAME)
+ {
+ warning ("malformed %<#pragma fini%>");
+ return;
+ }
+ }
+ else if (ttype == CPP_CLOSE_PAREN)
+ {
+ if (c_lex (&t) != CPP_EOF)
+ warning ("junk at end of %<#pragma fini%>");
+ return;
+ }
+ else
+ {
+ warning ("malformed %<#pragma fini%>");
+ return;
+ }
+ }
+}
+
+/* Register Solaris-specific #pragma directives. */
+
+void
+solaris_register_pragmas (void)
+{
+ c_register_pragma (0, "align", solaris_pragma_align);
+ c_register_pragma (0, "init", solaris_pragma_init);
+ c_register_pragma (0, "fini", solaris_pragma_fini);
+}
--- /dev/null
+/* Operating system specific prototypes to be used when targeting GCC for any
+ Solaris 2 system.
+ Copyright 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+extern void solaris_insert_attributes (tree, tree *);
+extern void solaris_register_pragmas (void);
+extern void solaris_output_init_fini (FILE *, tree);
--- /dev/null
+/* General Solaris system support.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by CodeSourcery, LLC.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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 GCC; 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"
+#include "coretypes.h"
+#include "tree.h"
+#include "tm.h"
+#include "tm_p.h"
+#include "toplev.h"
+#include "ggc.h"
+
+tree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;
+
+/* Attach any pending attributes for DECL to the list in *ATTRIBUTES.
+ Pending attributes come from #pragma or _Pragma, so this code is
+ only useful in the C family front ends, but it is included in
+ all languages to avoid changing the target machine initializer
+ depending on the language. */
+
+void
+solaris_insert_attributes (tree decl, tree *attributes)
+{
+ tree *x, next;
+
+ if (solaris_pending_aligns != NULL && TREE_CODE (decl) == VAR_DECL)
+ for (x = &solaris_pending_aligns; *x; x = &TREE_CHAIN (*x))
+ {
+ tree name = TREE_PURPOSE (*x);
+ tree value = TREE_VALUE (*x);
+ if (DECL_NAME (decl) == name)
+ {
+ if (lookup_attribute ("aligned", DECL_ATTRIBUTES (decl))
+ || lookup_attribute ("aligned", *attributes))
+ warning ("%Jignoring %<#pragma align%> for explicitly "
+ "aligned %<%D%>", decl, decl);
+ else
+ *attributes = tree_cons (get_identifier ("aligned"), value,
+ *attributes);
+ next = TREE_CHAIN (*x);
+ ggc_free (*x);
+ *x = next;
+ break;
+ }
+ }
+
+ if (solaris_pending_inits != NULL && TREE_CODE (decl) == FUNCTION_DECL)
+ for (x = &solaris_pending_inits; *x; x = &TREE_CHAIN (*x))
+ {
+ tree name = TREE_PURPOSE (*x);
+ if (DECL_NAME (decl) == name)
+ {
+ *attributes = tree_cons (get_identifier ("init"), NULL,
+ *attributes);
+ *attributes = tree_cons (get_identifier ("used"), NULL,
+ *attributes);
+ next = TREE_CHAIN (*x);
+ ggc_free (*x);
+ *x = next;
+ break;
+ }
+ }
+
+ if (solaris_pending_finis != NULL && TREE_CODE (decl) == FUNCTION_DECL)
+ for (x = &solaris_pending_finis; *x; x = &TREE_CHAIN (*x))
+ {
+ tree name = TREE_PURPOSE (*x);
+ if (DECL_NAME (decl) == name)
+ {
+ *attributes = tree_cons (get_identifier ("fini"), NULL,
+ *attributes);
+ *attributes = tree_cons (get_identifier ("used"), NULL,
+ *attributes);
+ next = TREE_CHAIN (*x);
+ ggc_free (*x);
+ *x = next;
+ break;
+ }
+ }
+}
+
+/* Output initializer or finalizer entries for DECL to FILE. */
+
+void
+solaris_output_init_fini (FILE *file, tree decl)
+{
+ if (lookup_attribute ("init", DECL_ATTRIBUTES (decl)))
+ {
+ fprintf (file, "\t.pushsection\t\".init\"\n");
+ ASM_OUTPUT_CALL (file, IDENTIFIER_POINTER (DECL_NAME (decl)));
+ fprintf (file, "\t.popsection\n");
+ }
+
+ if (lookup_attribute ("fini", DECL_ATTRIBUTES (decl)))
+ {
+ fprintf (file, "\t.pushsection\t\".fini\"\n");
+ ASM_OUTPUT_CALL (file, IDENTIFIER_POINTER (DECL_NAME (decl)));
+ fprintf (file, "\t.popsection\n");
+ }
+}
+
/* Operating system specific defines to be used when targeting GCC for any
Solaris 2 system.
- Copyright 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
} \
}
+/* Support Solaris-specific format checking for cmn_err. */
#define TARGET_N_FORMAT_TYPES 1
#define TARGET_FORMAT_TYPES solaris_format_types
+
+/* #pragma init and #pragma fini are implemented on top of init and
+ fini attributes. */
+#define SOLARIS_ATTRIBUTE_TABLE \
+ { "init", 0, 0, true, false, false, NULL }, \
+ { "fini", 0, 0, true, false, false, NULL }
+
+/* This is how to declare the size of a function. For Solaris, we output
+ any .init or .fini entries here. */
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
+ do \
+ { \
+ if (!flag_inhibit_size_directive) \
+ ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
+ solaris_output_init_fini (FILE, DECL); \
+ } \
+ while (0)
+
+/* Register the Solaris-specific #pragma directives. */
+#define REGISTER_TARGET_PRAGMAS() solaris_register_pragmas ()
+
+extern GTY(()) tree solaris_pending_aligns;
+extern GTY(()) tree solaris_pending_inits;
+extern GTY(()) tree solaris_pending_finis;
/* Don't include Solaris-specific format checks. */
#undef TARGET_N_FORMAT_TYPES
#undef TARGET_FORMAT_TYPES
+
+/* Don't include Solaris-specific .init / .fini support. */
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
+ do \
+ { \
+ if (!flag_inhibit_size_directive) \
+ ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
+ } \
+ while (0)
sparc_override_options will disable V8+ if not generating V9 code. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_V8PLUS + MASK_FPU + MASK_LONG_DOUBLE_128)
+
+/* Solaris-specific #pragmas are implemented on top of attributes. Hook in
+ the bits from config/sol2.c. */
+#define SUBTARGET_INSERT_ATTRIBUTES solaris_insert_attributes
+#define SUBTARGET_ATTRIBUTE_TABLE SOLARIS_ATTRIBUTE_TABLE
+
+/* Output a simple call for .init/.fini. */
+#define ASM_OUTPUT_CALL(FILE, NAME) \
+ fprintf (FILE, "\tcall\t%s\n\t nop\n", NAME)
/* Don't include Solaris-specific format checks. */
#undef TARGET_N_FORMAT_TYPES
#undef TARGET_FORMAT_TYPES
+
+/* Don't include Solaris-specific .init / .fini support. */
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
+ do \
+ { \
+ if (!flag_inhibit_size_directive) \
+ ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
+ } \
+ while (0)
static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *);
static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
enum machine_mode, tree, bool);
+#ifdef SUBTARGET_ATTRIBUTE_TABLE
+const struct attribute_spec sparc_attribute_table[];
+#endif
\f
/* Option handling. */
#undef TARGET_LATE_RTL_PROLOGUE_EPILOGUE
#define TARGET_LATE_RTL_PROLOGUE_EPILOGUE true
+#ifdef SUBTARGET_INSERT_ATTRIBUTES
+#undef TARGET_INSERT_ATTRIBUTES
+#define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
+#endif
+
+#ifdef SUBTARGET_ATTRIBUTE_TABLE
+#undef TARGET_ATTRIBUTE_TABLE
+#define TARGET_ATTRIBUTE_TABLE sparc_attribute_table
+#endif
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Validate and override various options, and do some machine dependent
};
}
\f
+#ifdef SUBTARGET_ATTRIBUTE_TABLE
+/* Table of valid machine attributes. */
+const struct attribute_spec sparc_attribute_table[] =
+{
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+ SUBTARGET_ATTRIBUTE_TABLE,
+ { NULL, 0, 0, false, false, false, NULL }
+};
+#endif
+\f
/* Miscellaneous utilities. */
/* Nonzero if CODE, a comparison, is suitable for use in v9 conditional move
-# Solaris-specific format checking
+# Solaris-specific format checking and pragmas
sol2-c.o: $(srcdir)/config/sol2-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- tree.h c-format.h intl.h
+ tree.h c-format.h intl.h $(CPPLIB_H) c-pragma.h $(TM_H) $(TM_P_H) \
+ toplev.h $(C_COMMON_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/sol2-c.c
+
+# Solaris-specific attributes
+sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ tree.h $(TM_H) $(TM_P_H) toplev.h $(GGC_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/sol2.c
* ARM Pragmas::
* RS/6000 and PowerPC Pragmas::
* Darwin Pragmas::
+* Solaris Pragmas::
* Symbol-Renaming Pragmas::
@end menu
anywhere within the variables' scopes.
@end table
+@node Solaris Pragmas
+@subsection Solaris Pragmas
+
+The Solaris target supports @code{#pragma redefine_extname}
+(@pxref{Symbol-Renaming Pragmas}). It also supports additional
+@code{#pragma} directives for compatibility with the system compiler.
+
+@table @code
+@item align @var{alignment} (@var{variable} [, @var{variable}]...)
+@cindex pragma, align
+
+Increase the minimum alignment of each @var{variable} to @var{alignment}.
+This is the same as GCC's @code{aligned} attribute @pxref{Variable
+Attributes}).
+
+@item fini (@var{function} [, @var{function}]...)
+@cindex pragma, fini
+
+This pragma causes each listed @var{function} to be called after
+main, or during shared module unloading, by adding a call to the
+@code{.fini} section.
+
+@item init (@var{function} [, @var{function}]...)
+@cindex pragma, init
+
+This pragma causes each listed @var{function} to be called during
+initialization (before @code{main}) or during shared module loading, by
+adding a call to the @code{.init} section.
+
+@end table
+
@node Symbol-Renaming Pragmas
@subsection Symbol-Renaming Pragmas