View Issue Details

IDProjectCategoryView StatusLast Update
0000474GCC - GNU C CompilerBugpublic2020-08-24 03:14
Reporterdmik Assigned Topsmedley  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Summary0000474: _System modifier doesn't always work
DescriptionI noticed that in GCC versions after 4.4.2 the _System calling convention modifier doesn't always work.

1. In a simple testcase (a simple function int _System foo() { return 0; }) everything works as expected: the function declared does not get an underscore character in front.

2. If you try to build Lucide (current SVN) using GCC 4.4.4 or 4.5.2, some functions will get underscores in declarations but not in definitions which results in link failures (undefined symbols). GCC 4.4.2 works.

3. If you try to build Qt4 (current SVN) using GCG 4.5.2, the same problem as in 2. appears. GCC 4.4.4 and GCC 4.4.2 work.
Additional InformationAs I said the simple test case doesn't reveal the problem (it seems to depend on the environment a lot), so in order to reproduce it it's best to try to build Lucide and Qt on your own. It's fairly straight forward and well documented. If you have questions, I will help you.
TagsNo tags attached.
Attached Files
emx.c.442-445 (8,963 bytes)
i386.c.442-445 (6,182 bytes)
emx.c (37,317 bytes)   
/* emx.c: Functions for emx as target system.

Original version by Eberhard Mattes, based on i386.c.
Heavily modified by Andrew Zabolotny and Knut St. Osmundsen.
Modified for GCC 4.3.2 by Paul Smedley 2008

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"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "output.h"
#include "tree.h"
#include "flags.h"
#include "tm_p.h"
#include "toplev.h"
#include "hashtab.h"
#include "ggc.h"

/* The size of the target's pointer type.  */
#ifndef PTR_SIZE
#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
#endif

/* DO NOT COMMIT WITH THIS DEFINED!!! */
/* #define BIRD_DEBUG */

#ifdef BIRD_DEBUG
static const char *code(tree node)
{
    if (node)
    {
        switch (TREE_CODE (node))
        {
            case IDENTIFIER_NODE:   return "IDENTIFIER_NODE";
            case TREE_LIST:         return "TREE_LIST      ";
            case TREE_VEC:          return "TREE_VEC       ";
            case BLOCK:             return "BLOCK          ";
            case FUNCTION_TYPE:     return "FUNCTION_TYPE  ";
            case FUNCTION_DECL:     return "FUNCTION_DECL  ";
            case METHOD_TYPE:       return "METHOD_TYPE    ";
            case FIELD_DECL:        return "FIELD_DECL     ";
            case TYPE_DECL:         return "TYPE_DECL      ";
            case VAR_DECL:          return "VAR_DECL       ";
            case PARM_DECL:         return "PARM_DECL      ";
            case RESULT_DECL:       return "RESULT_DECL    ";
            case CONST_DECL:        return "CONST_DECL     ";
            case POINTER_TYPE:      return "POINTER_TYPE   ";
            case VOID_TYPE:         return "VOID_TYPE      ";
            case INTEGER_TYPE:      return "INTEGER_TYPE   ";
            case CHAR_TYPE:         return "CHAR_TYPE      ";
            case BOOLEAN_TYPE:      return "BOOLEAN_TYPE   ";
            case SET_TYPE:          return "SET_TYPE       ";
            case ARRAY_TYPE:        return "ARRAY_TYPE     ";
            case RECORD_TYPE:       return "RECORD_TYPE    ";
            case QUAL_UNION_TYPE:   return "QUAL_UNION_TYPE";
            case UNION_TYPE:        return "UNION_TYPE     ";
            case INTEGER_CST:       return "INTEGER_CST    ";
            default:
                break;
        }
    }
    return "";
}

const char *birddump_callingconv(tree node);
const char *birddump_callingconv(node)
    tree node;
{
    static const char *apsz[] = {"system", "optlink", "stdcall", "cdecl", "dllimport", "dllexport"};
    static const char *psznone = "none";
    static const char *pszdefault = "default";
    tree        attr;
    unsigned    i;

    if (!node)
        return psznone;

    attr = DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_P (node) ? TYPE_ATTRIBUTES (node) : NULL_TREE;
    if (!attr)
        return pszdefault;

    for (i = 0; i < sizeof(apsz) / sizeof(apsz[0]); i++)
        if (node && attr && lookup_attribute (apsz[i], attr))
            return apsz[i];

    return pszdefault;
}

const char *birddump_name(tree node);
const char *birddump_name(tree node)
{
    tree name = NULL_TREE;
    if (node == NULL_TREE)
        name = NULL_TREE;
    else if (DECL_P(node))
        name = DECL_NAME(node);
    else if (TYPE_P(node))
    {
        name = TYPE_NAME(node);
        if (TREE_CODE(node) == RECORD_TYPE && DECL_NAME(name))
            name = DECL_NAME(name);
    }
    if (name != NULL_TREE)
        return IDENTIFIER_POINTER(name);
    return "<none>";
}

void birddump (tree node, const char *pszFunction)
{
    tree type, type2, context;
    if (!node)
        return;

    type = TREE_TYPE (node);
    type2 = type ? TREE_TYPE (type) : NULL_TREE;
    context = DECL_P (node) ? DECL_CONTEXT (node) : NULL_TREE;

    fprintf(stderr, "dbg: node=%d %s %p %s '%s'  type=%d %s %p %s '%s'  type_type=%d %s %p %s '%s'  context=%d %s %p %s '%s' (%s)\n",
            TREE_CODE(node), code(node), (void*)node, birddump_callingconv(node), birddump_name(node),
           g type ? (int)TREE_CODE(type) : -1, code(type), (void*)type, birddump_callingconv(type), birddump_name (type),
            type2 ? (int)TREE_CODE(type2) : -1, code(type2), (void*)type2, birddump_callingconv(type2), birddump_name (type2),
            context ? (int)TREE_CODE(context) : -1, code(context), (void*)context, birddump_callingconv(context), birddump_name (context),
            pszFunction);
}

#define dfprintf(a) fprintf a
/*#define DUMP(node) birddump(node, __FUNCTION__)*/
#define DUMP(node) do {} while (0)
#else
#define dfprintf(a) do {} while (0) 
/*#define dfprintf(a) fprintf a */
#define DUMP(node) do {} while (0)
#endif

int emx_c_set_decl_assembler_name (tree decl, int fclass)
{
  static int recurse;
  const char *oldsym;
  char *newsym;
  size_t sl;
  tree id, type;
  int rc = 1;

  dfprintf((stderr, "emx_c_set_decl_assembler_name\n"));
  DUMP(decl);

  /* Sometimes we recursively call DECL_ASSEMBLER_NAME to apply the default
     mangling rules for current compiler. */
  if (recurse)
    return 0;

  /* Only functions declarations are subject to mangling. */
  if (TREE_CODE (decl) != FUNCTION_DECL)
    return 0;

  recurse++;
  type = TREE_TYPE (decl);

  if (lookup_attribute ("system", TYPE_ATTRIBUTES (type)))
    {
      /* Here we mangle _System functions as defined by IBM specs.
         The function always gets its name as-is (unless it is a method,
         which is a undefined case as VACPP always use _Optlink for methods,
         at least that's what I have understood from the docs). */

      oldsym = IDENTIFIER_POINTER (DECL_NAME (decl));
      if (fclass)
        return 0;

      /* Specifying '*' as first symbol character tells gcc (see varasm.c,
         function assemble_name()) to output the label as-is rather than
         invoking the ASM_OUTPUT_LABELREF macro (which prepends a underscore) */

      sl = strlen (oldsym);
      newsym = xmalloc (sl + 2);
      newsym [0] = '*';
      memcpy (newsym + 1, oldsym, sl + 1);

      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (newsym));

      dfprintf ((stderr, "dbg: system %s -> %s\n", oldsym, newsym));
    }
  else if (lookup_attribute ("optlink", TYPE_ATTRIBUTES (type)))
    {
      /* At the moment we're only implementing OS/2 VAC linking
         compatibility for the C language. This means that no leading
         underscore.
         For C++ we are not compatible. It doesn't make that much sense
         either since we're not VFT compatible either. For simplicity
         and safety we are removing the leading underscore from the
         default mangled names to catch invalid declarations in the
         linking. */

      id = DECL_ASSEMBLER_NAME (decl);

      /* Remove the leading underscore. */
      oldsym = IDENTIFIER_POINTER (id);
      sl = strlen (oldsym);
      newsym = xmalloc (sl + 2);
      newsym [0] = '*';
      memcpy (newsym + 1, oldsym, sl + 1);

      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (newsym));

      dfprintf ((stderr, "dbg: optlink %s -> %s\n", oldsym, newsym));
    }
  else if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (type)))
    {
      /* Mangle decl as the former assembler name modified with a
         suffix consisting of an atsign (@) followed by the number of bytes of
         arguments.
         For C++ the same applies as for optlink. See above. */

      int total = 0;

      /* If function does not have ellipsis as last argument, count total args size */
      if (TYPE_ARG_TYPES (type))
        if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (type))) == void_type_node)
          {
            tree formal_type = TYPE_ARG_TYPES (type);

            while (TREE_VALUE (formal_type) != void_type_node)
              {
                int parm_size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
                /* Must round up to include padding.  This is done the same
                   way as in store_one_arg.  */
                parm_size = ((parm_size + PARM_BOUNDARY - 1) / PARM_BOUNDARY * PARM_BOUNDARY);
                total += parm_size;
                formal_type = TREE_CHAIN (formal_type);
              }
          }

      id = DECL_ASSEMBLER_NAME (decl);
      oldsym = IDENTIFIER_POINTER (id);
      newsym = xmalloc (strlen (oldsym) + 10);
      sprintf (newsym, "%s@%d", oldsym, total / BITS_PER_UNIT);
      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (newsym));

      dfprintf ((stderr, "dbg: stdcall %s -> %s\n", oldsym, newsym));
    }
  else if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
    {
      /* Mangle decl as the former assembler name modified with a prefix of an atsign (@), and 
         suffix consisting of an atsign (@) followed by the number of bytes of
         arguments.
         For C++ the same applies as for optlink. See above. */

      int total = 0;

      /* If function does not have ellipsis as last argument, count total args size */
      if (TYPE_ARG_TYPES (type))
        if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (type))) == void_type_node)
          {
            tree formal_type = TYPE_ARG_TYPES (type);

            while (TREE_VALUE (formal_type) != void_type_node)
              {
                int parm_size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
                /* Must round up to include padding.  This is done the same
                   way as in store_one_arg.  */
                parm_size = ((parm_size + PARM_BOUNDARY - 1) / PARM_BOUNDARY * PARM_BOUNDARY);
                total += parm_size;
                formal_type = TREE_CHAIN (formal_type);
              }
          }

      id = DECL_ASSEMBLER_NAME (decl);
      oldsym = IDENTIFIER_POINTER (id);
      newsym = xmalloc (strlen (oldsym) + 11);
      sprintf (newsym, "*@%s@%d", oldsym, total / BITS_PER_UNIT);
      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (newsym));

      dfprintf ((stderr, "dbg: fastcall %s -> %s\n", oldsym, newsym));
    }
  else
    rc = 0;

  recurse--;
  return rc;
}

#if 0 /* choose between the smaller non working version, and the
         large ugly one which is working. */

tree emx_handle_vacpp_attribute (tree *node, tree name, tree args,
  int flags, _Bool *no_add_attrs)
{
  tree *type;
  (void) args;
  (void) flags;

  dfprintf((stderr, "emx_handle_vacpp_attribute\n"));
  DUMP (*node);

  if (TREE_CODE (*node) != FUNCTION_TYPE
      && TREE_CODE (*node) != METHOD_TYPE
      && TREE_CODE (*node) != FIELD_DECL
      && TREE_CODE (*node) != TYPE_DECL)
    {
      warning ("`%s' attribute only applies to functions",
	       IDENTIFIER_POINTER (name));
      *no_add_attrs = true;
    }

  if (TARGET_64BIT)
    {
      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
      *no_add_attrs = true;
    }

  /* Check if the attributes are compatible */
  if (ix86_check_append_attr (*node, name, no_add_attrs))
    return NULL_TREE;

  /* Now, a new type with our attribute please!
     If the FUNCTION_TYPE/METHOD_TYPE already have the attribute associated,
     there is no need to duplicate the type.
     @todo: I'm unsure wether or not we should do this from node and down... */
  for (type = node;
       TREE_CODE (*type) != FUNCTION_TYPE && TREE_CODE (*type) != METHOD_TYPE;
       type = &TREE_TYPE (*type))
      /* do nothing */;

  if (lookup_attribute (IDENTIFIER_POINTER (name), TYPE_ATTRIBUTES (*type)))
      return NULL_TREE;

  *type = build_type_copy (*type);
  *type = build_type_attribute_variant (*type, tree_cons (name, args, TYPE_ATTRIBUTES (*type)) );
  /**no_add_attrs = true; ?? */

  dfprintf((stderr, "emx_handle_vacpp_attribute: new type (%p)\n", (void*)type));
  DUMP (*node);
  return NULL_TREE;
}

#else

/* This is the working version which we belive duplicate some which could be
   done by the generic attribute stuff in GCC... */
tree emx_handle_vacpp_attribute (tree *node, tree name, tree args, int flags, _Bool *no_add_attrs)
{
  tree type;

  dfprintf((stderr, "emx_handle_vacpp_attribute: node=%p\n", (void *)node));
  DUMP (*node);
#if 1
  if (TREE_CODE (*node) != FUNCTION_TYPE
      && TREE_CODE (*node) != METHOD_TYPE
      && TREE_CODE (*node) != FIELD_DECL
      && TREE_CODE (*node) != TYPE_DECL)
    {
      warning (OPT_Wattributes, "%qs attribute only applies to functions",
	       IDENTIFIER_POINTER (name));
      *no_add_attrs = true;
      return NULL_TREE;
    }
#endif
  switch (TREE_CODE (*node))
    {
      /* Declarations!
         We need to attach the attribute to the type of the declaration.
         (Name mangling is done by emx_c_set_decl_assembler_name().)  */
      case FUNCTION_DECL:/* Function declaration. */
      case TYPE_DECL:    /* Function or function pointer type. */
      case FIELD_DECL:   /* Function pointer (or function?) as a struct, union or class member. */
      case PARM_DECL:    /* Function pointer as a parameter. */
      case VAR_DECL:     /* Function pointer variable. */
        /* If this is a type declaration with our attribute, we allow it
           only if it is a pointer-to-a-function type or a function type. */
        type = TREE_TYPE (*node);
        if (TREE_CODE (type) == POINTER_TYPE)
          type = TREE_TYPE(type);
#if 0
        if (   TREE_CODE (type) != FUNCTION_TYPE
            && TREE_CODE (type) != METHOD_TYPE)
          {
            warning ("`%s' attribute only applies to functions and function types, not to '%T'.",
                     IDENTIFIER_POINTER (name), type);
            *no_add_attrs = true;
            break;
          }
#endif
        if (ix86_check_append_attr (type, name, no_add_attrs))
          break;

        /* If required we'll make a variant of the type for this attribute. */
        if (!lookup_attribute (IDENTIFIER_POINTER (name),
                               TYPE_ATTRIBUTES (type)))
          {
            tree *ptype = node;
            while (*ptype != type)
                ptype = &TREE_TYPE (*ptype);
            *ptype = build_variant_type_copy (*ptype);
            *ptype = build_type_attribute_variant (
                *ptype, tree_cons (name, args, TYPE_ATTRIBUTES (*ptype)) );
            dfprintf((stderr, "emx_handle_vacpp_attribute: new type\n"));
            DUMP(*node);
          }
        else
          dfprintf((stderr, "emx_handle_vacpp_attribute: use old type\n"));
        *no_add_attrs = true;
        break;

      /* Types!
         For types involving functions we need to convince decl_attributes()
         (and its callers) to supply a declaration so we safely can change
         the type. */
      case POINTER_TYPE:
        /* We allow:
           This being the return type of a function which is coming soon.
           This being a function pointer which declaration is coming next.
           Everything else is considered inappropriate use of the attribute. */
        if (   !(flags & ATTR_FLAG_FUNCTION_NEXT)
            && (    !(flags & ATTR_FLAG_DECL_NEXT)
                ||  !(type = TREE_TYPE (*node))
                || (   TREE_CODE (type) != FUNCTION_TYPE
                    && TREE_CODE (type) != METHOD_TYPE)))
        {
            warning ("`%s' attribute only applies to functions and function types",
                     IDENTIFIER_POINTER (name));
            *no_add_attrs = true;
            break;
        }
        /* fall thru */
      case FUNCTION_TYPE:
      case METHOD_TYPE:
#if 0 /* bird: This fixes optlink/tst4.c and doesn't seem to break anything.
               If set to true we are in some cases imposing _Optlink onto following
               declarations. This is weird stuff!
            !! This problem is actually what we see with the other implementation!! */
        *no_add_attrs = true;
#endif
        return tree_cons (name, args, NULL_TREE);

      default:
        warning ("`%s' attribute only applies to functions and function types (code=%d)",
                 IDENTIFIER_POINTER (name), TREE_CODE (*node));
        *no_add_attrs = true;
        break;
    }

  return NULL_TREE;
}
#endif

void
emx_eh_frame_section ()
{
/*
  tree label = get_file_function_name ('F');
  The __ehInit undefined external here is to drag __ehInit/__ehInitDLL into
  the linking so DLLs are initiated correctly. (#577)
*/
  dfprintf ((stderr, "trace: emx_eh_frame_section\n"));
  switch_to_section (data_section);
  ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
  fputs ("\t.stabs\t\"___eh_frame__\",24,0,0,Lframe1\n", asm_out_file); /* N_SETD */
  fputs ("\t.stabs\t\"___ehInit\",1,0,0,0\n", asm_out_file);  /* N_UNDEF | N_EXT */
}

void
i386_emx_init_sections ()
{
  dfprintf ((stderr, "trace: emx_init_sections\n"));
  exception_section = data_section;
  eh_frame_section = get_unnamed_section (0,
					 emx_eh_frame_section,
					 NULL); 
}

#if 0
static void
i386_emx_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  /* Tell GNU LD that this is part of the static destructor set.
     This will work for any system that uses stabs, most usefully
     aout systems.  */
  dbxout_begin_simple_stabs ("___DTOR_LIST__", 22 /* N_SETT */);
  dbxout_stab_value_label (XSTR (symbol, 0));
  switch_to_section (data_section);
  ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
  fputs ("\t.stabs\t\"___eh_frame__\",24,0,0,Lframe1\n", asm_out_file); /* N_SETD */
  fputs ("\t.stabs\t\"___ehInit\",1,0,0,0\n", asm_out_file);  /* N_UNDEF | N_EXT */
}
#endif

