Index: osprey/common/com/intrn_entry.def
===================================================================
--- osprey/common/com/intrn_entry.def	(revision 3425)
+++ osprey/common/com/intrn_entry.def	(working copy)
@@ -7670,6 +7670,10 @@
 DEF_INTRN_ENTRY(INTRN_CTYPE_TOLOWER_LOC, "CTYPE_TOLOWER_LOC", NOT_BYVAL, PURE, NO_SIDEEFFECTS, 
                 DOES_RETURN, NOT_ACTUAL, NOT_CGINTRINSIC, NOT_SLAVE, 
                 IRETURN_PPI4, "__ctype_tolower_loc", "CTYPE_TOLOWER_LOC", "__ctype_tolower_loc")
+/* I4OBJSZ */
+DEF_INTRN_ENTRY(INTRN_OBJ_SZ, "BUILTIN_OBJ_SZ", BYVAL, PURE, NO_SIDEEFFECTS, 
+                DOES_RETURN, ACTUAL, NOT_CGINTRINSIC, NOT_SLAVE, 
+                IRETURN_SZT, NULL, NULL, "dummy_name")
 
 /* END of DEF_INTRN_ENTRY */
 
Index: osprey/wgen/wgen_expr.cxx
===================================================================
--- osprey/wgen/wgen_expr.cxx	(revision 3425)
+++ osprey/wgen/wgen_expr.cxx	(working copy)
@@ -5699,6 +5699,65 @@
 #endif // FE_GNU_4_2_0
 #endif // KEY
 
+
+// Following function is a quick kludge to bug# 586 reported in bugs.open64.net.
+// The problem is that open64's backend currently does not fold 
+// __builtin_object_size() into constant, causing "unresolved symbol" problem 
+// at link time.
+//
+// This function is part of GCC extension; gcc tries to fold this function in 
+// may places (see fold_builtin_object_size()@builtins.c for details), and it 
+// has a pass called "objsz" dedicated to that purpose (see tree-object-size.c for 
+// details).
+//
+// fold_builtin_object_size() is called prior to the generic -> gspin conversion;
+// it is able to fold some simple cases; but in general, most cases have to handled
+// by the "objsz" pass which relies on SSA. 
+//
+//   The value the function "__builtin_object_size(void* p, int type)" evaluated to 
+// depends on the capability of compiler data flow analysis. Basically, if compiler
+// reveals that pointer <p> points to object O with type T, it will return sizeof(T);
+// otherwise it returns "type < 2 ? -1 : 0".
+//
+//  This function simply substitute the "__builtin_object_size(p, ty)" with 
+//  "ty < 2 ? -1 : 0".
+//  
+static WN*
+Fold_Object_Size (WN* intrinsic_op) {
+
+    Is_True (WN_operator (intrinsic_op) == OPR_INTRINSIC_OP && 
+             WN_intrinsic (intrinsic_op) ==  INTRN_OBJ_SZ,
+             ("Invalid intrisic op"));
+    
+    // the rtype should be the type corresponing to high level type size_t
+    //
+    TYPE_ID rtype = WN_rtype (intrinsic_op);
+
+    // step 1: Get the 2nd actual of __builtin_object_size()
+    //
+    WN* arg1 = WN_kid0(WN_kid1(intrinsic_op));
+    arg1 = WN_COPY_Tree (arg1);
+    WN_DELETE_Tree (intrinsic_op);
+
+    // step 2: construct expression : "<arg1> < 2 ? -1 : 0"
+    // 
+
+    // step 2.1 create condition "<arg1> < 2".
+    //
+    WN* cond = WN_CreateExp2 (OPC_BI4LT,
+                              WN_Type_Conversion (arg1, MTYPE_I4),
+                              WN_CreateIntconst (OPC_I4INTCONST, 2));
+    
+    // step 2.2 create the selection exp
+    WN* res = WN_CreateExp3 (OPR_SELECT, MTYPE_I4, MTYPE_V, 
+                             cond,
+                             WN_CreateIntconst (OPC_I4INTCONST, -1),
+                             WN_CreateIntconst (OPC_I4INTCONST, 0));
+
+    res = WN_Type_Conversion (res, rtype);
+    return res;
+}
+
 WN * 
 WGEN_Expand_Expr (gs_t exp,
 		  bool need_result,
@@ -9002,6 +9061,11 @@
 		whirl_generated = TRUE;
 	        break;
 	
+	      case GSBI_BUILT_IN_OBJECT_SIZE:
+	        iopc = INTRN_OBJ_SZ;
+	        intrinsic_op = TRUE;
+	        break;
+               
 	      case GSBI_BUILT_IN_POPCOUNT:
 	        iopc = INTRN_I4POPCNT;
 	        intrinsic_op = TRUE;
@@ -9439,6 +9503,12 @@
 				      iopc, num_args, ikids);
             WN_Set_Deref_If_Needed(wn);
 
+        if (iopc == INTRN_OBJ_SZ) {
+            // kludge to the undefined __builtin_object_size() problem (bug #586).  
+            //
+            wn = Fold_Object_Size (wn);
+        }
+
 #ifdef KEY
 	    if (cvt_to != MTYPE_UNKNOWN) // bug 8251
               wn = WN_Cvt (ret_mtype, cvt_to, wn);