/* Add a __POST$xxx label before epilogue if -mepilogue specified */
void emx_output_function_begin_epilogue (f)
    FILE *f;
{
  dfprintf ((stderr, "trace: emx_output_function_begin_epilogue\n"));
  if (TARGET_EPILOGUE && TREE_PUBLIC (current_function_decl))
  {
    const char *func_label = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
    char *lbl = XALLOCAVEC (char, strlen (func_label) + 8);
    strcpy (lbl, "__POST$");
    if (func_label[0] == '*')
      func_label++;
    strcat (lbl, func_label);
    ASM_OUTPUT_LABEL (f, lbl);
  }
}


/* Checks if the function is using either optlink or system calling convention
   and returns 1 in those cases forcing the return value to be in memory.
   The problem (#631) was that structures less than 8 bytes were returned in
   registers. _System and _Optlink requires them to be passed in as a hidden
   parameter.
   @type is the return type.
   @fntype is function type, call expression, function declaration or null.
   The return value is 1 to force the return value into memory. Return 0 if we
   don't know. */

int emx_return_in_memory_with_fntype (type, fntype)
    tree type, fntype;
{
  dfprintf ((stderr, "trace: emx_return_in_memory_with_fntype\n"));
  /* (from aggregate_value_p() CVS trunk) */
  if (fntype)
    switch (TREE_CODE (fntype))
      {
      case CALL_EXPR:
        fntype = get_callee_fndecl (fntype);
        fntype = fntype ? TREE_TYPE (fntype) : 0;
        break;
      case FUNCTION_DECL:
        fntype = TREE_TYPE (fntype);
        break;
      case FUNCTION_TYPE:
      case METHOD_TYPE:
        break;
      case IDENTIFIER_NODE:
        fntype = 0;
        break;
      default:
        /* We don't expect other rtl types here.  */
        abort();
      }

  /* (future targetm.calls.return_in_memory additions) */
  if (fntype
   && AGGREGATE_TYPE_P (type)
   && (   lookup_attribute ("optlink", TYPE_ATTRIBUTES (fntype))
       || lookup_attribute ("system", TYPE_ATTRIBUTES (fntype))))
    {
      dfprintf((stderr, "emx_return_in_memory_with_fntype: returns 1\n"));
      return 1;
    }

  /* return ix86_return_in_memory (exp); - future */
  dfprintf((stderr, "emx_return_in_memory_with_fntype: returns 0\n"));
  return 0;
}

/* copy&hack from winnt.c */

static tree associated_type (tree);
static bool i386_emx_determine_dllexport_p (tree);
static bool i386_emx_determine_dllimport_p (tree);

/* Handle a "shared" attribute;
   arguments as in struct attribute_spec.handler.  */
tree
ix86_handle_shared_attribute (tree *node, tree name,
			      tree args ATTRIBUTE_UNUSED,
			      int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
  dfprintf ((stderr, "trace: ix86_handle_shared_attribute\n"));
  DUMP (*node);
  if (TREE_CODE (*node) != VAR_DECL)
    {
      warning (OPT_Wattributes, "%qs attribute only applies to variables",
	       IDENTIFIER_POINTER (name));
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Handle a "selectany" attribute;
   arguments as in struct attribute_spec.handler.  */
tree
ix86_handle_selectany_attribute (tree *node, tree name,
			         tree args ATTRIBUTE_UNUSED,
			         int flags ATTRIBUTE_UNUSED,
				 bool *no_add_attrs)
{
  dfprintf ((stderr, "trace: ix86_handle_selectany_attribute\n"));
  /* The attribute applies only to objects that are initialized and have
     external linkage.  However, we may not know about initialization
     until the language frontend has processed the decl. We'll check for
     initialization later in encode_section_info.  */	
  if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node))
    {	
      error ("%qs attribute applies only to initialized variables"
       	     " with external linkage",  IDENTIFIER_POINTER (name));
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Return the type that we should use to determine if DECL is
   imported or exported.  */

static tree
associated_type (tree decl)
{
  dfprintf ((stderr, "trace: associated_type\n"));
  return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
          ?  DECL_CONTEXT (decl) : NULL_TREE);
}

/* Return true if DECL should be a dllexport'd object.  */

static bool
i386_emx_determine_dllexport_p (tree decl)
{
  dfprintf((stderr, "i386_emx_determine_dllexport_p\n"));
  tree assoc;

  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
    return false;

  if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
    return true;

  /* Also mark class members of exported classes with dllexport.  */
  assoc = associated_type (decl);
  if (assoc && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (assoc)))
    return i386_emx_type_dllexport_p (decl);
 
  return false;
}

/* Return true if DECL should be a dllimport'd object.  */

static bool
i386_emx_determine_dllimport_p (tree decl)
{
  dfprintf((stderr, "i386_emx_determine_dllimport_p\n"));
  tree assoc;

  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
    return false;

  /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag.
     We may need to override an earlier decision.  */
  if (DECL_DLLIMPORT_P (decl))
    return true;

  /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
     by  targetm.cxx.adjust_class_at_definition.  Check again to emit
     warnings if the class attribute has been overridden by an
     out-of-class definition.  */
  assoc = associated_type (decl);
  if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc)))
    return i386_emx_type_dllimport_p (decl);

  return false;
}

/* Handle the -mno-fun-dllimport target switch.  */
bool
i386_emx_valid_dllimport_attribute_p (const_tree decl)
{
  dfprintf ((stderr, "trace: i386_emx_valid_dllimport_attribute_p\n"));
   if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
     return false;
   return true;
}

#if 0
/* Return string which is the function name, identified by ID, modified
   with a suffix consisting of an atsign (@) followed by the number of
   bytes of arguments.  If ID is NULL use the DECL_NAME as base. If
   FASTCALL is true, also add the FASTCALL_PREFIX.
   Return NULL if no change required.  */

static tree
gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall)
{
  HOST_WIDE_INT total = 0;
  const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
  char *new_str, *p;
  tree type = TREE_TYPE (decl);
  tree arg;
  function_args_iterator args_iter;

  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);  

  if (prototype_p (type))
    {
      /* This attribute is ignored for variadic functions.  */ 
      if (stdarg_p (type))
	return NULL_TREE;

      /* Quit if we hit an incomplete type.  Error is reported
	 by convert_arguments in c-typeck.c or cp/typeck.c.  */
      FOREACH_FUNCTION_ARGS(type, arg, args_iter)
	{
	  HOST_WIDE_INT parm_size;
	  HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;

	  if (! COMPLETE_TYPE_P (arg))
	    break;

	  parm_size = int_size_in_bytes (arg);
	  if (parm_size < 0)
	    break;

	  /* Must round up to include padding.  This is done the same
	     way as in store_one_arg.  */
	  parm_size = ((parm_size + parm_boundary_bytes - 1)
		       / parm_boundary_bytes * parm_boundary_bytes);
	  total += parm_size;
	}
      }
  /* Assume max of 8 base 10 digits in the suffix.  */
  p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1);
  if (fastcall)
    *p++ = FASTCALL_PREFIX;
  sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total);

  return get_identifier (new_str);
}

/* Maybe decorate and get a new identifier for the DECL of a stdcall or
   fastcall function. The original identifier is supplied in ID. */

static tree
i386_emx_maybe_mangle_decl_assembler_name (tree decl, tree id)
{
  tree new_id = NULL_TREE;

  if (TREE_CODE (decl) == FUNCTION_DECL)
    { 
      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
      if (lookup_attribute ("stdcall", type_attributes))
	new_id = gen_stdcall_or_fastcall_suffix (decl, id, false);
      else if (lookup_attribute ("fastcall", type_attributes))
	new_id = gen_stdcall_or_fastcall_suffix (decl, id, true);
    }

  return new_id;
}

/* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
   in the language-independent default hook
   langhooks,c:lhd_set_decl_assembler_name ()
   and in cp/mangle,c:mangle_decl ().  */
tree
i386_emx_mangle_decl_assembler_name (tree decl, tree id)
{
  tree new_id = i386_emx_maybe_mangle_decl_assembler_name (decl, id);   

  return (new_id ? new_id : id);
}
#endif

void
i386_emx_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
{
  rtx symbol;
  int flags;

  dfprintf ((stderr, "trace: i386_emx_encode_section_info\n"));
  DUMP (decl);

  /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above.  */
  default_encode_section_info (decl, rtl, first);

  /* Careful not to prod global register variables.  */
  if (!MEM_P (rtl))
    return;

  symbol = XEXP (rtl, 0);
  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);

#if 0
  switch (TREE_CODE (decl))
    {
    case FUNCTION_DECL:
      if (first)
	{
	  /* FIXME: In Ada, and perhaps other language frontends,
	     imported stdcall names may not yet have been modified.
	     Check and do it know.  */
         tree new_id;
         tree old_id = DECL_ASSEMBLER_NAME (decl);
     	  const char* asm_str = IDENTIFIER_POINTER (old_id);
          /* Do not change the identifier if a verbatim asmspec
	     or if stdcall suffix already added. */
      	  if (*asm_str == '*' || strchr (asm_str, '@'))
            break;
	  if ((new_id = i386_emx_maybe_mangle_decl_assembler_name (decl, old_id)))
	    {
	      /* These attributes must be present on first declaration,
		 change_decl_assembler_name will warn if they are added
		 later and the decl has been referenced, but duplicate_decls
		 should catch the mismatch first.  */
	      change_decl_assembler_name (decl, new_id);
	      XSTR (symbol, 0) = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
	    }
	}
      break;

    case VAR_DECL:
      if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
	{
	  if (DECL_INITIAL (decl)
	      /* If an object is initialized with a ctor, the static
		 initialization and destruction code for it is present in
		 each unit defining the object.  The code that calls the
		 ctor is protected by a link-once guard variable, so that
		 the object still has link-once semantics,  */
	      || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
	    make_decl_one_only (decl);
	  else
	    error ("%q+D:'selectany' attribute applies only to "
		   "initialized objects", decl);
	}
      break;

    default:
      return;
    }
#endif

  /* Mark the decl so we can tell from the rtl whether the object is
     dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
     handles dllexport/dllimport override semantics.  */

  flags = (SYMBOL_REF_FLAGS (symbol) &
	   ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT));

  if (i386_emx_determine_dllexport_p (decl))
    flags |= SYMBOL_FLAG_DLLEXPORT;
  else if (i386_emx_determine_dllimport_p (decl))
    {
      flags |= SYMBOL_FLAG_DLLIMPORT;
      /* If we went through the associated_type path, this won't already
	 be set.  Though, frankly, this seems wrong, and should be fixed
	 elsewhere.  */
      if (!DECL_DLLIMPORT_P (decl))
	{
	  DECL_DLLIMPORT_P (decl) = 1;
	  flags &= ~SYMBOL_FLAG_LOCAL;
	}
    }
  SYMBOL_REF_FLAGS (symbol) = flags;
}

/* [snip] */

#if 0 /* don't think we need this. */
/* Keep a list of external functions.  */

struct extern_list GTY(())
{
  struct extern_list *next;
  tree decl;
  const char *name;
};

static GTY(()) struct extern_list *extern_head;

/* Assemble an external function reference.  We need to keep a list of
   these, so that we can output the function types at the end of the
   assembly.  We can't output the types now, because we might see a
   definition of the function later on and emit debugging information
   for it then.  */

void
i386_emx_record_external_function (tree decl, const char *name)
{
  dfprintf ((stderr, "trace: i386_emx_record_external_function\n"));
  struct extern_list *p;

  p = (struct extern_list *) ggc_alloc (sizeof *p);
  p->next = extern_head;
  p->decl = decl;
  p->name = name;
  extern_head = p;
}
#endif

#if 1
/* i386.c seems to need this for 4.3.2 */
bool
i386_emx_binds_local_p (const_tree exp)
{
  /* PE does not do dynamic binding.  Indeed, the only kind of
     non-local reference comes from a dllimport'd symbol.  */
  if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
      && DECL_DLLIMPORT_P (exp))
    return false;

  return true;
}
#endif

/* Keep a list of exported symbols.  */

struct export_list GTY(())
{
  struct export_list *next;
  tree decl;
  const char *name;
  const char *asm_name;
  const char *exported_name;
  unsigned    ordinal;
  int is_data;		/* used to type tag exported symbols.  */
};

static GTY(()) struct export_list *export_head;

#if 1
/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
   prefix if it exists.  */

const char *
i386_emx_strip_name_encoding (const char *str)
{
  dfprintf ((stderr, "trace: i386_emx_strip_name_encoding(%s)\n", str));
  if (*str == '%')                      /* don't actually know what this is.. */
    str += 2;
  if (*str == '*')
    str += 1;
  return str;
}
#endif
/* Also strip the fastcall prefix and stdcall suffix.  */

const char * emx_strip_name_encoding_full (const char *str)
{
  dfprintf ((stderr, "trace: i386_emx_strip_name_encoding_full(%s)\n", str));
  const char *p;
  const char *ret;
#if 0
  const char *name = default_strip_name_encoding (str);
#else
  const char *name = i386_emx_strip_name_encoding (str);
#endif

  /* Strip leading '@' on fastcall symbols.  */
  if (*name == '@')
    name++;

  /* Strip trailing "@n".  */
  p = strchr (name, '@');
  if (p)
    ret = ggc_alloc_string (name, p - name);
  else 
    ret = name;
  dfprintf ((stderr, "trace: emx_strip_name_encoding_full: '%s' -> '%s'\n", str, ret));
  return ret;
}

void
i386_emx_asm_output_aligned_decl_common (FILE *stream, tree decl,
					const char *name, HOST_WIDE_INT size,
					HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
  dfprintf ((stderr, "trace: i386_emx_asm_output_aligned_decl_common\n"));

  i386_emx_maybe_record_exported_symbol (decl, name, 1);
  rtx symbol;
  symbol = XEXP (DECL_RTL (decl), 0);
  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
  if (!SYMBOL_REF_DLLIMPORT_P (symbol)){
      /* 16 is the best we can do (segment para). */    
      const int xalign = (align) > 16 ? 16 : (align);   
      fprintf ((stream), "\t.comm\t"); 			
      assemble_name ((stream), (name));			
      fprintf ((stream), ", %d\t%s %d\n",		
	       (((size) + xalign - 1) / xalign) * xalign, 
               ASM_COMMENT_START, (size));	        
  }
}

/* Assemble an export symbol entry.  We need to keep a list of
   these, so that we can output the export list at the end of the
   assembly.  We used to output these export symbols in each function,
   but that causes problems with GNU ld when the sections are
   linkonce.  */

void
i386_emx_maybe_record_exported_symbol (tree decl, const char *name, int is_data EMX_DBG_LOC_DECL)
{
  rtx symbol;
  struct export_list *p;

  symbol = XEXP (DECL_RTL (decl), 0);
  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
  if (!SYMBOL_REF_DLLEXPORT_P (symbol)){
    return;}
  dfprintf ((stderr,
             "trace: i386_emx_maybe_record_exported_symbol: %s %s(%d)\n"
             "           name='%s' is_data=%d\n", EMX_DBG_LOC_RARGS, name, is_data));

  p = (struct export_list *) xmalloc (sizeof *p);
  p->next = export_head;
  p->name = name;
  p->asm_name = NULL;
  p->exported_name = NULL;
  p->ordinal = 0;
  p->is_data = is_data;
  export_head = p;
}


/* This is called at the end of assembly.  For each external function
   which has not been defined, we output a declaration now.  We also
   output the .drectve section.  */

void
i386_emx_file_end (void)
{
  dfprintf ((stderr, "trace: emx_file_end\n"));
  struct extern_list *p; 

  ix86_file_end ();

#if 0 /* don't think we need this */
  for (p = extern_head; p != NULL; p = p->next)
    {
      tree decl;

      decl = p->decl;

      /* Positively ensure only one declaration for any given symbol.  */
      if (! TREE_ASM_WRITTEN (decl)
	  && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
	{
	  TREE_ASM_WRITTEN (decl) = 1;
	  i386_emx_declare_function_type (asm_out_file, p->name,
					 TREE_PUBLIC (decl));
	}
    }
#endif

  if (export_head)
    {
      struct export_list *q;
      fprintf (asm_out_file, "\t%s Exports: \"<exportname>,<ordinal>=<asmname>,<code|data>\", N_EXP,0,0,-42\n", ASM_COMMENT_START);

      for (q = export_head; q != NULL; q = q->next)
	{
          static const char * const types[2] = {",code", ",data"};
          tree decl = q->decl;
          if (decl)
            {
              DUMP(decl);
              /* breaks thunks. Windows ain't doing this either.
                 If it turns out to break stuff, try add "|| DECL_COMDAT (decl)".
              if (!TREE_STATIC (decl))
                {
                  dfprintf ((stderr, "dbg: skipping %p. !TREE_STATIC\n", decl));
                  continue;
                }
               */
              if (!q->asm_name)
                q->asm_name = q->exported_name ? q->exported_name
                  : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
            }
          if (!q->asm_name)
            q->asm_name = q->exported_name ? q->exported_name : q->name;
          if (!q->exported_name && !q->ordinal)
            q->exported_name = q->asm_name ? q->asm_name : q->name;
          fprintf (asm_out_file, "\t.stabs\t\"");
          ASM_OUTPUT_LABELREF(asm_out_file, q->exported_name);
          fprintf (asm_out_file, ",%u=", q->ordinal);
          ASM_OUTPUT_LABELREF(asm_out_file, q->asm_name);
          fprintf (asm_out_file, "%s\",0x6c,0,0,-42\t%s %s\n", /* 0x6c == N_EXP */
                   types[q->is_data], ASM_COMMENT_START, q->name);

	}
    }
}

emx.c (37,317 bytes)   
gcc-4.4.4-20100707.diff (82,968 bytes)   
Only in gcc-4.4.4: build-i386-pc-os2-emx
Only in gcc-4.4.4: build.log
Only in gcc-4.4.4: conf.cmd
Only in gcc-4.4.4/config: mh-emx
Only in gcc-4.4.4: config.log
Only in gcc-4.4.4: config.status
diff -ur gcc-4.4.4-o/configure gcc-4.4.4/configure
--- gcc-4.4.4-o/configure	2009-04-25 12:55:28.000000000 +0845
+++ gcc-4.4.4/configure	2010-07-03 11:03:42.000000000 +0845
@@ -2196,7 +2196,7 @@
 	;;
     *-*-solaris2* | *-*-sysv4* | *-*-irix6* | *-*-osf* | *-*-hpux11*)
 	;;
-    *-*-darwin* | *-*-aix*)
+    *-*-darwin* | *-*-aix* | i*86-pc-*emx)
 	;;
     *)
 	noconfigdirs="$noconfigdirs target-libgomp"
diff -ur gcc-4.4.4-o/configure.ac gcc-4.4.4/configure.ac
--- gcc-4.4.4-o/configure.ac	2009-04-25 12:55:28.000000000 +0845
+++ gcc-4.4.4/configure.ac	2010-07-03 11:03:42.000000000 +0845
@@ -431,7 +431,7 @@
 	;;
     *-*-solaris2* | *-*-sysv4* | *-*-irix6* | *-*-osf* | *-*-hpux11*)
 	;;
-    *-*-darwin* | *-*-aix*)
+    *-*-darwin* | *-*-aix*  | i*86-pc-*emx)
 	;;
     *)
 	noconfigdirs="$noconfigdirs target-libgomp"
@@ -1050,6 +1050,9 @@
   i[[3456789]]86-*-msdosdjgpp*)
     host_makefile_frag="config/mh-djgpp"
     ;;
+  i[3456]86-*-os2*)
+    host_makefile_frag="config/mh-emx"
+    ;;
   *-cygwin*)
     ACX_CHECK_CYGWIN_CAT_WORKS
     host_makefile_frag="config/mh-cygwin"
Only in gcc-4.4.4: configure.ac.orig
Only in gcc-4.4.4: configure.lineno
Only in gcc-4.4.4: configure.orig
Only in gcc-4.4.4/fixincludes: configure.orig
Only in gcc-4.4.4/fixincludes: configure.rej
diff -ur gcc-4.4.4-o/fixincludes/fixincl.c gcc-4.4.4/fixincludes/fixincl.c
--- gcc-4.4.4-o/fixincludes/fixincl.c	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/fixincludes/fixincl.c	2010-07-03 11:03:44.000000000 +0845
@@ -29,7 +29,7 @@
 #include <sys/wait.h>
 #endif
 
-#if defined( HAVE_MMAP_FILE )
+#if defined( HAVE_MMAP_FILE ) && !defined(__OS2__)
 #include <sys/mman.h>
 #define  BAD_ADDR ((void*)-1)
 #endif
@@ -336,7 +336,7 @@
       return (char*)NULL;
     }
 
-#ifdef HAVE_MMAP_FILE
+#if defined( HAVE_MMAP_FILE ) && !defined(__OS2__)
   curr_data_mapped = BOOL_TRUE;
 
   /*  IF the file size is a multiple of the page size,
diff -ur gcc-4.4.4-o/fixincludes/fixlib.h gcc-4.4.4/fixincludes/fixlib.h
--- gcc-4.4.4-o/fixincludes/fixlib.h	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/fixincludes/fixlib.h	2010-07-03 11:03:44.000000000 +0845
@@ -211,7 +211,7 @@
 
 extern int gnu_type_map_ct;
 
-#ifdef HAVE_MMAP_FILE
+#if defined( HAVE_MMAP_FILE ) && !defined(__OS2__)
 #define UNLOAD_DATA() do { if (curr_data_mapped) { \
   munmap ((void*)pz_curr_data, data_map_size); close (data_map_fd); } \
   else free ((void*)pz_curr_data); } while(0)
Only in gcc-4.4.4/fixincludes: fixlib.h.orig
Only in gcc-4.4.4/fixincludes/tests/base: arpa
Only in gcc-4.4.4/fixincludes/tests/base: fs
Only in gcc-4.4.4/fixincludes/tests/base: machine
Only in gcc-4.4.4/gcc: ada
Only in gcc-4.4.4/gcc: builtins.c.orig
Only in gcc-4.4.4/gcc: builtins.c.rej
diff -ur gcc-4.4.4-o/gcc/c-decl.c gcc-4.4.4/gcc/c-decl.c
--- gcc-4.4.4-o/gcc/c-decl.c	2010-03-27 21:31:06.000000000 +0945
+++ gcc-4.4.4/gcc/c-decl.c	2010-07-03 11:03:44.000000000 +0845
@@ -1353,6 +1353,7 @@
 	     built in, newdecl silently overrides olddecl.  The latter
 	     occur only in Objective C; see also above.  (FIXME: Make
 	     Objective C use normal builtins.)  */
+
 	  if (!DECL_IS_BUILTIN (olddecl)
 	      && !DECL_EXTERN_INLINE (olddecl))
 	    {
Only in gcc-4.4.4/gcc: c-decl.c.orig
Only in gcc-4.4.4/gcc: c-decl.c.rej
diff -ur gcc-4.4.4-o/gcc/calls.c gcc-4.4.4/gcc/calls.c
--- gcc-4.4.4-o/gcc/calls.c	2009-10-12 22:23:28.000000000 +0845
+++ gcc-4.4.4/gcc/calls.c	2010-07-03 11:03:44.000000000 +0845
@@ -3949,7 +3949,9 @@
   va_list p;
 
   va_start (p, nargs);
+
   emit_library_call_value_1 (0, orgfun, NULL_RTX, fn_type, outmode, nargs, p);
+
   va_end (p);
 }
 
Only in gcc-4.4.4/gcc: calls.c.orig
Only in gcc-4.4.4/gcc/config/i386: emx-ctordtor.c
Only in gcc-4.4.4/gcc/config/i386: emx-cxx.c
Only in gcc-4.4.4/gcc/config/i386: emx-dllinit.c
Only in gcc-4.4.4/gcc/config/i386: emx-eh.c
Only in gcc-4.4.4/gcc/config/i386: emx-libgcc_so_d.def
Only in gcc-4.4.4/gcc/config/i386: emx-libgcc1.asm
Only in gcc-4.4.4/gcc/config/i386: emx-stubs.c
Only in gcc-4.4.4/gcc/config/i386: emx.c
Only in gcc-4.4.4/gcc/config/i386: emx.h
Only in gcc-4.4.4/gcc/config/i386: host-emx.c
diff -ur gcc-4.4.4-o/gcc/config/i386/i386-protos.h gcc-4.4.4/gcc/config/i386/i386-protos.h
--- gcc-4.4.4-o/gcc/config/i386/i386-protos.h	2009-07-12 03:51:26.000000000 +0845
+++ gcc-4.4.4/gcc/config/i386/i386-protos.h	2010-07-03 11:12:16.000000000 +0845
@@ -187,6 +187,8 @@
 extern void ix86_expand_truncdf_32 (rtx, rtx);
 
 #ifdef TREE_CODE
+extern int ix86_check_append_attr PARAMS ((tree, tree, bool *));
+
 extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
 extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
 extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
@@ -204,6 +206,9 @@
 extern unsigned int ix86_minimum_alignment (tree, enum machine_mode,
 					    unsigned int);
 extern int ix86_constant_alignment (tree, int);
+#ifdef __EMX__
+extern tree ix86_handle_dll_attribute (tree *, tree, tree, int, bool *);
+#endif
 extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
 extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
 extern int x86_field_alignment (tree, int);
@@ -279,3 +284,16 @@
 #ifdef HAVE_ATTR_cpu
 extern enum attr_cpu ix86_schedule;
 #endif
+
+/* In emx.c  */
+extern bool i386_emx_binds_local_p (const_tree);
+extern void i386_emx_init_sections (void);
+extern void i386_emx_asm_out_destructor (rtx, int);
+extern tree i386_emx_mangle_decl_assembler_name (tree, tree);
+extern void i386_emx_maybe_record_exported_symbol (tree, const char *, int);
+extern bool i386_emx_valid_dllimport_attribute_p (const_tree);
+
+/* In emx-cxx.c  */
+extern void i386_emx_adjust_class_at_definition (tree);
+extern bool i386_emx_type_dllimport_p (tree);
+extern bool i386_emx_type_dllexport_p (tree);
Only in gcc-4.4.4/gcc/config/i386: i386-protos.h.orig
Only in gcc-4.4.4/gcc/config/i386: i386-protos.h.rej
diff -ur gcc-4.4.4-o/gcc/config/i386/i386.c gcc-4.4.4/gcc/config/i386/i386.c
--- gcc-4.4.4-o/gcc/config/i386/i386.c	2010-04-08 23:54:16.000000000 +0845
+++ gcc-4.4.4/gcc/config/i386/i386.c	2010-07-04 08:12:00.000000000 +0845
@@ -62,6 +62,10 @@
 #define CHECK_STACK_LIMIT (-1)
 #endif
 
+#ifdef EMX
+extern bool i386_emx_binds_local_p (const_tree);
+#endif
+
 /* Return index of given mode in mult and division cost tables.  */
 #define MODE_INDEX(mode)					\
   ((mode) == QImode ? 0						\
@@ -4093,7 +4097,6 @@
   if (level > 1)
     flag_schedule_insns = 0;
 #endif
-
   if (TARGET_MACHO)
     /* The Darwin libraries never set errno, so we might as well
        avoid calling them when that's the only reason we would.  */
@@ -4341,6 +4344,7 @@
 
   return 1;
 }
+
 
 /* Return the regparm value for a function with the indicated TYPE and DECL.
    DECL may be NULL when calling function indirectly
@@ -4529,7 +4533,11 @@
   rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
 
   /* Cdecl functions override -mrtd, and never pop the stack.  */
-  if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype)))
+  if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))
+#ifdef TARGET_SYSTEM_DECL_ATTRIBUTES
+   && ! lookup_attribute ("system", TYPE_ATTRIBUTES (funtype))
+#endif
+     ) 
     {
       /* Stdcall and fastcall functions will pop the stack if not
          variable args.  */
@@ -4756,6 +4764,11 @@
 		      ? (!prototype_p (fntype) || stdarg_p (fntype))
 		      : !libname);
 
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTESx
+  /* _Optlink calling convention says all args until the ellipsis
+             are passed in registers, and all varargs on the stack. */
+  if (!cum->optlink)
+#endif
   if (!TARGET_64BIT)
     {
       /* If there are variable arguments, then we won't pass anything
@@ -4781,8 +4794,26 @@
 	      cum->fastcall = 1;
 	    }
 	  else
-	    cum->nregs = ix86_function_regparm (fntype, fndecl);
+            {
+		cum->nregs = ix86_function_regparm (fntype, fndecl);
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTESx
+		if (lookup_attribute ("optlink", TYPE_ATTRIBUTES (fntype)))
+	          {
+			cum->nregs = 3; cum->optlink = 1;
+		  }
+#endif
+	    }
 	}
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTESx
+      /* Limit number of registers to pass arguments as in _Optlink specification */
+      if (cum->optlink)
+        {
+          if (cum->nregs > 3)
+            cum->nregs = 3;
+          if (cum->fpu_nregs > 4)
+            cum->fpu_nregs = 4;
+        }
+#endif
 
       /* Set up the number of SSE registers used for passing SFmode
 	 and DFmode arguments.  Warn for mismatching ABI.  */
@@ -5579,6 +5610,61 @@
     case HImode:
     case QImode:
       cum->words += words;
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTESx
+          /* Optlink functions never pass aggregates in registers
+             (they are pushed on the stack, and the registers are
+             preserved for following parameters). */
+          if (cum->optlink)
+            {
+              /* If out of eyecatcher slots, do nothing */
+              if (!cum->ec_slots)
+                return;
+
+              if (INTEGRAL_TYPE_P (type)
+               || POINTER_TYPE_P (type))
+                {
+                  /* Integer types takes one slot in eyecatcher */
+                  cum->ec_slots--;
+                }
+              else if (FLOAT_MODE_P (mode))
+                {
+                  /* Fixed-point parameters are passed in FPU registers */
+                  if (cum->fpu_nregs)
+                    {
+                      cum->fpu_nregs--;
+                      cum->fpu_regno++;
+                      /* Args passed in FPU stack takes one eyecatcher slot */
+                      cum->ec_slots--;
+                    }
+                  else
+                    {
+                      /* FPU args passed on RT stack takes 1/2/4 slots */
+                      cum->ec_slots -= words;
+                    }
+
+                  /* The case with ec_slots <= 0 will be catched a little lates */
+                  if (cum->ec_slots > 0)
+                    return;
+                }
+              else
+                {
+                  /* This is nor a integer, address or float parameter.
+                     Pass it on the stack but count its size in eyecatcher. */
+                  cum->ec_slots -= words;
+                  if (cum->ec_slots > 0)
+                    return;
+                }
+
+              /* If we're out of eyecatcher slots, pass the arg on the stack */
+              if (cum->ec_slots <= 0)
+                {
+                  cum->ec_slots = 0;
+                  cum->nregs = 0;
+                  cum->fpu_nregs = 0;
+                  return;
+                }
+            }
+#endif
       cum->nregs -= words;
       cum->regno += words;
 
@@ -5732,11 +5818,37 @@
   if (mode == VOIDmode)
     return constm1_rtx;
 
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTESx
+  rtx ret = NULL_RTX;
+      /* For optlink calling convention, don't pass anything other than
+         integral types and floats through registers. */
+      if (!cum->optlink
+          || INTEGRAL_TYPE_P (type)
+          || POINTER_TYPE_P (type)
+          || (TREE_CODE (type) == REAL_TYPE))
+#endif
+
   switch (mode)
     {
     default:
       break;
 
+#if defined TARGET_OPTLINK_DECL_ATTRIBUTESx
+        case XFmode:
+        case TFmode:
+        if (cum->fpu_nregs && cum->optlink && cum->ec_slots)
+          {
+            /* Pass first four floating-point args in FPU registers */
+            ret = gen_rtx_PARALLEL (mode, rtvec_alloc (2));
+            XVECEXP (ret, 0, 0) = gen_rtx_EXPR_LIST ( VOIDmode,
+                                           NULL_RTX, const0_rtx);
+            XVECEXP (ret, 0, 1) = gen_rtx_EXPR_LIST (VOIDmode,
+                                           gen_rtx_REG ( mode, FIRST_FLOAT_REG + cum->fpu_regno),
+                                           const0_rtx);
+          }
+        break;
+#endif
+
     case BLKmode:
       if (bytes < 0)
 	break;
@@ -5746,6 +5858,28 @@
     case HImode:
     case QImode:
       if (words <= cum->nregs)
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTESx
+          {
+            if (cum->optlink)
+              {
+                if (cum->ec_slots)
+                  {
+                    /* Optlink specs says that the parameter is passed in a register
+                       and space on the stack is reserved for it as well (which is not
+                       filled). Currently GCC will pass the parameter *both* in register
+                       and stack; this is suboptimal but is compatible. */
+                    ret = gen_rtx_PARALLEL ( mode, rtvec_alloc (2));
+                    XVECEXP (ret, 0, 0) = gen_rtx_EXPR_LIST ( VOIDmode,
+                                                   NULL_RTX, const0_rtx);
+                    XVECEXP (ret, 0, 1) = gen_rtx_EXPR_LIST ( VOIDmode,
+                                                   gen_rtx_REG ( mode, cum->regno),
+                                                   const0_rtx);
+                  }
+              }
+            else
+              ret = gen_rtx_REG (mode, cum->regno);
+          }
+#else
 	{
 	  int regno = cum->regno;
 
@@ -5765,6 +5899,7 @@
 	    }
 	  return gen_rtx_REG (mode, regno);
 	}
+#endif
       break;
 
     case DFmode:
@@ -5832,6 +5967,9 @@
 				        cum->mmx_regno + FIRST_MMX_REG);
 	}
       break;
+#ifdef __OS2__x /* ????? */
+      }
+#endif
     }
 
   return NULL_RTX;
@@ -6004,6 +6142,9 @@
        || mode == TFmode
        || mode == TCmode)
       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTESz
+          && !cum->optlink
+#endif
     return true;
   if (TYPE_ALIGN (type) < 128)
     return false;
@@ -9023,12 +9164,13 @@
       if (SYMBOL_REF_TLS_MODEL (x))
 	return false;
 
+#ifndef __EMX__ /* 2009-01-15 */
       /* DLLIMPORT symbols are never valid.  */
       if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
-	  && SYMBOL_REF_DLLIMPORT_P (x))
+	  && SYMBOL_REF_DLLIMPORT_P (x)) 
 	return false;
+#endif
       break;
-
     case CONST_DOUBLE:
       if (GET_MODE (x) == TImode
 	  && x != CONST0_RTX (TImode)
@@ -9944,7 +10086,11 @@
   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
   name = targetm.strip_name_encoding (name);
   prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
+#ifndef __OS2__
     ? "*__imp_" : "*__imp__";
+#else
+    ? "" : "";
+#endif
   namelen = strlen (name);
   prefixlen = strlen (prefix);
   imp_name = (char *) alloca (namelen + prefixlen + 1);
@@ -9958,7 +10104,6 @@
 
   rtl = gen_const_mem (Pmode, rtl);
   set_mem_alias_set (rtl, ix86_GOT_alias_set ());
-
   SET_DECL_RTL (to, rtl);
   SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
 
@@ -10023,7 +10168,8 @@
       return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
     }
 
-  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
+#ifndef __EMX__ /* 2009-01-15 */
+  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES) 
     {
       if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (x))
 	return legitimize_dllimport_symbol (x, true);
@@ -10036,7 +10182,7 @@
 	  return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
 	}
     }
-
+#endif
   if (flag_pic && SYMBOLIC_CONST (x))
     return legitimize_pic_address (x, 0);
 
@@ -12336,9 +12482,11 @@
 	  if (op1 == op0)
 	    return;
 	}
+#ifndef __EMX__ /* 2009-01-16 */
       else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
-	       && SYMBOL_REF_DLLIMPORT_P (op1))
+	       && SYMBOL_REF_DLLIMPORT_P (op1)) 
 	op1 = legitimize_dllimport_symbol (op1, false);
+#endif
     }
   else if (GET_CODE (op1) == CONST
 	   && GET_CODE (XEXP (op1, 0)) == PLUS
@@ -12351,10 +12499,11 @@
       model = SYMBOL_REF_TLS_MODEL (symbol);
       if (model)
 	tmp = legitimize_tls_address (symbol, model, true);
+#ifndef __EMX__ /* 2009-01-16 */
       else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
-	       && SYMBOL_REF_DLLIMPORT_P (symbol))
+	       && SYMBOL_REF_DLLIMPORT_P (symbol)) 
 	tmp = legitimize_dllimport_symbol (symbol, true);
-
+#endif
       if (tmp)
 	{
 	  tmp = force_operand (tmp, NULL);
@@ -29530,10 +29679,22 @@
 }
 
 
-/* Table of valid machine attributes.  */
+/* Table of valid machine attributes.  
+   If you change it, you must change the array at the beginning of 
+   ix86_comp_type_attributes() as well! */
 static const struct attribute_spec ix86_attribute_table[] =
 {
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+#ifdef EMX /** @todo: ugly stuff, cleanup later. */
+  /* Stdcall attribute says callee is responsible for popping arguments
+     if they are not variable.  */
+  { "stdcall",   0, 0, false, false, false, ix86_handle_system_attribute },
+  /* Fastcall attribute says callee is responsible for popping arguments
+     if they are not variable.  */
+  { "fastcall",  0, 0, false, false,  false,  ix86_handle_system_attribute },
+  /* Cdecl attribute says the callee is a normal C declaration */
+  { "cdecl",     0, 0, false, false, false, ix86_handle_system_attribute },
+#else
   /* Stdcall attribute says callee is responsible for popping arguments
      if they are not variable.  */
   { "stdcall",   0, 0, false, true,  true,  ix86_handle_cconv_attribute },
@@ -29542,6 +29703,7 @@
   { "fastcall",  0, 0, false, true,  true,  ix86_handle_cconv_attribute },
   /* Cdecl attribute says the callee is a normal C declaration */
   { "cdecl",     0, 0, false, true,  true,  ix86_handle_cconv_attribute },
+#endif
   /* Regparm attribute specifies how many integer arguments are to be
      passed in registers.  */
   { "regparm",   1, 1, false, true,  true,  ix86_handle_cconv_attribute },
@@ -29551,6 +29713,7 @@
   /* force_align_arg_pointer says this function realigns the stack at entry.  */
   { (const char *)&ix86_force_align_arg_pointer_string, 0, 0,
     false, true,  true, ix86_handle_cconv_attribute },
+
 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   { "dllimport", 0, 0, false, false, false, handle_dll_attribute },
   { "dllexport", 0, 0, false, false, false, handle_dll_attribute },
@@ -29565,9 +29728,107 @@
   { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
   { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
   /* End element.  */
+#ifdef EMX /** @todo: ugly stuff, cleanup later. */
+#ifdef TARGET_SYSTEM_DECL_ATTRIBUTES
+  /* System says the function is extern "C" and is not underscored. */
+  { "system",    0, 0, false, false, false, ix86_handle_system_attribute },
+#endif
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTES
+  /* Optlink is like regparm with a few differences */
+  { "optlink",   0, 0, false, false, false, ix86_handle_optlink_attribute },
+#endif
+#else
+#ifdef TARGET_SYSTEM_DECL_ATTRIBUTES
+  /* System says the function is extern "C" and is not underscored. */
+  { "system",    0, 0, false, true,  true,  ix86_handle_system_attribute },
+#endif
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTES
+  /* Optlink is like regparm with a few differences */
+  { "optlink",   0, 0, false, true,  true,  ix86_handle_optlink_attribute },
+#endif
+#endif
   { NULL,        0, 0, false, false, false, NULL }
 };
 
+/* The attribute denotes a calling convention */
+#define IX86_ATTR_TYPE_CALLCONV  0x00010000
+/* Calling convention mask: attributes with bits
+   in these positions equal are nealy compatible */
+#define IX86_ATTR_MASK_CALLCONV  0x0000000f
+/* Ordinal number for attributes with equal calling convention bits */
+#define IX86_ATTR_MASK_ORDINAL   0x000000f0
+
+/* This array contains some flags containing additional information
+   about attributes. Keep it in sync with ix86_attribute_table. */
+static unsigned ix86_attribute_codes [] =
+{
+  IX86_ATTR_TYPE_CALLCONV | 0x01, /* stdcall */
+  IX86_ATTR_TYPE_CALLCONV | 0x05, /* fastcall */
+  IX86_ATTR_TYPE_CALLCONV | 0x02, /* cdecl */
+  IX86_ATTR_TYPE_CALLCONV | 0x03, /* regparm */
+  IX86_ATTR_TYPE_CALLCONV | 0x06, /* sseregparm */
+#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+  0, /* dllimport */
+  0, /* dllexport */
+  0, /* shared */
+#endif
+  IX86_ATTR_TYPE_CALLCONV | 0x07, /* ms_struct */
+  IX86_ATTR_TYPE_CALLCONV | 0x08, /* gcc_struct */
+#ifdef TARGET_SYSTEM_DECL_ATTRIBUTES
+  IX86_ATTR_TYPE_CALLCONV | 0x12, /* system is compatible with cdecl */
+#endif
+#ifdef TARGET_OPTLINK_DECL_ATTRIBUTES
+  IX86_ATTR_TYPE_CALLCONV | 0x04, /* optlink */
+#endif
+};
+
+
+/* Check if we don't have incompatible calling conversion attributes */
+int
+ix86_check_append_attr (type, name, no_add_attrs)
+    tree type, name;
+     bool *no_add_attrs;
+{
+  /* ??? use ix86_comp_type_attributes maybe ??? */
+  unsigned i;
+  const char *exclname;
+
+  exclname = IDENTIFIER_POINTER (name);
+  if (exclname [0] == '_')
+    {
+      /* Remove leading and trailing underscores */
+      const char *x1, *x2;
+      char *newname;
+      x1 = exclname + 1;
+      while (*x1 == '_')
+        x1++;
+      x2 = strchr (x1, 0);
+      while (x2 [-1] == '_' && x2 > x1)
+        x2--;
+      newname = alloca (x2 - x1 + 1);
+      memcpy (newname, x1, x2 - x1);
+      newname [x2 - x1] = 0;
+      exclname = newname;
+    }
+
+  for (i = 0; ix86_attribute_table [i].name; i++)
+    if ((ix86_attribute_codes [i] & IX86_ATTR_TYPE_CALLCONV)
+     && lookup_attribute (ix86_attribute_table [i].name, TYPE_ATTRIBUTES (type)))
+      {
+        /* Warn if we have another calling convention attribute and it is
+           different from the currently processed attribute. If there is
+           already an attribute with the same name attached, silently ignore
+           currently processed attribute. */
+        if (strcmp (exclname, ix86_attribute_table [i].name))
+          warning ("`%s' attribute is incompatible with earlier defined `%s' attribute",
+                   IDENTIFIER_POINTER (name), ix86_attribute_table [i].name);
+        *no_add_attrs = true;
+        return -1;
+      }
+
+  return 0;
+}
+
 /* Implement targetm.vectorize.builtin_vectorization_cost.  */
 static int
 x86_builtin_vectorization_cost (bool runtime_test)
@@ -29805,8 +30066,13 @@
 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
 #endif
 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#ifndef __EMX__
 #undef TARGET_BINDS_LOCAL_P
 #define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
+#else
+#undef TARGET_BINDS_LOCAL_P
+#define TARGET_BINDS_LOCAL_P i386_emx_binds_local_p
+#endif /* __EMX__ */
 #endif
 
 #undef TARGET_ASM_OUTPUT_MI_THUNK
Only in gcc-4.4.4/gcc/config/i386: i386.c.orig
Only in gcc-4.4.4/gcc/config/i386: i386.c.rej
diff -ur gcc-4.4.4-o/gcc/config/i386/i386.h gcc-4.4.4/gcc/config/i386/i386.h
--- gcc-4.4.4-o/gcc/config/i386/i386.h	2009-11-14 04:58:16.000000000 +0945
+++ gcc-4.4.4/gcc/config/i386/i386.h	2010-07-04 18:47:26.000000000 +0845
@@ -1586,6 +1586,12 @@
 				   be passed in SSE registers.  Otherwise 0.  */
   int call_abi;			/* Set to SYSV_ABI for sysv abi. Otherwise
  				   MS_ABI for ms abi.  */
+#ifdef EMX
+  int fpu_regno;		/* next available FPU register number */
+  int fpu_nregs;		/* # registers available for passing */
+  int ec_slots;			/* # eyecatcher slots left (see optlink specs) */
+  int optlink;			/* nonzero if optlink (vs. regparm) */
+#endif /* EMX */
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
Only in gcc-4.4.4/gcc/config/i386: i386.h.orig
Only in gcc-4.4.4/gcc/config/i386: i386.h.rej
diff -ur gcc-4.4.4-o/gcc/config/i386/i386.md gcc-4.4.4/gcc/config/i386/i386.md
--- gcc-4.4.4-o/gcc/config/i386/i386.md	2009-12-08 00:29:18.000000000 +0945
+++ gcc-4.4.4/gcc/config/i386/i386.md	2010-07-03 14:35:56.000000000 +0845
@@ -20298,7 +20298,7 @@
    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
    (clobber (reg:CC FLAGS_REG))]
   "!TARGET_64BIT && TARGET_STACK_PROBE"
-  "call\t___chkstk"
+  "call\t__alloca"
   [(set_attr "type" "multi")
    (set_attr "length" "5")])
 
@@ -20311,7 +20311,7 @@
    (clobber (reg:DI R11_REG))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && TARGET_STACK_PROBE"
-  "call\t___chkstk"
+  "call\t__alloca"
   [(set_attr "type" "multi")
    (set_attr "length" "5")])
 
diff -ur gcc-4.4.4-o/gcc/config/i386/predicates.md gcc-4.4.4/gcc/config/i386/predicates.md
--- gcc-4.4.4-o/gcc/config/i386/predicates.md	2009-11-15 04:38:08.000000000 +0945
+++ gcc-4.4.4/gcc/config/i386/predicates.md	2010-07-03 11:03:46.000000000 +0845
@@ -501,8 +501,10 @@
 {
   if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
     return false;
+#ifndef __EMX__ /* mangles dllimport symbols in a bad way on OS/2 */
   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op))
     return false;
+#endif
   return true;
 })
 
Only in gcc-4.4.4/gcc/config/i386: predicates.md.orig
Only in gcc-4.4.4/gcc/config/i386: t-emx
Only in gcc-4.4.4/gcc/config/i386: x-emx
Only in gcc-4.4.4/gcc/config/i386: xm-emx.h
Only in gcc-4.4.4/gcc/config: mt
diff -ur gcc-4.4.4-o/gcc/config.build gcc-4.4.4/gcc/config.build
--- gcc-4.4.4-o/gcc/config.build	2008-02-22 05:40:38.000000000 +0945
+++ gcc-4.4.4/gcc/config.build	2010-07-03 11:03:46.000000000 +0845
@@ -119,5 +119,9 @@
     # All other System V variants.
     build_install_headers_dir=install-headers-cpio
     ;;
+i*86-pc-*emx)		# i?86 running OS/2
+    build_xm_file=i386/xm-emx.h
+    exeext=.exe
+    build_exeext=.exe
 esac
 
diff -ur gcc-4.4.4-o/gcc/config.gcc gcc-4.4.4/gcc/config.gcc
--- gcc-4.4.4-o/gcc/config.gcc	2010-02-18 14:09:04.000000000 +0945
+++ gcc-4.4.4/gcc/config.gcc	2010-07-03 15:10:10.000000000 +0845
@@ -1303,6 +1303,25 @@
 			;;
 	esac
 	;;
+i*86-pc-*emx)		# i?86 running OS/2
+	xm_file=i386/xm-emx.h
+	tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h i386/emx.h"
+	extra_objs="emx.o emx-stubs.o"
+	cxx_target_objs="${cxx_target_objs} emx-cxx.o"
+	xm_defines="USG BSTRING NO_SYS_SIGLIST"
+	exeext=.exe
+	tmake_file=i386/t-emx
+    # r=bird: why do we do this??
+	target_alias=${host}
+    # r=bird: and this??
+	CFLAGS="-Zstack 1024 -Zcrtdll"
+	if test x$enable_threads = xyes; then
+		thread_file=os2
+	fi
+	gas=yes
+	gnu_ld=yes
+	float_format=none
+	;;
 i[34567]86-*-interix3*)
 	tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h i386/i386-interix3.h interix.h interix3.h"
 	tmake_file="${tmake_file} i386/t-interix"
Only in gcc-4.4.4/gcc: config.gcc.orig
diff -ur gcc-4.4.4-o/gcc/config.host gcc-4.4.4/gcc/config.host
--- gcc-4.4.4-o/gcc/config.host	2009-09-14 01:47:50.000000000 +0845
+++ gcc-4.4.4/gcc/config.host	2010-07-03 11:15:56.000000000 +0845
@@ -197,6 +197,11 @@
         ;;
     esac
     ;;
+  i*86-pc-*emx)		# i?86 running OS/2
+    host_exeext=.exe
+#    out_host_hook_obj=host-emx.o
+#    host_xmake_file="${host_xmake_file} i386/x-emx"
+    ;;
   i[34567]86-*-pe | i[34567]86-*-cygwin*)
     host_xm_file=i386/xm-cygwin.h
     out_host_hook_obj=host-cygwin.o
Only in gcc-4.4.4/gcc: config.host.orig
Only in gcc-4.4.4/gcc: config.host.rej
diff -ur gcc-4.4.4-o/gcc/cp/class.c gcc-4.4.4/gcc/cp/class.c
--- gcc-4.4.4-o/gcc/cp/class.c	2009-06-25 01:47:02.000000000 +0845
+++ gcc-4.4.4/gcc/cp/class.c	2010-07-03 11:03:46.000000000 +0845
@@ -2384,6 +2384,18 @@
       if (!DECL_VINDEX (decl))
 	DECL_VINDEX (decl) = error_mark_node;
       IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
+/* Added 2009-01-11 */
+      if (DECL_DLLIMPORT_P (decl))
+	{
+	  /* When we handled the dllimport attribute we may not have known
+	     that this function is virtual   We can't use dllimport 
+	     semantics for a virtual method because we need to initialize
+	     the vtable entry with a constant address.  */
+	  DECL_DLLIMPORT_P (decl) = 0;
+	  DECL_ATTRIBUTES (decl)
+	    = remove_attribute ("dllimport", DECL_ATTRIBUTES (decl));
+	}
+
     }
 }
 
Only in gcc-4.4.4/gcc/cp: class.c.orig
diff -ur gcc-4.4.4-o/gcc/cp/cp-tree.h gcc-4.4.4/gcc/cp/cp-tree.h
--- gcc-4.4.4-o/gcc/cp/cp-tree.h	2009-12-16 00:59:58.000000000 +0945
+++ gcc-4.4.4/gcc/cp/cp-tree.h	2010-07-03 11:03:46.000000000 +0845
@@ -4461,7 +4461,11 @@
 extern void expand_end_catch_block		(void);
 extern tree build_exc_ptr			(void);
 extern tree build_throw				(tree);
+#ifndef __OS2__
 extern int nothrow_libfn_p			(const_tree);
+#else
+extern int nothrow_libfn_p			(tree);
+#endif
 extern void check_handlers			(tree);
 extern void choose_personality_routine		(enum languages);
 extern tree eh_type_info			(tree);
Only in gcc-4.4.4/gcc/cp: cp-tree.h.orig
diff -ur gcc-4.4.4-o/gcc/cp/decl.c gcc-4.4.4/gcc/cp/decl.c
--- gcc-4.4.4-o/gcc/cp/decl.c	2010-01-15 08:34:16.000000000 +0945
+++ gcc-4.4.4/gcc/cp/decl.c	2010-07-03 11:03:46.000000000 +0845
@@ -10720,7 +10720,22 @@
 	    }
 	}
     }
-
+#if 0 /* Broken in 3.4.6 - is it still necessary??? */
+#if 1 /* bird: HACK ALERT! HACK ALERT! */
+  /* Don't replace attributes with nothing. See the nsSupportWeakReference / friend problem.
+     Limit any negative sideeffects this hack may have by only caring for a select number of attributes. */
+  if (   TYPE_ATTRIBUTES (t)
+      && (   lookup_attribute ("dllexport", TYPE_ATTRIBUTES (t))
+          || lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t))
+          || lookup_attribute ("system", TYPE_ATTRIBUTES (t))
+          || lookup_attribute ("cdecl", TYPE_ATTRIBUTES (t))
+          || lookup_attribute ("optlink", TYPE_ATTRIBUTES (t))
+          || lookup_attribute ("stdcall", TYPE_ATTRIBUTES (t))))
+    TYPE_ATTRIBUTES (t) = merge_attributes(TYPE_ATTRIBUTES (t), attributes);
+  else
+    TYPE_ATTRIBUTES (t) = attributes;
+#endif
+#endif
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 }
 
Only in gcc-4.4.4/gcc/cp: decl.c.orig
diff -ur gcc-4.4.4-o/gcc/cp/dump.c gcc-4.4.4/gcc/cp/dump.c
--- gcc-4.4.4-o/gcc/cp/dump.c	2008-03-22 04:41:50.000000000 +0945
+++ gcc-4.4.4/gcc/cp/dump.c	2010-07-03 11:03:46.000000000 +0845
@@ -202,6 +202,31 @@
   }
 }
 
+#if 1 /* bird hacking */
+static void cp_dump_attributes (dump_info_p di, tree t)
+{
+  tree attr = NULL;
+  if (DECL_P (t))
+    attr = DECL_ATTRIBUTES (t);
+  else if (TYPE_P (t))
+    attr = TYPE_ATTRIBUTES (t);
+  else
+    return;
+  if (lookup_attribute ("optlink", attr))
+    dump_string (di, "optlink");
+  if (lookup_attribute ("stdcall", attr))
+    dump_string (di, "stdcall");
+  if (lookup_attribute ("cdecl", attr))
+    dump_string (di, "cdecl");
+  if (lookup_attribute ("system", attr))
+    dump_string (di, "system");
+  if (lookup_attribute ("dllexport", attr))
+    dump_string (di, "dllexport");
+  if (lookup_attribute ("dllimport", attr))
+    dump_string (di, "dllimport");
+}
+#endif /* bird hacking */
+
 bool
 cp_dump_tree (void* dump_info, tree t)
 {
@@ -217,6 +242,10 @@
 	dump_string_field (di, "lang", language_to_string (DECL_LANGUAGE (t)));
     }
 
+#if 1 /* bird hacking */
+  cp_dump_attributes (di, t);
+#endif 
+
   switch (code)
     {
     case IDENTIFIER_NODE:
diff -ur gcc-4.4.4-o/gcc/cp/error.c gcc-4.4.4/gcc/cp/error.c
--- gcc-4.4.4-o/gcc/cp/error.c	2009-08-04 21:13:26.000000000 +0845
+++ gcc-4.4.4/gcc/cp/error.c	2010-07-03 11:17:58.000000000 +0845
@@ -28,6 +28,7 @@
 #include "toplev.h"
 #include "flags.h"
 #include "diagnostic.h"
+#include "tm_p.h"
 #include "langhooks-def.h"
 #include "cxx-pretty-print.h"
 
@@ -590,12 +591,18 @@
 	 templates, e.g. std::is_function.  */
     case FUNCTION_TYPE:
       dump_type_prefix (TREE_TYPE (t), flags);
+#ifdef TARGET_PRINT_TYPE_ATTRS
+      TARGET_PRINT_TYPE_ATTRS (t, scratch_buffer);
+#endif
       break;
 
     case METHOD_TYPE:
       dump_type_prefix (TREE_TYPE (t), flags);
       pp_maybe_space (cxx_pp);
       pp_cxx_left_paren (cxx_pp);
+#ifdef TARGET_PRINT_TYPE_ATTRS
+      TARGET_PRINT_TYPE_ATTRS (t, scratch_buffer);
+#endif
       dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
       pp_cxx_colon_colon (cxx_pp);
       break;
Only in gcc-4.4.4/gcc/cp: error.c.orig
Only in gcc-4.4.4/gcc/cp: error.c.rej
diff -ur gcc-4.4.4-o/gcc/cp/except.c gcc-4.4.4/gcc/cp/except.c
--- gcc-4.4.4-o/gcc/cp/except.c	2008-08-18 20:02:52.000000000 +0845
+++ gcc-4.4.4/gcc/cp/except.c	2010-07-03 11:03:46.000000000 +0845
@@ -929,8 +929,13 @@
 
 #include "cfns.h"
 
+#ifndef __OS2__
 int
 nothrow_libfn_p (const_tree fn)
+#else
+int
+nothrow_libfn_p (tree fn)
+#endif
 {
   tree id;
 
@@ -947,6 +952,13 @@
      unless the system headers are playing rename tricks, and if
      they are, we don't want to be confused by them.  */
   id = DECL_NAME (fn);
+#ifdef TARGET_CXX_SET_DECL_ASSEMBLER_NAME /* GCC-OS2 */
+  /* Actually the above is a bug. We can't mangle correctly unless we
+     have a complete decl. Until then, as a partial fix, reset the
+     mangled name to NULL so that next DECL_ASSEMBLER_NAME calls
+     mangler again, now with a complete decl. */
+  SET_DECL_ASSEMBLER_NAME(fn, NULL_TREE);
+#endif
   return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
 }
 
Only in gcc-4.4.4/gcc/cp: except.c.orig
diff -ur gcc-4.4.4-o/gcc/cp/g++spec.c gcc-4.4.4/gcc/cp/g++spec.c
--- gcc-4.4.4-o/gcc/cp/g++spec.c	2009-02-21 01:05:38.000000000 +0945
+++ gcc-4.4.4/gcc/cp/g++spec.c	2010-07-03 11:03:46.000000000 +0845
@@ -47,6 +47,12 @@
 #ifndef LIBSTDCXX_STATIC
 #define LIBSTDCXX_STATIC LIBSTDCXX
 #endif
+#ifdef LIBSTDCXX_STATIC                                                             /* bird */
+#define LIBSTDCXX_STATIC "-lstdc++"                                                 /* bird */
+#endif                                                                              /* bird */
+#ifdef LIBSTDCXX_PROFILE_STATIC                                                     /* bird */
+#define LIBSTDCXX_PROFILE_STATIC "-lstdc++"                                         /* bird */
+#endif                                                                              /* bird */
 
 void
 lang_specific_driver (int *in_argc, const char *const **in_argv,
@@ -99,6 +105,9 @@
   /* True if we should add -shared-libgcc to the command-line.  */
   int shared_libgcc = 1;
 
+  /* True if we saw the '-static' option on the commandline. */                     /* bird */
+  int saw_static = 0;                                                               /* bird */
+                                                                                    /* bird */
   /* The total number of arguments with the new stuff.  */
   int argc;
 
@@ -200,9 +209,13 @@
 		 cause a warning.  */
 	      library = -1;
 	    }
-	  else if (strcmp (argv[i], "-static-libgcc") == 0
-		   || strcmp (argv[i], "-static") == 0)
+	  else if (strcmp (argv[i], "-static-libgcc") == 0)                             /* bird */
 	    shared_libgcc = 0;
+          else if (strcmp (argv[i], "-static") == 0)                                /* bird */
+            {                                                                       /* bird */
+              saw_static = 1;                                                       /* bird */
+              shared_libgcc = 0;                                                    /* bird */
+            }                                                                       /* bird */
 	  else if (DEFAULT_WORD_SWITCH_TAKES_ARG (&argv[i][1]))
 	    i++;
 	  else
Only in gcc-4.4.4/gcc/cp: g++spec.c.orig
Only in gcc-4.4.4/gcc/cp: g++spec.c.rej
diff -ur gcc-4.4.4-o/gcc/cp/mangle.c gcc-4.4.4/gcc/cp/mangle.c
--- gcc-4.4.4-o/gcc/cp/mangle.c	2009-12-23 00:13:54.000000000 +0945
+++ gcc-4.4.4/gcc/cp/mangle.c	2010-07-03 14:10:56.000000000 +0845
@@ -78,6 +78,11 @@
 # define MANGLE_TRACE_TREE(FN, NODE)
 #endif
 
+/* Provide a dummy target-specific name mangling hook */
+#ifndef TARGET_CXX_SET_DECL_ASSEMBLER_NAME
+#define TARGET_CXX_SET_DECL_ASSEMBLER_NAME(decl) 0
+#endif
+
 /* Nonzero if NODE is a class template-id.  We can't rely on
    CLASSTYPE_USE_TEMPLATE here because of tricky bugs in the parser
    that hard to distinguish A<T> from A, where A<T> is the type as
@@ -2796,9 +2801,13 @@
 void
 mangle_decl (const tree decl)
 {
-  tree id = mangle_decl_string (decl);
-  id = targetm.mangle_decl_assembler_name (decl, id);
-  SET_DECL_ASSEMBLER_NAME (decl, id);
+  /* GCC-OS2: mangling hack - fixes _System */
+  tree id;
+  if (!TARGET_CXX_SET_DECL_ASSEMBLER_NAME (decl)) {
+     id = mangle_decl_string (decl);
+     id = targetm.mangle_decl_assembler_name (decl, id);
+     SET_DECL_ASSEMBLER_NAME (decl, id);
+  }
 }
 
 /* Generate the mangled representation of TYPE.  */
Only in gcc-4.4.4/gcc/cp: mangle.c.orig
Only in gcc-4.4.4/gcc/cp: mangle.c.rej
diff -ur gcc-4.4.4-o/gcc/cppdefault.c gcc-4.4.4/gcc/cppdefault.c
--- gcc-4.4.4-o/gcc/cppdefault.c	2007-07-26 17:22:00.000000000 +0845
+++ gcc-4.4.4/gcc/cppdefault.c	2010-07-03 11:03:46.000000000 +0845
@@ -41,6 +41,8 @@
 # undef CROSS_INCLUDE_DIR
 #endif
 
+/* GCC-OS2: Added a few more configuration options so we can automagically
+   rewrite /gcc/ to whereever we're installed for all of the dirs we use. */
 const struct default_include cpp_include_defaults[]
 #ifdef INCLUDE_DEFAULTS
 = INCLUDE_DEFAULTS;
@@ -60,10 +62,10 @@
 #endif
 #ifdef LOCAL_INCLUDE_DIR
     /* /usr/local/include comes before the fixincluded header files.  */
-    { LOCAL_INCLUDE_DIR, 0, 0, 1, 1, 0 },
+    { LOCAL_INCLUDE_DIR, LOCAL_INCLUDE_COMPONENT, 0, 1, 1, 0 },
 #endif
 #ifdef PREFIX_INCLUDE_DIR
-    { PREFIX_INCLUDE_DIR, 0, 0, 1, 0, 0 },
+    { PREFIX_INCLUDE_DIR, PREFIX_INCLUDE_COMPONENT, 0, 1, 0, 0 },
 #endif
 #ifdef GCC_INCLUDE_DIR
     /* This is the dir for gcc's private headers.  */
@@ -91,7 +93,7 @@
 #endif
 #ifdef SYSTEM_INCLUDE_DIR
     /* Some systems have an extra dir of include files.  */
-    { SYSTEM_INCLUDE_DIR, 0, 0, 0, 1, 0 },
+    { SYSTEM_INCLUDE_DIR, SYSTEM_INCLUDE_COMPONENT, 0, 0, 1, 0 },
 #endif
 #ifdef STANDARD_INCLUDE_DIR
     /* /usr/include comes dead last.  */
diff -ur gcc-4.4.4-o/gcc/cppdefault.h gcc-4.4.4/gcc/cppdefault.h
--- gcc-4.4.4-o/gcc/cppdefault.h	2007-07-26 17:22:00.000000000 +0845
+++ gcc-4.4.4/gcc/cppdefault.h	2010-07-03 11:03:46.000000000 +0845
@@ -67,4 +67,26 @@
 /* Return true if the toolchain is relocated.  */
 bool cpp_relocated (void);
 
+/* GCC-OS2: Additional configuration options. */
+#ifndef STANDARD_INCLUDE_SYSROOT
+#define STANDARD_INCLUDE_SYSROOT 1
+#endif 
+       
+#ifndef SYSTEM_INCLUDE_COMPONENT
+#define SYSTEM_INCLUDE_COMPONENT 0
+#endif 
+
+#ifndef SYSTEM_INCLUDE_SYSROOT
+#define SYSTEM_INCLUDE_SYSROOT 1
+#endif 
+
+#ifndef LOCAL_INCLUDE_COMPONENT
+#define LOCAL_INCLUDE_COMPONENT 0
+#endif 
+
+#ifndef PREFIX_INCLUDE_COMPONENT
+#define PREFIX_INCLUDE_COMPONENT 0
+#endif 
+/* GCC-OS2: end */
+
 #endif /* ! GCC_CPPDEFAULT_H */
diff -ur gcc-4.4.4-o/gcc/dbxout.c gcc-4.4.4/gcc/dbxout.c
--- gcc-4.4.4-o/gcc/dbxout.c	2009-10-19 21:00:26.000000000 +0845
+++ gcc-4.4.4/gcc/dbxout.c	2010-07-03 11:03:46.000000000 +0845
@@ -1342,7 +1342,14 @@
 static void
 dbxout_global_decl (tree decl)
 {
-  if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
+  if (TREE_CODE (decl) == VAR_DECL 
+#ifdef EMXx /* bird: debug info for all referenced global vars. problem with 4.3.2*/
+      && (   !DECL_EXTERNAL (decl)
+          || (   use_gnu_debug_info_extensions
+              && TREE_SYMBOL_REFERENCED (DECL_NAME (decl))))
+#else
+      && ! DECL_EXTERNAL (decl))
+#endif
     {
       int saved_tree_used = TREE_USED (decl);
       TREE_USED (decl) = 1;
@@ -2153,6 +2160,13 @@
       /* 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.  */
+#ifdef EMX
+      /* bird: I believe this test is wrong. The test above checks if we
+         already used gnu extenstions and gathers that it's ok to continue
+         do non-standard stuff then.
+         Anyway, we can't cope with crossreferences to enums. */
+     if (!use_gnu_debug_info_extensions)
+#endif
       if ((TYPE_NAME (type) != 0
 	   && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
 		 && DECL_IGNORED_P (TYPE_NAME (type)))
@@ -2775,10 +2789,19 @@
 
     case RESULT_DECL:
     case VAR_DECL:
+#ifdef EMX
+      /* Don't mention a variable that is external and unreferenced..
+	 bird: Referenced variables must be mentioned for OMF support.  */
+      if (DECL_EXTERNAL (decl)
+          && (   !use_gnu_debug_info_extensions
+              || !TREE_SYMBOL_REFERENCED (DECL_NAME (decl))))
+        break;
+#else
       /* Don't mention a variable that is external.
 	 Let the file that defines it describe it.  */
       if (DECL_EXTERNAL (decl))
 	break;
+#endif
 
       /* If the variable is really a constant
 	 and not written in memory, inform the debugger.
@@ -3054,6 +3077,35 @@
 	  addr = 0;
 	  number = offs;
 	  code = N_GSYM;
+#ifdef EMX 
+          /* bird: Two hacks.
+             1) Get right address for globals. We're using the value field of
+                the entry for this. This makes the following code work:
+                class foo { foo() {static const char *psz= "foo";} };
+             2) Hack 1 doesn't work for external or communal data. They would
+                both require a fixup of the stabs value to work - which a.out
+                naturally doesn't support (ELF does though).
+                So, what we'll do is to make an extra entry before the 'G'
+                entry which tells us the symbol name.
+                In this case the value of the 'G' entry is -12357.  */
+          if (use_gnu_debug_info_extensions)
+            {
+              addr = XEXP (home, 0);
+              if (DECL_EXTERNAL (decl) || DECL_COMMON (decl))
+                {
+                  fprintf (asm_out_file, "\t.stabs\t\"");
+                  output_addr_const (asm_out_file, addr);
+#if 0
+                  fprintf (asm_out_file, "\",%d,0,0,0\n", /*N_EXT | N_UNDF*/1);
+#else
+                  fprintf (asm_out_file, "\",%d,0,0,0\n", /*extension*/ 0xfe);
+#endif
+                  addr = 0;
+                  number = -12357;
+                }
+            }
+#endif
+
 	}
     }
   else if (GET_CODE (home) == CONCAT)
Only in gcc-4.4.4/gcc: dbxout.c.orig
Only in gcc-4.4.4/gcc: except.c.orig
diff -ur gcc-4.4.4-o/gcc/explow.c gcc-4.4.4/gcc/explow.c
--- gcc-4.4.4-o/gcc/explow.c	2009-02-21 01:05:38.000000000 +0945
+++ gcc-4.4.4/gcc/explow.c	2010-07-04 08:12:32.000000000 +0845
@@ -1346,6 +1346,7 @@
 					         plus_constant (size, first)));
 
       addr = convert_memory_address (ptr_mode, addr);
+
       emit_library_call (stack_check_libfunc, LCT_NORMAL, VOIDmode, 1, addr,
 			 ptr_mode);
     }
Only in gcc-4.4.4/gcc: explow.c.orig
Only in gcc-4.4.4/gcc: expr.c.orig
diff -ur gcc-4.4.4-o/gcc/fix-header.c gcc-4.4.4/gcc/fix-header.c
--- gcc-4.4.4-o/gcc/fix-header.c	2009-02-21 01:05:38.000000000 +0945
+++ gcc-4.4.4/gcc/fix-header.c	2010-07-03 11:03:46.000000000 +0845
@@ -1086,6 +1086,10 @@
   long int inf_size;
   struct symbol_list *cur_symbols;
 
+#if defined (__EMX__)
+  return 0;	// fix-header does only harm to emx` includes
+#endif
+
   progname = "fix-header";
   if (argv[0] && argv[0][0])
     {
Only in gcc-4.4.4/gcc: fix-header.c.orig
Only in gcc-4.4.4/gcc: fortran
diff -ur gcc-4.4.4-o/gcc/function.c gcc-4.4.4/gcc/function.c
--- gcc-4.4.4-o/gcc/function.c	2009-11-14 05:42:50.000000000 +0945
+++ gcc-4.4.4/gcc/function.c	2010-07-04 08:12:58.000000000 +0845
@@ -4256,6 +4256,7 @@
      || (!defined(HAS_INIT_SECTION)			\
 	 && !defined(INIT_SECTION_ASM_OP)		\
 	 && !defined(INIT_ARRAY_SECTION_ASM_OP)))
+
   emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
 #endif
 }
Only in gcc-4.4.4/gcc: function.c.orig
diff -ur gcc-4.4.4-o/gcc/gcc.c gcc-4.4.4/gcc/gcc.c
--- gcc-4.4.4-o/gcc/gcc.c	2010-01-09 09:50:06.000000000 +0945
+++ gcc-4.4.4/gcc/gcc.c	2010-07-03 11:03:46.000000000 +0845
@@ -362,7 +362,7 @@
 static void init_gcc_specs (struct obstack *, const char *, const char *,
 			    const char *);
 #endif
-#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
+#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX) && !defined (NO_FORCE_EXEOBJ_SUFFIX)
 static const char *convert_filename (const char *, int, int);
 #endif
 
@@ -1186,6 +1186,9 @@
    {"--warn-", "-W", "*j"},
    {"--write-dependencies", "-MD", 0},
    {"--write-user-dependencies", "-MMD", 0},
+#ifdef CLH
+   {"--help", "-h", "oj"},
+#endif
    {"--", "-f", "*j"}
  };
 
@@ -1948,8 +1951,11 @@
 static int signal_count;
 
 /* Name with which this program was invoked.  */
-
+#ifdef CLH
+const char *programname;
+#else
 static const char *programname;
+#endif
 
 /* Allocate the argument vector.  */
 
@@ -2884,7 +2890,7 @@
   for (n_commands = 1, i = 0; i < argbuf_index; i++)
     if (strcmp (argbuf[i], "|") == 0)
       {				/* each command.  */
-#if defined (__MSDOS__) || defined (OS2) || defined (VMS)
+#if defined (__MSDOS__) || defined (VMS)
 	fatal ("-pipe not supported");
 #endif
 	argbuf[i] = 0;	/* termination of command args.  */
@@ -3162,7 +3168,7 @@
 
 const char **outfiles;
 
-#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
+#if (defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)) && !defined (NO_FORCE_EXEOBJ_SUFFIX)
 
 /* Convert NAME to a new name if it is the standard suffix.  DO_EXE
    is true if we should look for an executable suffix.  DO_OBJ
@@ -3572,6 +3578,7 @@
 	}
     }
 
+#ifndef __EMX__ /* Under OS/2 (__EMX__) LPATH is used in LANManager client & server */
   /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
   GET_ENVIRONMENT (temp, "LPATH");
   if (temp && *cross_compile == '0')
@@ -3604,6 +3611,7 @@
 	    endp++;
 	}
     }
+#endif /* not __EMX__ */
 
   /* Convert new-style -- options to old-style.  */
   translate_options (&argc, (const char *const **) &argv);
@@ -3852,6 +3860,14 @@
 	  verbose_only_flag++;
 	  verbose_flag++;
 	}
+#ifdef CLH
+      else if (! strncmp (argv[i], "-h", 2))
+	{
+	  extern int clh_display (const char *text, const char *selector);
+          extern char *gcc_clh_text;
+          exit (clh_display (gcc_clh_text, &argv[i][2]));
+        }
+#endif /* CLH */
       else if (argv[i][0] == '-' && argv[i][1] != 0)
 	{
 	  const char *p = &argv[i][1];
@@ -3930,6 +3946,7 @@
 
 	    case 'o':
 	      have_o = 1;
+#ifndef NO_FORCE_EXEOBJ_SUFFIX
 #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
 	      if (! have_c)
 		{
@@ -3965,6 +3982,7 @@
 	      else
 		argv[i] = convert_filename (argv[i], ! have_c, 0);
 #endif
+#endif
 	      goto normal_switch;
 
 	    default:
@@ -4039,14 +4057,12 @@
      configured-in locations.  */
   if (!gcc_exec_prefix)
     {
-#ifndef OS2
       add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
 		  PREFIX_PRIORITY_LAST, 1, 0);
       add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
 		  PREFIX_PRIORITY_LAST, 2, 0);
       add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
 		  PREFIX_PRIORITY_LAST, 2, 0);
-#endif
       add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
 		  PREFIX_PRIORITY_LAST, 1, 0);
     }
@@ -4301,7 +4317,7 @@
 	}
       else
 	{
-#ifdef HAVE_TARGET_OBJECT_SUFFIX
+#if defined (HAVE_TARGET_OBJECT_SUFFIX) && !defined (NO_FORCE_EXEOBJ_SUFFIX)
 	  argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK));
 #endif
 
@@ -6649,7 +6665,11 @@
     }
 
   if (n_infiles == added_libraries)
+#ifdef CLH
+    fatal ("no input files, try \"%s --help\"", programname);
+#else
     fatal ("no input files");
+#endif
 
   /* Make a place to record the compiler output file names
      that correspond to the input files.  */
@@ -6821,6 +6841,7 @@
      with %b in LINK_SPEC. We use the first input file that we can find
      a compiler to compile it instead of using infiles.language since for
      languages other than C we use aliases that we then lookup later.  */
+#ifndef __EMX__ /* This code fails on OS/2 - revert to the GCC 3.4.6 code */
   if (n_infiles > 0)
     {
       int i;
@@ -6832,6 +6853,10 @@
 	    break;
 	  }
     }
+#else
+  if (n_infiles > 0)
+    set_input (infiles[0].name);
+#endif
 
   if (error_count == 0)
     {
Only in gcc-4.4.4/gcc: gcc.c.orig
diff -ur gcc-4.4.4-o/gcc/genattrtab.c gcc-4.4.4/gcc/genattrtab.c
--- gcc-4.4.4-o/gcc/genattrtab.c	2008-07-09 15:30:20.000000000 +0845
+++ gcc-4.4.4/gcc/genattrtab.c	2010-07-03 11:03:48.000000000 +0845
@@ -4443,6 +4443,11 @@
   rtx tem;
   int i;
 
+#ifdef EMX
+  /* Otherwise we can't use more than 32Mb memory and genattrtab uses a lot */
+  _uflags (_UF_SBRK_MODEL, _UF_SBRK_ARBITRARY);
+#endif
+
   progname = "genattrtab";
 
   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
Only in gcc-4.4.4/gcc: genattrtab.c.orig
diff -ur gcc-4.4.4-o/gcc/gengtype.c gcc-4.4.4/gcc/gengtype.c
--- gcc-4.4.4-o/gcc/gengtype.c	2008-08-07 00:55:22.000000000 +0845
+++ gcc-4.4.4/gcc/gengtype.c	2010-07-03 11:03:48.000000000 +0845
@@ -328,7 +328,11 @@
       /* No space for a lang_bitmap is necessary.  Discard the '['. */
       c = getc (list);
       line = here;
+#ifndef __EMX__
       while (c != ']' && c != '\n' && c != EOF)
+#else
+      while (c != ']' && c != '\n' && c != EOF && c != '\r')
+#endif
 	{
 	  *here++ = c;
 	  c = getc (list);
@@ -338,7 +342,11 @@
       if (c == ']')
 	{
 	  c = getc (list);  /* eat what should be a newline */
+#ifndef __EMX__
 	  if (c != '\n' && c != EOF)
+#else
+	  if (c != '\n' && c != EOF && c != '\r' )
+#endif
 	    error_at_line (pos, "junk on line after language tag [%s]", line);
 	}
       else
Only in gcc-4.4.4/gcc: gengtype.c.orig
Only in gcc-4.4.4/gcc: gengtype.c.rej
diff -ur gcc-4.4.4-o/gcc/genmultilib gcc-4.4.4/gcc/genmultilib
--- gcc-4.4.4-o/gcc/genmultilib	2007-07-26 17:22:00.000000000 +0845
+++ gcc-4.4.4/gcc/genmultilib	2010-07-03 11:03:48.000000000 +0845
@@ -40,6 +40,9 @@
 # elements in the second list are separated by spaces.  If the second
 # argument is empty, the option names will be used as the directory
 # names.
+# If number of elements in second argument is bigger than number of options
+# in the first argument, the n+1'th element is used as default directory
+# name (i.e. when no one of options specified in argument 1 was used)
 
 # The optional third argument is a list of options which are
 # identical.  The elements in the list are separated by spaces.  Each
@@ -261,6 +264,12 @@
   fi
 fi
 
+# See if default directory was specified
+if [ -n "$1" ]; then
+  defaultdir="$1"
+else
+  defaultdir="."
+fi
 # We need another recursive shell script to correctly handle positive
 # matches.  If we are invoked as
 #   genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2"
Only in gcc-4.4.4/gcc: gthr-os2.h
diff -ur gcc-4.4.4-o/gcc/gthr.h gcc-4.4.4/gcc/gthr.h
--- gcc-4.4.4-o/gcc/gthr.h	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/gcc/gthr.h	2010-07-03 11:21:54.000000000 +0845
@@ -137,6 +137,7 @@
      POSIX/Unix95 threads with -D_PTHREADS95
      DCE threads with -D_DCE_THREADS
      Solaris/UI threads with -D_SOLARIS_THREADS
+     OS/2 threads with -D_OS2_THREADS
    
 */
 
@@ -151,6 +152,8 @@
 #include "gthr-dce.h"
 #elif _SOLARIS_THREADS
 #include "gthr-solaris.h"
+#elif _OS2_THREADS 
+#include "gthr-os2.h"
 
 /* Include GTHREAD_FILE if one is defined.  */
 #elif defined(HAVE_GTHR_DEFAULT)
Only in gcc-4.4.4/gcc: gthr.h.orig
Only in gcc-4.4.4/gcc: gthr.h.rej
Only in gcc-4.4.4/gcc: include-fixed
diff -ur gcc-4.4.4-o/gcc/incpath.c gcc-4.4.4/gcc/incpath.c
--- gcc-4.4.4-o/gcc/incpath.c	2009-02-21 01:05:38.000000000 +0945
+++ gcc-4.4.4/gcc/incpath.c	2010-07-03 11:11:34.000000000 +0845
@@ -37,7 +37,11 @@
 # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
 # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
 #elif !defined (HOST_LACKS_INODE_NUMBERS)
-# define INO_T_EQ(A, B) ((A) == (B))
+# if defined __EMX__
+#  define INO_T_EQ(A, B) 0
+# else
+#  define INO_T_EQ(A, B) ((A) == (B))
+# endif
 # define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
 #endif
 
diff -ur gcc-4.4.4-o/gcc/langhooks.c gcc-4.4.4/gcc/langhooks.c
--- gcc-4.4.4-o/gcc/langhooks.c	2009-02-21 01:05:38.000000000 +0945
+++ gcc-4.4.4/gcc/langhooks.c	2010-07-03 11:03:48.000000000 +0845
@@ -38,6 +38,12 @@
 #include "ggc.h"
 #include "diagnostic.h"
 
+/* Provide a dummy target-specific name mangling hook */
+#ifndef TARGET_C_SET_DECL_ASSEMBLER_NAME
+#define TARGET_C_SET_DECL_ASSEMBLER_NAME(decl) 0
+#endif
+
+
 /* Do nothing; in many cases the default hook.  */
 
 void
@@ -159,6 +165,9 @@
 		      || DECL_EXTERNAL (decl)
 		      || TREE_PUBLIC (decl))));
   
+     /* GCCOS2: Some targets may want to apply special mangling
+        depending on certain attributes etc (e.g. stdcall). */
+     if (!TARGET_C_SET_DECL_ASSEMBLER_NAME (decl)) {
   /* By default, assume the name to use in assembly code is the same
      as that used in the source language.  (That's correct for C, and
      GCC used to set DECL_ASSEMBLER_NAME to the same value as
@@ -182,7 +191,7 @@
       id = get_identifier (label);
     }
   SET_DECL_ASSEMBLER_NAME (decl, id);
-
+ } /* os2 */
 }
 
 /* Type promotion for variable arguments.  */
diff -ur gcc-4.4.4-o/gcc/libgcc2.c gcc-4.4.4/gcc/libgcc2.c
--- gcc-4.4.4-o/gcc/libgcc2.c	2009-09-25 03:45:44.000000000 +0845
+++ gcc-4.4.4/gcc/libgcc2.c	2010-07-03 11:03:48.000000000 +0845
@@ -2139,7 +2139,7 @@
       (*(p-1)) ();
     }
 #endif
-#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
+#if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION) && !defined (DONT_AUTOREGISTER_FRAME_INFO)
   {
     static int completed = 0;
     if (! completed)
@@ -2158,7 +2158,7 @@
 void
 __do_global_ctors (void)
 {
-#ifdef EH_FRAME_SECTION_NAME
+#if defined (EH_FRAME_SECTION_NAME) && !defined (DONT_AUTOREGISTER_FRAME_INFO)
   {
     static struct object object;
     __register_frame_info (__EH_FRAME_BEGIN__, &object);
Only in gcc-4.4.4/gcc: libgcc2.c.orig
diff -ur gcc-4.4.4-o/gcc/Makefile.in gcc-4.4.4/gcc/Makefile.in
--- gcc-4.4.4-o/gcc/Makefile.in	2010-03-08 21:31:28.000000000 +0945
+++ gcc-4.4.4/gcc/Makefile.in	2010-07-03 11:03:48.000000000 +0845
@@ -206,6 +206,9 @@
 # -------------------------------------------
 
 SHELL = @SHELL@
+# "mkdir cp; cp something cp" doesn't work ash on OS/2.
+CP = cp@host_exeext@
+
 # pwd command to use.  Allow user to override default by setting PWDCMD in
 # the environment to account for automounters.  The make variable must not
 # be called PWDCMD, otherwise the value set here is passed to make
@@ -933,6 +936,16 @@
 	    build/min-insn-modes.o build/gensupport.o build/print-rtl.o
 BUILD_ERRORS = build/errors.o
 
+# GCC-OS2: help
+# This gets linked into gcc if command-line help was enabled
+#CLH_LIBS = @gcc_clh_libs@
+# These definitions enables --help for gcc
+#CLH_CFLAGS = @gcc_clh_cflags@
+#CLH_GCC = @gcc_clh_gcc@
+#CLH_CPP = @gcc_clh_cpp@
+#CLH_G77 = @gcc_clh_g77@
+#CLH_GCJ = @gcc_clh_gcj@
+
 # Specify the directories to be searched for header files.
 # Both . and srcdir are used, in that order,
 # so that *config.h will be found in the compilation
@@ -1637,7 +1650,7 @@
 # compile libgcc2.a.
 # Also create gcc-cross, so that install-common will install properly.
 gcc-cross$(exeext): xgcc$(exeext)
-	cp xgcc$(exeext) gcc-cross$(exeext)
+	$(CP) xgcc$(exeext) gcc-cross$(exeext)
 
 dummy-checksum.o : dummy-checksum.c
 
@@ -1654,6 +1667,16 @@
 	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) cc1-checksum.o \
 	  $(BACKEND) $(LIBS) $(BACKENDLIBS)
 
+# GCC-OS2: help.
+clh.o: clh.c $(CONFIG_H)
+	$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $(srcdir)/clh.c
+
+clh_gcc.c: $(srcdir)/doc/invoke.texi $(srcdir)/mkoptdesc.sh
+	$(srcdir)/mkoptdesc.sh $(srcdir)/doc/invoke.texi gcc > clh_gcc.c
+
+clh_cpp.c: $(srcdir)/doc/invoke.texi $(srcdir)/mkoptdesc.sh
+	$(srcdir)/mkoptdesc.sh $(srcdir)/doc/invoke.texi cpp > clh_cpp.c
+
 #
 # Build libgcc.a.
 
@@ -3522,7 +3545,7 @@
 
 test-protoize-simple: ./protoize ./unprotoize $(GCC_PASSES)
 	-rm -f tmp-proto.[cso]
-	cp $(srcdir)/protoize.c tmp-proto.c
+	$(CP) $(srcdir)/protoize.c tmp-proto.c
 	chmod u+w tmp-proto.c
 	./protoize -N -B ./ -x getopt.h -c "-B./ -Wall -Wwrite-strings \
 	  $(GCC_CFLAGS) $(INCLUDES) \
@@ -3595,12 +3618,12 @@
 	    realfile=`echo $$file | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
 	    $(STAMP) include/$$realfile; \
 	    rm -f include/$$realfile; \
-	    cp $$file include; \
+	    $(CP) $$file include; \
 	    chmod a+r include/$$realfile; \
 	  fi; \
 	done
 	rm -f include/unwind.h
-	cp $(UNWIND_H) include/unwind.h
+	$(CP) $(UNWIND_H) include/unwind.h
 	set -e; for ml in `cat fixinc_list`; do \
 	  sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \
 	  multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
@@ -3618,7 +3641,7 @@
 	done
 # Install the README
 	rm -f include-fixed/README
-	cp $(srcdir)/../fixincludes/README-fixinc include-fixed/README
+	$(CP) $(srcdir)/../fixincludes/README-fixinc include-fixed/README
 	chmod a+r include-fixed/README
 	$(STAMP) $@
 
@@ -3707,7 +3730,7 @@
 	    if [ -f $${fix_dir}/limits.h ]; then \
 	      mv $${fix_dir}/limits.h $${fix_dir}/syslimits.h; \
 	    else \
-	      cp $(srcdir)/gsyslimits.h $${fix_dir}/syslimits.h; \
+	      $(CP) $(srcdir)/gsyslimits.h $${fix_dir}/syslimits.h; \
 	    fi; \
 	    chmod a+r $${fix_dir}/syslimits.h; \
 	  done; \
Only in gcc-4.4.4/gcc: Makefile.in.orig
Only in gcc-4.4.4/gcc: Makefile.in.rej
Only in gcc-4.4.4/gcc: opts.c.orig
Only in gcc-4.4.4/gcc: opts.c.rej
diff -ur gcc-4.4.4-o/gcc/prefix.c gcc-4.4.4/gcc/prefix.c
--- gcc-4.4.4-o/gcc/prefix.c	2007-09-04 01:54:20.000000000 +0845
+++ gcc-4.4.4/gcc/prefix.c	2010-07-03 11:03:48.000000000 +0845
@@ -352,5 +352,7 @@
 void
 set_std_prefix (const char *prefix, int len)
 {
+#ifndef __EMX__
   std_prefix = save_string (prefix, len);
+#endif
 }
diff -ur gcc-4.4.4-o/gcc/reg-stack.c gcc-4.4.4/gcc/reg-stack.c
--- gcc-4.4.4-o/gcc/reg-stack.c	2009-05-23 03:44:30.000000000 +0845
+++ gcc-4.4.4/gcc/reg-stack.c	2010-07-03 11:03:48.000000000 +0845
@@ -2612,6 +2612,21 @@
   edge e;
   edge_iterator ei;
 
+  /* GCC-OS2: fp regs passing
+     Figure out the arguments passed in stack registers.  */
+  tree parm = DECL_ARGUMENTS (current_function_decl);
+  int incoming_arg [REG_STACK_SIZE];
+  int i;
+
+  memset (incoming_arg, 0, sizeof (incoming_arg));
+  while (parm)
+    {
+      rtx x = DECL_INCOMING_RTL (parm);
+      if (STACK_REG_P (x))
+	incoming_arg[REGNO (x) - FIRST_STACK_REG] = x;
+      parm = TREE_CHAIN (parm);
+    }
+
   /* Load something into each stack register live at function entry.
      Such live registers can be caused by uninitialized variables or
      functions not returning values on all paths.  In order to keep
@@ -2626,9 +2641,17 @@
       basic_block block = e->dest;
       block_info bi = BLOCK_INFO (block);
       int reg, top = -1;
+      int dead_arguments = 0; /* GCC-OS2: fp regs passing */ 
+
+      /* GCC-OS2: fp regs passing
+         Put the incoming arguments to the stack. */
+      for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
+	if (incoming_arg [i - FIRST_STACK_REG])
+	  bi->stack_in.reg[++top] = i;
 
       for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
-	if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
+	if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg)
+	    && !incoming_arg [reg - FIRST_STACK_REG]) /* GCC-OS2: fp regs passing */
 	  {
 	    rtx init;
 
@@ -2642,6 +2665,42 @@
 	  }
 
       bi->stack_in.top = top;
+
+      /* GCC-OS2: fp regs passing */
+
+      /* Check whether there are any dead arguments that needs
+         to be popped.  */
+      for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
+	if (incoming_arg [i - FIRST_STACK_REG]
+	    && !TEST_HARD_REG_BIT (bi->stack_in.reg_set, i))
+          {
+	    dead_arguments = 1;
+	    break;
+          }
+
+      if (dead_arguments)
+	{
+	  rtx seq;
+	  rtx after;
+	  start_sequence ();
+		  
+	  /* ??? pop_stack needs some point to emit insns after.
+	     Also needed to keep gen_sequence from returning a 
+	     pattern as opposed to a sequence, which would lose
+	     REG_DEAD notes.  */
+	  after = emit_note (NOTE_INSN_DELETED);
+
+	  for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
+	    if (incoming_arg [i - FIRST_STACK_REG]
+		&& !TEST_HARD_REG_BIT (bi->stack_in.reg_set,i))
+	      after = emit_pop_insn (after, &bi->stack_in,
+				     FP_MODE_REG (i, DFmode), EMIT_AFTER);
+
+	  seq = get_insns ();
+	  end_sequence ();
+	  inserted = 1;
+	  insert_insn_on_edge (seq, e);
+	}
     }
 
   return inserted;
Only in gcc-4.4.4/gcc: reg-stack.c.orig
diff -ur gcc-4.4.4-o/gcc/target-def.h gcc-4.4.4/gcc/target-def.h
--- gcc-4.4.4-o/gcc/target-def.h	2009-02-21 01:05:38.000000000 +0945
+++ gcc-4.4.4/gcc/target-def.h	2010-07-03 11:03:48.000000000 +0845
@@ -95,7 +95,9 @@
 #define TARGET_ASM_FUNCTION_PROLOGUE default_function_pro_epilogue
 #define TARGET_ASM_FUNCTION_EPILOGUE default_function_pro_epilogue
 #define TARGET_ASM_FUNCTION_END_PROLOGUE no_asm_to_stream
+#ifndef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE /* GCC-OS2 */
 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE no_asm_to_stream
+#endif                                     /* GCC-OS2 */
 
 #ifndef TARGET_ASM_RELOC_RW_MASK
 #define TARGET_ASM_RELOC_RW_MASK default_reloc_rw_mask
diff -ur gcc-4.4.4-o/gcc/toplev.c gcc-4.4.4/gcc/toplev.c
--- gcc-4.4.4-o/gcc/toplev.c	2010-03-31 11:36:30.000000000 +0845
+++ gcc-4.4.4/gcc/toplev.c	2010-07-03 11:03:48.000000000 +0845
@@ -1572,9 +1572,11 @@
   pp_format_decoder (global_dc->printer) = &default_tree_printer;
 
   /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages.  */
+#ifndef __OS2__ /* On OS/2 we'd rather see the registers to help understand where the crash occured */
 #ifdef SIGSEGV
   signal (SIGSEGV, crash_signal);
 #endif
+#endif
 #ifdef SIGILL
   signal (SIGILL, crash_signal);
 #endif
Only in gcc-4.4.4/gcc: toplev.c.orig
diff -ur gcc-4.4.4-o/gcc/tree.c gcc-4.4.4/gcc/tree.c
--- gcc-4.4.4-o/gcc/tree.c	2010-04-08 20:13:06.000000000 +0845
+++ gcc-4.4.4/gcc/tree.c	2010-07-03 11:03:48.000000000 +0845
@@ -4186,7 +4186,6 @@
 
   return NULL_TREE;
 }
-
 #endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES  */
 
 /* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
@@ -7022,7 +7021,6 @@
      the program) rather than the file name (which imposes extra
      constraints).  */
   sprintf (buf, FILE_FUNCTION_FORMAT, type, p);
-
   return get_identifier (buf);
 }
 
Only in gcc-4.4.4/gcc: tree.c.orig
Only in gcc-4.4.4/gcc: treelang
diff -ur gcc-4.4.4-o/gcc/unwind-compat.c gcc-4.4.4/gcc/unwind-compat.c
--- gcc-4.4.4-o/gcc/unwind-compat.c	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/gcc/unwind-compat.c	2010-07-03 11:03:48.000000000 +0845
@@ -23,7 +23,7 @@
    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#if defined (USE_GAS_SYMVER) && defined (USE_LIBUNWIND_EXCEPTIONS)
+#if defined (USE_GAS_SYMVER) && defined (USE_LIBUNWIND_EXCEPTIONS) 
 #include "tconfig.h"
 #include "tsystem.h"
 #include "unwind.h"
Only in gcc-4.4.4/gcc: unwind-compat.c.orig
diff -ur gcc-4.4.4-o/gcc/unwind-dw2.c gcc-4.4.4/gcc/unwind-dw2.c
--- gcc-4.4.4-o/gcc/unwind-dw2.c	2010-01-20 18:24:18.000000000 +0945
+++ gcc-4.4.4/gcc/unwind-dw2.c	2010-07-03 11:03:48.000000000 +0845
@@ -146,6 +146,7 @@
   return context->flags & EXTENDED_CONTEXT_BIT;
 }
 
+#ifndef __KLIBC__ /* KLIBC already defines these in libc063.dll */
 /* Get the value of register INDEX as saved in CONTEXT.  */
 
 inline _Unwind_Word
@@ -176,6 +177,7 @@
       return * (_Unwind_Word *) ptr;
     }
 }
+#endif
 
 static inline void *
 _Unwind_GetPtr (struct _Unwind_Context *context, int index)
@@ -183,6 +185,7 @@
   return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
 }
 
+#ifndef __KLIBC__ /* KLIBC already defines these in libc063.dll */
 /* Get the value of the CFA as saved in CONTEXT.  */
 
 _Unwind_Word
@@ -219,6 +222,7 @@
       * (_Unwind_Word *) ptr = val;
     }
 }
+#endif
 
 /* Get the pointer to a register INDEX as saved in CONTEXT.  */
 
@@ -266,6 +270,7 @@
   return context->by_value[index];
 }
 
+#ifndef __KLIBC__ /* KLIBC already defines these in libc063.dll */
 /* Retrieve the return address for CONTEXT.  */
 
 inline _Unwind_Ptr
@@ -273,6 +278,7 @@
 {
   return (_Unwind_Ptr) context->ra;
 }
+#endif
 
 /* Retrieve the return address and flag whether that IP is before
    or after first not yet fully executed instruction.  */
@@ -284,6 +290,7 @@
   return (_Unwind_Ptr) context->ra;
 }
 
+#ifndef __KLIBC__ /* KLIBC already defines these in libc063.dll */
 /* Overwrite the return address for CONTEXT with VAL.  */
 
 inline void
@@ -328,7 +335,7 @@
   return (_Unwind_Ptr) context->bases.tbase;
 }
 #endif
-
+#endif /* __KLIBC__ */
 #ifdef MD_UNWIND_SUPPORT
 #include MD_UNWIND_SUPPORT
 #endif
Only in gcc-4.4.4/gcc: unwind-dw2.c.orig
diff -ur gcc-4.4.4-o/gcc/unwind.inc gcc-4.4.4/gcc/unwind.inc
--- gcc-4.4.4-o/gcc/unwind.inc	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/gcc/unwind.inc	2010-07-03 11:03:48.000000000 +0845
@@ -76,6 +76,7 @@
   return code;
 }
 
+#ifndef __KLIBC__ /* KLIBC already defines these in libc063.dll */
 /* Raise an exception, passing along the given exception object.  */
 
 _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
@@ -134,7 +135,7 @@
 
   uw_install_context (&this_context, &cur_context);
 }
-
+#endif
 
 /* Subroutine of _Unwind_ForcedUnwind also invoked from _Unwind_Resume.  */
 
@@ -212,6 +213,7 @@
 }
 
 
+#ifndef __KLIBC__ /* KLIBC already defines these in libc063.dll */
 /* Resume propagation of an existing exception.  This is used after
    e.g. executing cleanup code, and not to implement rethrowing.  */
 
@@ -261,7 +263,6 @@
   uw_install_context (&this_context, &cur_context);
 }
 
-
 /* A convenience function that calls the exception_cleanup field.  */
 
 void
@@ -270,7 +271,7 @@
   if (exc->exception_cleanup)
     (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
 }
-
+#endif /* __KLIBC__ */
 
 /* Perform stack backtrace through unwind data.  */
 
Only in gcc-4.4.4/gcc: unwind.inc.orig
diff -ur gcc-4.4.4-o/gcc/varasm.c gcc-4.4.4/gcc/varasm.c
--- gcc-4.4.4-o/gcc/varasm.c	2010-01-20 21:12:48.000000000 +0945
+++ gcc-4.4.4/gcc/varasm.c	2010-07-03 11:03:48.000000000 +0845
@@ -1511,7 +1511,6 @@
 default_named_section_asm_out_destructor (rtx symbol, int priority)
 {
   section *sec;
-
   if (priority != DEFAULT_INIT_PRIORITY)
     sec = get_cdtor_priority_section (priority, 
 				      /*constructor_p=*/false);
@@ -2445,6 +2444,20 @@
 	name = IDENTIFIER_POINTER (id);
       gcc_assert (! TREE_CHAIN (id));
     }
+#if 0
+  /* Some code assume that this is the identifier returned 
+     by DECL_ASSEMBLER_NAME (). However, for GCC-OS2 it's not
+     since the calling conventions _Optlink, __stdcall, and
+     _System name encodings are included in the identifier
+     returned by DECL_ASSEMBLER_NAME ().
+     Therefore we need this extra little cludge here. */
+  if (name != real_name)
+    {
+      id = maybe_get_identifier (name);
+      if (id)
+	mark_referenced (id);
+   }
+#endif
 
   assemble_name_raw (file, name);
 }
Only in gcc-4.4.4/gcc: varasm.c.orig
Only in gcc-4.4.4: gnattools
Only in gcc-4.4.4: host-i386-pc-os2-emx
Only in gcc-4.4.4: i386-pc-os2-emx
diff -ur gcc-4.4.4-o/include/filenames.h gcc-4.4.4/include/filenames.h
--- gcc-4.4.4-o/include/filenames.h	2008-03-22 09:20:06.000000000 +0945
+++ gcc-4.4.4/include/filenames.h	2010-07-03 11:03:48.000000000 +0845
@@ -30,7 +30,7 @@
 extern "C" {
 #endif
 
-#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
+#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) || defined(__EMX__)
 
 #ifndef HAVE_DOS_BASED_FILE_SYSTEM
 #define HAVE_DOS_BASED_FILE_SYSTEM 1
Only in gcc-4.4.4/include: filenames.h.orig
Only in gcc-4.4.4: libada
Only in gcc-4.4.4/libgcc/config/i386: t-emx
diff -ur gcc-4.4.4-o/libgcc/config.host gcc-4.4.4/libgcc/config.host
--- gcc-4.4.4-o/libgcc/config.host	2009-04-17 20:43:40.000000000 +0845
+++ gcc-4.4.4/libgcc/config.host	2010-07-03 11:24:12.000000000 +0845
@@ -339,6 +339,9 @@
 	;;
 x86_64-*-mingw*)
 	;;
+i*86-pc-*emx)		# i?86 running OS/2
+    host_exeext=.exe
+    ;;
 i[34567]86-*-interix3*)
 	;;
 ia64*-*-elf*)
Only in gcc-4.4.4/libgcc: config.host.orig
Only in gcc-4.4.4/libgcc: config.host.rej
Only in gcc-4.4.4/libgcc: configure.orig
Only in gcc-4.4.4/libgcc: configure.rej
Only in gcc-4.4.4: libgfortran
diff -ur gcc-4.4.4-o/libgomp/config/posix/lock.c gcc-4.4.4/libgomp/config/posix/lock.c
--- gcc-4.4.4-o/libgomp/config/posix/lock.c	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/libgomp/config/posix/lock.c	2010-07-03 11:03:48.000000000 +0845
@@ -243,6 +243,7 @@
 void
 gomp_init_nest_lock_25 (omp_nest_lock_25_t *lock)
 {
+#ifndef __EMX__
   pthread_mutexattr_t attr;
 
   pthread_mutexattr_init (&attr);
@@ -250,6 +251,7 @@
   pthread_mutex_init (&lock->lock, &attr);
   lock->count = 0;
   pthread_mutexattr_destroy (&attr);
+#endif
 }
 
 void
Only in gcc-4.4.4/libgomp/config/posix: lock.c.orig
diff -ur gcc-4.4.4-o/libgomp/config/posix/omp-lock.h gcc-4.4.4/libgomp/config/posix/omp-lock.h
--- gcc-4.4.4-o/libgomp/config/posix/omp-lock.h	2008-06-06 21:46:54.000000000 +0845
+++ gcc-4.4.4/libgomp/config/posix/omp-lock.h	2010-07-03 15:12:18.000000000 +0845
@@ -8,11 +8,13 @@
    thread than the one that called pthread_mutex_lock.  */
 
 #include <pthread.h>
+#ifndef __EMX__
 #include <semaphore.h>
+#endif
 
 typedef pthread_mutex_t omp_lock_25_t;
 typedef struct { pthread_mutex_t lock; int count; } omp_nest_lock_25_t;
-#ifdef HAVE_BROKEN_POSIX_SEMAPHORES
+#if defined(HAVE_BROKEN_POSIX_SEMAPHORES) || defined(__EMX__)
 /* If we don't have working semaphores, we'll make all explicit tasks
    tied to the creating thread.  */
 typedef pthread_mutex_t omp_lock_t;
diff -ur gcc-4.4.4-o/libgomp/config/posix/sem.h gcc-4.4.4/libgomp/config/posix/sem.h
--- gcc-4.4.4-o/libgomp/config/posix/sem.h	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/libgomp/config/posix/sem.h	2010-07-03 11:03:48.000000000 +0845
@@ -37,7 +37,11 @@
 # pragma GCC visibility push(default)
 #endif
 
+#ifndef __EMX__
 #include <semaphore.h>
+#else
+#define HAVE_BROKEN_POSIX_SEMAPHORES 1
+#endif 
 
 #ifdef HAVE_ATTRIBUTE_VISIBILITY
 # pragma GCC visibility pop
Only in gcc-4.4.4/libgomp/config/posix: sem.h.orig
diff -ur gcc-4.4.4-o/libiberty/argv.c gcc-4.4.4/libiberty/argv.c
--- gcc-4.4.4-o/libiberty/argv.c	2007-07-24 02:14:16.000000000 +0845
+++ gcc-4.4.4/libiberty/argv.c	2010-07-03 11:03:48.000000000 +0845
@@ -183,6 +183,7 @@
 	    {
 	      input++;
 	    }
+
 	  if ((maxargc == 0) || (argc >= (maxargc - 1)))
 	    {
 	      /* argv needs initialization, or expansion */
@@ -223,10 +224,12 @@
 		      bsquote = 0;
 		      *arg++ = *input;
 		    }
+#ifndef __OS2__ /* skip this due to use of backslash in drive paths */
 		  else if (*input == '\\')
 		    {
 		      bsquote = 1;
 		    }
+#endif
 		  else if (squote)
 		    {
 		      if (*input == '\'')
@@ -474,7 +477,6 @@
   "arg 'Jack said \\'hi\\'' has single quotes",
   "arg 'Jack said \\\"hi\\\"' has double quotes",
   "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9",
-  
   /* This should be expanded into only one argument.  */
   "trailing-whitespace ",
 
diff -ur gcc-4.4.4-o/libiberty/basename.c gcc-4.4.4/libiberty/basename.c
--- gcc-4.4.4-o/libiberty/basename.c	2005-04-16 09:25:08.000000000 +0845
+++ gcc-4.4.4/libiberty/basename.c	2010-07-03 11:03:48.000000000 +0845
@@ -24,7 +24,7 @@
 #endif
 
 #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
-  defined (__OS2__)
+  defined (__OS2__) || defined (__EMX__)
 #define HAVE_DOS_BASED_FILE_SYSTEM
 #ifndef DIR_SEPARATOR_2 
 #define DIR_SEPARATOR_2 '\\'
Only in gcc-4.4.4/libiberty/config: mh-emx
diff -ur gcc-4.4.4-o/libiberty/configure gcc-4.4.4/libiberty/configure
--- gcc-4.4.4-o/libiberty/configure	2009-04-08 23:03:32.000000000 +0845
+++ gcc-4.4.4/libiberty/configure	2010-07-03 11:26:00.000000000 +0845
@@ -2467,13 +2467,13 @@
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
   if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
+    CFLAGS="-g"
   else
     CFLAGS="-g"
   fi
 else
   if test "$GCC" = yes; then
-    CFLAGS="-O2"
+    CFLAGS=""
   else
     CFLAGS=
   fi
@@ -4104,6 +4104,7 @@
 if [ "${shared}" = "yes" ]; then
   case "${host}" in
     *-*-cygwin*)	;;
+    i*86-pc-*emx)	;;
     alpha*-*-linux*)	PICFLAG=-fPIC ;;
     arm*-*-*)		PICFLAG=-fPIC ;;
     hppa*-*-*)		PICFLAG=-fPIC ;;
diff -ur gcc-4.4.4-o/libiberty/configure.ac gcc-4.4.4/libiberty/configure.ac
--- gcc-4.4.4-o/libiberty/configure.ac	2009-04-08 23:03:32.000000000 +0845
+++ gcc-4.4.4/libiberty/configure.ac	2010-07-03 11:26:50.000000000 +0845
@@ -201,6 +201,7 @@
 if [[ "${shared}" = "yes" ]]; then
   case "${host}" in
     *-*-cygwin*)	;;
+    i*86-pc-*emx)	;;
     alpha*-*-linux*)	PICFLAG=-fPIC ;;
     arm*-*-*)		PICFLAG=-fPIC ;;
     hppa*-*-*)		PICFLAG=-fPIC ;;
Only in gcc-4.4.4/libiberty: configure.ac.orig
Only in gcc-4.4.4/libiberty: configure.ac.rej
Only in gcc-4.4.4/libiberty: configure.orig
Only in gcc-4.4.4/libiberty: configure.rej
diff -ur gcc-4.4.4-o/libiberty/getpwd.c gcc-4.4.4/libiberty/getpwd.c
--- gcc-4.4.4-o/libiberty/getpwd.c	2005-05-25 05:33:24.000000000 +0845
+++ gcc-4.4.4/libiberty/getpwd.c	2010-07-03 11:03:48.000000000 +0845
@@ -57,7 +57,7 @@
 #define GUESSPATHLEN 100
 #endif
 
-#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__)))
+#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__)) || defined(__EMX__))
 
 /* Get the working directory.  Use the PWD environment variable if it's
    set correctly, since this is faster and gives more uniform answers
@@ -105,7 +105,7 @@
   return p;
 }
 
-#else	/* VMS || _WIN32 && !__CYGWIN__ */
+#else	/* VMS || _WIN32 && !__CYGWIN__ || __EMX__ */
 
 #ifndef MAXPATHLEN
 #define MAXPATHLEN 255
@@ -125,4 +125,4 @@
   return pwd;
 }
 
-#endif	/* VMS || _WIN32 && !__CYGWIN__ */
+#endif	/* VMS || _WIN32 && !__CYGWIN__ || __EMX__ */
diff -ur gcc-4.4.4-o/libiberty/make-relative-prefix.c gcc-4.4.4/libiberty/make-relative-prefix.c
--- gcc-4.4.4-o/libiberty/make-relative-prefix.c	2008-03-25 02:56:20.000000000 +0945
+++ gcc-4.4.4/libiberty/make-relative-prefix.c	2010-07-03 11:03:48.000000000 +0845
@@ -74,7 +74,7 @@
 #endif
 
 #if defined (_WIN32) || defined (__MSDOS__) \
-    || defined (__DJGPP__) || defined (__OS2__)
+    || defined (__DJGPP__) || defined (__OS2__) || defined (__EMX__)
 #  define HAVE_DOS_BASED_FILE_SYSTEM
 #  define HAVE_HOST_EXECUTABLE_SUFFIX
 #  define HOST_EXECUTABLE_SUFFIX ".exe"
diff -ur gcc-4.4.4-o/libiberty/make-temp-file.c gcc-4.4.4/libiberty/make-temp-file.c
--- gcc-4.4.4-o/libiberty/make-temp-file.c	2009-02-23 04:28:30.000000000 +0945
+++ gcc-4.4.4/libiberty/make-temp-file.c	2010-07-03 11:27:36.000000000 +0845
@@ -132,7 +132,14 @@
       len = strlen (base);
       tmpdir = XNEWVEC (char, len + 2);
       strcpy (tmpdir, base);
+#ifdef __EMX__
+  if (tmpdir[len - 1] == '\\' || tmpdir[len - 1] == '/')
+    tmpdir[--len] = DIR_SEPARATOR;
+  else
+    tmpdir[len] = DIR_SEPARATOR;
+#else
       tmpdir[len] = DIR_SEPARATOR;
+#endif
       tmpdir[len+1] = '\0';
       memoized_tmpdir = tmpdir;
 #else /* defined(_WIN32) && !defined(__CYGWIN__) */
Only in gcc-4.4.4/libiberty: make-temp-file.c.orig
Only in gcc-4.4.4/libiberty: make-temp-file.c.rej
diff -ur gcc-4.4.4-o/libiberty/Makefile.in gcc-4.4.4/libiberty/Makefile.in
--- gcc-4.4.4-o/libiberty/Makefile.in	2008-10-22 22:15:18.000000000 +0845
+++ gcc-4.4.4/libiberty/Makefile.in	2010-07-03 11:03:48.000000000 +0845
@@ -71,7 +71,7 @@
 
 # A configuration can specify extra .o files that should be included,
 # even if they are in libc. (Perhaps the libc version is buggy.)
-EXTRA_OFILES = 
+EXTRA_OFILES =
 
 # Flags to pass to a recursive make.
 FLAGS_TO_PASS = \
diff -ur gcc-4.4.4-o/libiberty/pex-unix.c gcc-4.4.4/libiberty/pex-unix.c
--- gcc-4.4.4-o/libiberty/pex-unix.c	2007-08-24 16:25:34.000000000 +0845
+++ gcc-4.4.4/libiberty/pex-unix.c	2010-07-03 11:03:48.000000000 +0845
@@ -86,7 +86,7 @@
 
 static pid_t pex_wait (struct pex_obj *, pid_t, int *, struct pex_time *);
 
-#ifdef HAVE_WAIT4
+#if defined(HAVE_WAIT4) && !defined(__EMX__)
 
 static pid_t
 pex_wait (struct pex_obj *obj ATTRIBUTE_UNUSED, pid_t pid, int *status,
Only in gcc-4.4.4/libstdc++-v3/config/cpu: mips
Only in gcc-4.4.4/libstdc++-v3/config/os/solaris: solaris2.5
Only in gcc-4.4.4/libstdc++-v3/config/os/solaris: solaris2.6
Only in gcc-4.4.4/libstdc++-v3/config/os: windiss
Only in gcc-4.4.4/libstdc++-v3: configure.orig
Only in gcc-4.4.4/libstdc++-v3: configure.rej
diff -ur gcc-4.4.4-o/libstdc++-v3/include/bits/stringfwd.h gcc-4.4.4/libstdc++-v3/include/bits/stringfwd.h
--- gcc-4.4.4-o/libstdc++-v3/include/bits/stringfwd.h	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/libstdc++-v3/include/bits/stringfwd.h	2010-07-03 11:03:50.000000000 +0845
@@ -59,6 +59,8 @@
   template<> struct char_traits<wchar_t>;
 
   typedef basic_string<wchar_t> wstring;
+#elif defined(__OS2__)
+  typedef basic_string<wchar_t> wstring;
 #endif
 
 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) \
Only in gcc-4.4.4/libstdc++-v3/include/bits: stringfwd.h.orig
diff -ur gcc-4.4.4-o/libstdc++-v3/include/parallel/compatibility.h gcc-4.4.4/libstdc++-v3/include/parallel/compatibility.h
--- gcc-4.4.4-o/libstdc++-v3/include/parallel/compatibility.h	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/libstdc++-v3/include/parallel/compatibility.h	2010-07-03 11:03:50.000000000 +0845
@@ -39,7 +39,7 @@
 #include <sys/atomic.h>
 #endif
 
-#if !defined(_WIN32) || defined (__CYGWIN__)
+#if (!defined(_WIN32) && !defined(__OS2__)) || defined (__CYGWIN__)
 #include <sched.h>
 #endif
 
@@ -341,6 +341,9 @@
   {
 #if defined (_WIN32) && !defined (__CYGWIN__)
     Sleep(0);
+#elif defined (__OS2__)
+    unsigned long _System DosSleep (unsigned long ulInterval);
+    DosSleep(0);
 #else
     sched_yield();
 #endif
Only in gcc-4.4.4/libstdc++-v3/include/parallel: compatibility.h.orig
Only in gcc-4.4.4/libstdc++-v3: libmath
diff -ur gcc-4.4.4-o/libstdc++-v3/libsupc++/typeinfo gcc-4.4.4/libstdc++-v3/libsupc++/typeinfo
--- gcc-4.4.4-o/libstdc++-v3/libsupc++/typeinfo	2009-04-10 08:08:06.000000000 +0845
+++ gcc-4.4.4/libstdc++-v3/libsupc++/typeinfo	2010-07-03 11:03:50.000000000 +0845
@@ -59,7 +59,7 @@
 // indicate whether or not pointer comparison can be used.
 
 #ifndef __GXX_MERGED_TYPEINFO_NAMES
-  #if !__GXX_WEAK__
+  #if !__GXX_WEAK__ || (defined(__OS2__) && defined(__EMX__)) /* bird */
     // If weak symbols are not supported, typeinfo names are not merged.
     #define __GXX_MERGED_TYPEINFO_NAMES 0
   #else
@@ -70,7 +70,7 @@
 
 // By default follow the same rules as for __GXX_MERGED_TYPEINFO_NAMES.
 #ifndef __GXX_TYPEINFO_EQUALITY_INLINE
-  #if !__GXX_WEAK__
+  #if !__GXX_WEAK__ || (defined(__OS2__) && defined(__EMX__)) /* bird */
     #define __GXX_TYPEINFO_EQUALITY_INLINE 0
   #else
     #define __GXX_TYPEINFO_EQUALITY_INLINE 1
Only in gcc-4.4.4/libstdc++-v3/libsupc++: typeinfo.orig
Only in gcc-4.4.4/libstdc++-v3/testsuite/23_containers/list: operators
Only in gcc-4.4.4/libstdc++-v3/testsuite: thread
Only in gcc-4.4.4/libstdc++-v3/testsuite/util/native_type: assoc
Only in gcc-4.4.4/libstdc++-v3/testsuite/util/native_type: priority_queue
Only in gcc-4.4.4/libstdc++-v3/testsuite/util/regression: assoc
Only in gcc-4.4.4/libstdc++-v3/testsuite/util/regression: priority_queue
Only in gcc-4.4.4/libstdc++-v3/testsuite/util/regression/rand/assoc: detail
Only in gcc-4.4.4/libstdc++-v3/testsuite/util/regression/rand: io
Only in gcc-4.4.4/libstdc++-v3/testsuite/util/regression/rand/priority_queue: detail
Only in gcc-4.4.4/libstdc++-v3/testsuite/util: rng
Only in gcc-4.4.4: libtool.gcc
Only in gcc-4.4.4: Makefile
diff -ur gcc-4.4.4-o/Makefile.in gcc-4.4.4/Makefile.in
--- gcc-4.4.4-o/Makefile.in	2009-04-25 12:55:28.000000000 +0845
+++ gcc-4.4.4/Makefile.in	2010-07-03 11:28:14.000000000 +0845
@@ -418,7 +418,7 @@
 
 LIBCFLAGS_FOR_TARGET = $(CFLAGS_FOR_TARGET)
 LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates
-LDFLAGS_FOR_TARGET = 
+LDFLAGS_FOR_TARGET = @LDFLAGS_FOR_BUILD@
 
 # ------------------------------------
 # Miscellaneous targets and flag lists
Only in gcc-4.4.4: Makefile.in.orig
Only in gcc-4.4.4: Makefile.in.rej
Only in gcc-4.4.4: patch.log
Only in gcc-4.4.4: serdep.tmp
diff -ur gcc-4.4.4-o/symlink-tree gcc-4.4.4/symlink-tree
--- gcc-4.4.4-o/symlink-tree	2005-07-14 09:53:12.000000000 +0845
+++ gcc-4.4.4/symlink-tree	2010-07-03 11:03:52.000000000 +0845
@@ -71,7 +71,8 @@
   else
     echo "$f		..linked"
     rm -f $f
-    ln -s ${srcdir}/$f .
+#    ln -s ${srcdir}/$f .
+    cp -p ${srcdir}/$f .
   fi
 done
 
gcc-4.4.4-20100707.diff (82,968 bytes)   

Activities

dmik

2011-05-14 19:24

reporter   ~0001914

Actually, in case of Qt and GCC 4.5.2 the problem is not with _System, it's with __declspec(dllexport). This attribute seems to be ignored for some functions and the corresponding bit in the OMF file for them is not set. As a result, these functions are not exported from the DLL.

(PS. ERRRR. Paul, is it possible to fix the erroneous behaviour of this tracker where you press Add Note, it gives you some stupid message about a security token and your comment gets lost? It's really annoying to type the same text twice especially when it's big...)

psmedley

2011-05-15 13:08

administrator   ~0001915

could you post the full error when using 'add note'?

dmik

2011-05-16 11:35

reporter   ~0001917

Sure. Here it is:

---------------------------------------------------------------------------
APPLICATION ERROR #2800

Invalid form security token. Did you submit the form twice by accident?

Please use the "Back" button in your web browser to return to the previous page. There you can correct whatever problems were identified in this error or select another action. You can also click an option from the menu bar to go directly to a new section.
---------------------------------------------------------------------------

Steps to reproduce:

1. Enter something to the Note field.
2. Wait for some long time (I didn't count, but more than 15 min).
3. Try to press Add Note. You will go to a page with the above text and when you press back, your comment in the Note field is gone.

psmedley

2011-05-17 09:19

administrator   ~0001918

Hopefully the problem with Invalid form security token is fixed now - php.ini session.gc-maxlifetime was set too low.

psmedley

2011-06-26 09:42

administrator   ~0001930

Tried to build qt4 svn... but it fails here... log is at http://smedley.info/build.log

Any ideas?

diver

2011-06-29 14:02

reporter   ~0001931

you have most probably not cmd.exe as shell. for qt as written in the readme (afaik) cmd.exe as shell is needed.

psmedley

2011-07-01 09:11

administrator   ~0001932

OK I can confirm the bug is also present in GCC 4.5.3 - investigating now

psmedley

2011-09-02 03:24

administrator   ~0001964

with respect to Qt, GCC 4.4.x seems OK - 4.4.5 works here also

4.5.x is broken

Haven't tested with lucide yet, but if 4.4.x fails with lucide, then it must be a different bug

psmedley

2011-09-04 00:50

administrator   ~0001967

I assume the lucide error is:
kBuild: Linking lupoppler
weakld: error: Unresolved symbol (UNDEF) '_somParentNumResolve'.
weakld: info: The symbol is referenced by:
    U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupoppler.o
    U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupifield.o
    U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupibutton.o
    U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupitext.o
    U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupichoice.o
Ignoring unresolved externals reported from weak prelinker.
Error! E2028: _somParentNumResolve is an undefined reference
file U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupoppler.o(lupoppler.o): undefined symbol _somParentNumResolve
file U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupifield.o(lupifield.o): undefined symbol _somParentNumResolve
file U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupibutton.o(lupibutton.o): undefined symbol _somParentNumResolve
file U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupitext.o(lupitext.o): undefined symbol _somParentNumResolve
file U:\dev\lucide-svn\trunk\out\os2.x86\release\obj\lupoppler\lupichoice.o(lupichoice.o): undefined symbol _somParentNumResolve
kmk: *** [U:/DEV/lucide-svn/trunk/out/os2.x86/release/obj/lupoppler/lupplr.dll] Error 1
The failing command:
@g++.exe @U:/DEV/lucide-svn/trunk/out/os2.x86/release/obj/lupoppler/lupplr.rsp
kmk: *** [U:/DEV/lucide-svn/trunk/out/os2.x86/release/obj/lupoppler/lupplr.dll] Deleting file `U:/DEV/lucide-svn/trunk/out/os2.x86/release/obj/lupoppler/lupplr.map'
kmk: *** [U:/DEV/lucide-svn/trunk/out/os2.x86/release/obj/lupoppler/lupplr.dll] Deleting file `U:/DEV/lucide-svn/trunk/out/os2.x86/release/obj/lupoppler/lupplr.rsp'

psmedley

2011-09-04 09:35

administrator   ~0001968

Major differences between 4.4.2 and 4.4.4 in relation to handling of _System based on your patches... I've added some attachments showing the differences...

dmik

2011-09-04 12:31

reporter   ~0001969

Yes, this is what I get with Lucide as well. I will check it once more as well as my patches a bit later.

psmedley

2011-09-04 20:57

administrator   ~0001970

Probably not the best patch ever, but I merged in some of the stuff from 4.4.2's emx_handle_vacpp_attribute into 4.4.6's ix86_handle_cconv_attribute for the case where the attribute is _System

http://smedley.info/gcc-4.4.6-os2-20110904.zip

lucide now builds... not nothing else is tested to see if anything else broke

dmik

2011-10-03 19:52

reporter   ~0002013

Indeed, the above GCC fixes the problem. I will investigate the patch in detail when I have more time and get the local GCC build work.

Do the diff files attached at the top of this page contain all my GCC patches? Do they contain anything else? I can't find the originals ATM...

Can you tell if the if this "not the best patch" involved rolling back my changes?

dmik

2011-10-29 10:57

reporter   ~0002028

Could you please commit your changes that giveus GCC 4.4.6 in the above link to github as well? I'd like to have an opportunity to build it as well.

PS. I'm currently building all with this version so we will see if something goes wrong.

psmedley

2011-11-12 08:04

administrator   ~0002039

I believe this one is fixed in latest 4.4.6 - change required was https://github.com/psmedley/GCC4-OS2/commit/a962c9c8effb866342acc12cd924e7360bbb5dd9

Still needs to be committed to the gcc repository at github

dmik

2011-11-16 21:19

reporter   ~0002045

Paul, I don't think this fix is correct. Search for decl_required in gcc/attribs.c and you will find that decl_required may not be set together with type_required/function_type_required (which is a must for _System). More over, with this patch applied, typedefs that use _System are rejected by GCC ('__system__' attribute doesn not apply to types), including function pointer typedefs which is clearly wrong.

It must have worked for Lucide by some accident (triggered some other code path).

dmik

2011-11-17 13:20

reporter   ~0002046

Finally, I found a simple test case that reveals the problem we see in Lucide. Here it is:

int _System syscall_1(int a)
{
    return 0;
}

extern "C" int _System syscall_2(int a)
{
    return 0;
}

typedef void* proc(void*);

extern "C" proc * _System syscall_3(int a)
{
    return 0;
}

extern "C" _System proc * syscall_4(int a)
{
    return 0;
}

If you compile this snippet, you will see that "syscall_3" will get a leading underscore (which is wrong) while "syscall_4" will not. It only happens if "proc" is a function typedef. The only difference between these two declarations is the position of _System. Looks like a GCC bug to me. More over, I think that its position in case of "syscall_3" is more correct (since it applies to the function, not to the return type). GCC should either behave equally in both cases or complain in the latter case...

BTW, I compile this test with your winnt.c-like patches applied (with some minor modifications), but that should not influence the desribed behavior. What these patches do though is they break the old C++ mangling exception that was made for _System in EMX (so that in order to suppress it you have to explicitly add "extern "C"" as seen in the snippet above). However, it's a totally different issue and will be solved within 0000494 (at least now GCC behaves equally for _System, _Optlink and __stdcall in terms of C++ mangling and therefore we can fix all three of them at once).

dmik

2011-11-17 14:23

reporter   ~0002047

BTW, exactly the same problem is present if you use _stdcall instead of _System -- in the "syscall_3"-like case, it gets completely ignored too. Which tells us that the bug is cross-platform and does not originate from our OS/2 patches. (All _stdcall code in GCC is done by GCC developers).

dmik

2011-11-17 23:46

reporter   ~0002048

FUUUUUUUUUUUUUUUUUUUUK. Paul, sorry, but this bug tracker software is a complete piece of CRAP. I wrote a very big and detailed explanation here but it fucked it up with its brainless "invalid security token" nonsense again. I have no power to write it once more, so I will just tell that the functions (emx_handle_vacppp_attribute()/ix86_handle_system_attribute()) that you dropped when going from 4.4.2 to the next version were solving the cross-platform problem we're having now.

Can you please tell me where these functions originated from, why you removed them and how can I get the original path that contains them for further analysis?

I suggest that we move GCC issue tracking to GitHub which is much more reliable than this.

dmik

2011-11-17 23:47

reporter   ~0002049

* "the original path" is "the original patch".

psmedley

2011-11-18 22:32

administrator   ~0002050

Attached is emx.c from gcc 4.4.4 before emx_handle_vacppp_attribute() was removed

dmik

2011-11-21 21:01

reporter   ~0002052

I fixed the problem in https://github.com/psmedley/gcc/commit/b2e253aefce316f974d22fa5000d60da557ed017. This solution is cross-platform (will work also for __stdcall and friends).

Paul, please try to build this repo and check it on your side just to make sure that we may close this defect (it also makes sense to switch to it permanently and drop the GCC4-OS2 one as the former has better git history). In the meanwhile, I'm switching to 0000494.

psmedley

2011-12-03 21:40

administrator   ~0002063

Fixed by Dmitry

Issue History

Date Modified Username Field Change
2011-05-14 17:17 dmik New Issue
2011-05-14 19:24 dmik Note Added: 0001914
2011-05-15 13:05 psmedley Project Subversion for OS/2 & eCS => GCC - GNU C Compiler
2011-05-15 13:08 psmedley Note Added: 0001915
2011-05-16 11:35 dmik Note Added: 0001917
2011-05-17 09:19 psmedley Note Added: 0001918
2011-06-26 09:42 psmedley Note Added: 0001930
2011-06-29 14:02 diver Note Added: 0001931
2011-07-01 09:11 psmedley Note Added: 0001932
2011-09-02 03:24 psmedley Note Added: 0001964
2011-09-04 00:50 psmedley Note Added: 0001967
2011-09-04 09:35 psmedley Note Added: 0001968
2011-09-04 09:36 psmedley File Added: emx.c.442-445
2011-09-04 09:36 psmedley File Added: i386.c.442-445
2011-09-04 12:31 dmik Note Added: 0001969
2011-09-04 20:57 psmedley Note Added: 0001970
2011-10-03 19:52 dmik Note Added: 0002013
2011-10-29 10:57 dmik Note Added: 0002028
2011-11-12 08:04 psmedley Note Added: 0002039
2011-11-12 08:04 psmedley Assigned To => psmedley
2011-11-12 08:04 psmedley Status new => feedback
2011-11-16 21:19 dmik Note Added: 0002045
2011-11-16 21:19 dmik Status feedback => assigned
2011-11-17 13:20 dmik Note Added: 0002046
2011-11-17 14:23 dmik Note Added: 0002047
2011-11-17 23:46 dmik Note Added: 0002048
2011-11-17 23:47 dmik Note Added: 0002049
2011-11-18 22:32 psmedley File Added: emx.c
2011-11-18 22:32 psmedley Note Added: 0002050
2011-11-18 22:34 psmedley File Added: gcc-4.4.4-20100707.diff
2011-11-21 21:01 dmik Note Added: 0002052
2011-12-03 21:40 psmedley Note Added: 0002063
2011-12-03 21:40 psmedley Status assigned => resolved
2011-12-03 21:40 psmedley Resolution open => fixed
2020-08-24 03:14 psmedley Status resolved => closed