diff options
Diffstat (limited to 'contrib/gcc/objc/archive.c')
| -rw-r--r-- | contrib/gcc/objc/archive.c | 203 | 
1 files changed, 119 insertions, 84 deletions
diff --git a/contrib/gcc/objc/archive.c b/contrib/gcc/objc/archive.c index 0d5515270b41..c762fe6186e5 100644 --- a/contrib/gcc/objc/archive.c +++ b/contrib/gcc/objc/archive.c @@ -1,5 +1,5 @@  /* GNU Objective C Runtime archiving -   Copyright (C) 1993, 1995 Free Software Foundation, Inc. +   Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.     Contributed by Kresten Krab Thorup  This file is part of GNU CC. @@ -24,10 +24,15 @@ Boston, MA 02111-1307, USA.  */     however invalidate any other reasons why the executable file might be     covered by the GNU General Public License.  */ +#include "config.h"  #include "runtime.h"  #include "typedstream.h"  #include "encoding.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +  extern int fflush(FILE*);  #define ROUND(V, A) \ @@ -37,11 +42,6 @@ extern int fflush(FILE*);  #define PTR2LONG(P) (((char*)(P))-(char*)0)  #define LONG2PTR(L) (((char*)0)+(L)) -#define __objc_fatal(format, args...) \ - { fprintf(stderr, "archiving: "); \ -   fprintf(stderr, format, ## args); \ -   fprintf(stderr, "\n"); abort(); } -  /* Declare some functions... */  static int @@ -141,7 +141,8 @@ __objc_code_unsigned_short (unsigned char* buf, unsigned short val)  }  int -objc_write_unsigned_short (struct objc_typed_stream* stream, unsigned short value) +objc_write_unsigned_short (struct objc_typed_stream* stream,  +			   unsigned short value)  {    unsigned char buf[sizeof (unsigned short)+1];    int len = __objc_code_unsigned_short (buf, value); @@ -252,7 +253,8 @@ __objc_code_unsigned_long (unsigned char* buf, unsigned long val)  }  int -objc_write_unsigned_long (struct objc_typed_stream* stream, unsigned long value) +objc_write_unsigned_long (struct objc_typed_stream* stream,  +			  unsigned long value)  {    unsigned char buf[sizeof(unsigned long)+1];    int len = __objc_code_unsigned_long (buf, value); @@ -315,7 +317,8 @@ objc_write_string_atomic (struct objc_typed_stream* stream,  }  static int -objc_write_register_common (struct objc_typed_stream* stream, unsigned long key) +objc_write_register_common (struct objc_typed_stream* stream,  +			    unsigned long key)  {    unsigned char buf[sizeof (unsigned long)+2];    int len = __objc_code_unsigned_long (buf+1, key); @@ -359,7 +362,11 @@ __objc_write_extension (struct objc_typed_stream* stream, unsigned char code)        return (*stream->write)(stream->physical, &buf, 1);      }    else  -    abort(); +    { +      objc_error(nil, OBJC_ERR_BAD_OPCODE, +		 "__objc_write_extension: bad opcode %c\n", code); +      return -1; +    }  }  __inline__ int @@ -392,9 +399,10 @@ objc_write_object_reference (struct objc_typed_stream* stream, id object)  int   objc_write_root_object (struct objc_typed_stream* stream, id object)  { -  int len; +  int len = 0;    if (stream->writing_root_p) -    __objc_fatal ("objc_write_root_object called recursively") +    objc_error (nil, OBJC_ERR_RECURSE_ROOT,  +		"objc_write_root_object called recursively");    else      {        stream->writing_root_p = 1; @@ -426,12 +434,6 @@ objc_write_object (struct objc_typed_stream* stream, id object)      }  } -#ifdef __alpha__ -extern int atoi (const char*); -extern size_t strlen(const char*); -extern size_t strcpy(char*, const char*); -#endif -  __inline__ int  __objc_write_class (struct objc_typed_stream* stream, struct objc_class* class)  { @@ -488,7 +490,8 @@ objc_write_selector (struct objc_typed_stream* stream, SEL selector)    else      {        int length; -      hash_add (&stream->stream_table, LONG2PTR(key=PTR2LONG(sel_name)), (char*)sel_name); +      hash_add (&stream->stream_table,  +		LONG2PTR(key=PTR2LONG(sel_name)), (char*)sel_name);        if ((length = objc_write_register_common (stream, key)))  	return __objc_write_selector (stream, selector);        return length; @@ -520,8 +523,9 @@ objc_read_char (struct objc_typed_stream* stream, char* val)  	}        else -	__objc_fatal("expected 8bit signed int, got %dbit int", -		     (int)(buf&_B_NUMBER)*8); +	objc_error(nil, OBJC_ERR_BAD_DATA, +		   "expected 8bit signed int, got %dbit int", +		   (int)(buf&_B_NUMBER)*8);      }    return len;  } @@ -541,8 +545,9 @@ objc_read_unsigned_char (struct objc_typed_stream* stream, unsigned char* val)  	len = (*stream->read)(stream->physical, val, 1);        else -	__objc_fatal("expected 8bit unsigned int, got %dbit int", -		     (int)(buf&_B_NUMBER)*8); +	objc_error(nil, OBJC_ERR_BAD_DATA, +		   "expected 8bit unsigned int, got %dbit int", +		   (int)(buf&_B_NUMBER)*8);      }    return len;  } @@ -562,7 +567,8 @@ objc_read_short (struct objc_typed_stream* stream, short* value)  	  int pos = 1;  	  int nbytes = buf[0] & _B_NUMBER;  	  if (nbytes > sizeof (short)) -	    __objc_fatal("expected short, got bigger (%dbits)", nbytes*8); +	    objc_error(nil, OBJC_ERR_BAD_DATA, +		       "expected short, got bigger (%dbits)", nbytes*8);  	  len = (*stream->read)(stream->physical, buf+1, nbytes);  	  (*value) = 0;  	  while (pos <= nbytes) @@ -590,7 +596,8 @@ objc_read_unsigned_short (struct objc_typed_stream* stream,  	  int pos = 1;  	  int nbytes = buf[0] & _B_NUMBER;  	  if (nbytes > sizeof (short)) -	    __objc_fatal("expected short, got int or bigger"); +	    objc_error(nil, OBJC_ERR_BAD_DATA, +		       "expected short, got int or bigger");  	  len = (*stream->read)(stream->physical, buf+1, nbytes);  	  (*value) = 0;  	  while (pos <= nbytes) @@ -616,7 +623,7 @@ objc_read_int (struct objc_typed_stream* stream, int* value)  	  int pos = 1;  	  int nbytes = buf[0] & _B_NUMBER;  	  if (nbytes > sizeof (int)) -	    __objc_fatal("expected int, got bigger"); +	    objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger");  	  len = (*stream->read)(stream->physical, buf+1, nbytes);  	  (*value) = 0;  	  while (pos <= nbytes) @@ -643,7 +650,7 @@ objc_read_long (struct objc_typed_stream* stream, long* value)  	  int pos = 1;  	  int nbytes = buf[0] & _B_NUMBER;  	  if (nbytes > sizeof (long)) -	    __objc_fatal("expected long, got bigger"); +	    objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger");  	  len = (*stream->read)(stream->physical, buf+1, nbytes);  	  (*value) = 0;  	  while (pos <= nbytes) @@ -663,7 +670,7 @@ __objc_read_nbyte_uint (struct objc_typed_stream* stream,    unsigned char buf[sizeof(unsigned int)+1];    if (nbytes > sizeof (int)) -    __objc_fatal("expected int, got bigger"); +    objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger");    len = (*stream->read)(stream->physical, buf, nbytes);    (*val) = 0; @@ -699,7 +706,7 @@ __objc_read_nbyte_ulong (struct objc_typed_stream* stream,    unsigned char buf[sizeof(unsigned long)+1];    if (nbytes > sizeof (long)) -    __objc_fatal("expected long, got bigger"); +    objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger");    len = (*stream->read)(stream->physical, buf, nbytes);    (*val) = 0; @@ -747,7 +754,7 @@ objc_read_string (struct objc_typed_stream* stream,        case _B_SSTR:  	{  	  int length = buf[0]&_B_VALUE; -	  (*string) = (char*)__objc_xmalloc(length+1); +	  (*string) = (char*)objc_malloc(length+1);  	  if (key)  	    hash_add (&stream->stream_table, LONG2PTR(key), *string);  	  len = (*stream->read)(stream->physical, *string, length); @@ -760,7 +767,7 @@ objc_read_string (struct objc_typed_stream* stream,  	  char *tmp;  	  len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key);  	  tmp = hash_value_for_key (stream->stream_table, LONG2PTR (key)); -	  *string = __objc_xmalloc (strlen(tmp) + 1); +	  *string = objc_malloc (strlen(tmp) + 1);  	  strcpy (*string, tmp);  	}  	break; @@ -770,7 +777,7 @@ objc_read_string (struct objc_typed_stream* stream,  	  unsigned int nbytes = buf[0]&_B_VALUE;  	  len = __objc_read_nbyte_uint(stream, nbytes, &nbytes);  	  if (len) { -	    (*string) = (char*)__objc_xmalloc(nbytes+1); +	    (*string) = (char*)objc_malloc(nbytes+1);  	    if (key)  	      hash_add (&stream->stream_table, LONG2PTR(key), *string);  	    len = (*stream->read)(stream->physical, *string, nbytes); @@ -780,7 +787,8 @@ objc_read_string (struct objc_typed_stream* stream,  	break;        default: -	__objc_fatal("expected string, got opcode %c\n", (buf[0]&_B_CODE)); +	objc_error(nil, OBJC_ERR_BAD_DATA, +		   "expected string, got opcode %c\n", (buf[0]&_B_CODE));        }      } @@ -825,13 +833,14 @@ objc_read_object (struct objc_typed_stream* stream, id* object)  	  /* check null-byte */  	  len = (*stream->read)(stream->physical, buf, 1);  	  if (buf[0] != '\0') -	    __objc_fatal("expected null-byte, got opcode %c", buf[0]); +	    objc_error(nil, OBJC_ERR_BAD_DATA, +		       "expected null-byte, got opcode %c", buf[0]);  	}        else if ((buf[0]&_B_CODE) == _B_UCOMM)  	{  	  if (key) -	    __objc_fatal("cannot register use upcode..."); +	    objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode...");  	  len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key);  	  (*object) = hash_value_for_key (stream->object_table, LONG2PTR(key));  	} @@ -840,20 +849,24 @@ objc_read_object (struct objc_typed_stream* stream, id* object)  	{  	  struct objc_list* other;  	  len = objc_read_unsigned_long (stream, &key); -	  other = (struct objc_list*)hash_value_for_key (stream->object_refs, LONG2PTR(key)); -	  hash_add (&stream->object_refs, LONG2PTR(key), (void*)list_cons(object, other)); +	  other = (struct objc_list*)hash_value_for_key (stream->object_refs,  +							 LONG2PTR(key)); +	  hash_add (&stream->object_refs, LONG2PTR(key),  +		    (void*)list_cons(object, other));  	}        else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */  	{  	  if (key) -	    __objc_fatal("cannot register root object..."); +	    objc_error(nil, OBJC_ERR_BAD_KEY, +		       "cannot register root object...");  	  len = objc_read_object (stream, object);  	  __objc_finish_read_root_object (stream);  	}        else -	__objc_fatal("expected object, got opcode %c", buf[0]); +	objc_error(nil, OBJC_ERR_BAD_DATA, +		   "expected object, got opcode %c", buf[0]);      }    return len;  } @@ -881,7 +894,7 @@ objc_read_class (struct objc_typed_stream* stream, Class* class)  	  /* get class */  	  len = objc_read_string (stream, &class_name);  	  (*class) = objc_get_class(class_name); -	  free (class_name); +	  objc_free(class_name);  	  /* register */  	  if (key) @@ -894,15 +907,17 @@ objc_read_class (struct objc_typed_stream* stream, Class* class)        else if ((buf[0]&_B_CODE) == _B_UCOMM)  	{  	  if (key) -	    __objc_fatal("cannot register use upcode..."); +	    objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode...");  	  len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key);  	  (*class) = hash_value_for_key (stream->stream_table, LONG2PTR(key));  	  if (!*class) -	    __objc_fatal("cannot find class for key %lu", key); +	    objc_error(nil, OBJC_ERR_BAD_CLASS, +		       "cannot find class for key %lu", key);  	}        else -	__objc_fatal("expected class, got opcode %c", buf[0]); +	objc_error(nil, OBJC_ERR_BAD_DATA, +		   "expected class, got opcode %c", buf[0]);      }    return len;  } @@ -936,7 +951,7 @@ objc_read_selector (struct objc_typed_stream* stream, SEL* selector)  	    }  	  else   	    (*selector) = sel_get_any_uid(selector_name); -	  free (selector_name); +	  objc_free(selector_name);  	  /* register */  	  if (key) @@ -946,13 +961,15 @@ objc_read_selector (struct objc_typed_stream* stream, SEL* selector)        else if ((buf[0]&_B_CODE) == _B_UCOMM)  	{  	  if (key) -	    __objc_fatal("cannot register use upcode..."); +	    objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode...");  	  len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); -	  (*selector) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); +	  (*selector) = hash_value_for_key (stream->stream_table,  +					    LONG2PTR(key));  	}        else -	__objc_fatal("expected selector, got opcode %c", buf[0]); +	objc_error(nil, OBJC_ERR_BAD_DATA, +		   "expected selector, got opcode %c", buf[0]);      }    return len;  } @@ -1019,13 +1036,15 @@ objc_write_type(TypedStream* stream, const char* type, const void* data)      break;    case _C_ATOM: -    return objc_write_string_atomic (stream, *(char**)data, strlen(*(char**)data)); +    return objc_write_string_atomic (stream, *(char**)data,  +				     strlen(*(char**)data));      break;    case _C_ARY_B:      {        int len = atoi(type+1); -      while (isdigit(*++type)); +      while (isdigit(*++type)) +	;        return objc_write_array (stream, type, len, data);      }      break;  @@ -1034,8 +1053,9 @@ objc_write_type(TypedStream* stream, const char* type, const void* data)      {        int acc_size = 0;        int align; -      while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */ -      while (*type != _C_STRUCT_E); +      while (*type != _C_STRUCT_E && *type++ != '=') +	; /* skip "<name>=" */ +      while (*type != _C_STRUCT_E)  	{  	  align = objc_alignof_type (type);       /* padd to alignment */  	  acc_size += ROUND (acc_size, align); @@ -1047,8 +1067,11 @@ objc_write_type(TypedStream* stream, const char* type, const void* data)      }    default: -    fprintf(stderr, "objc_write_type: cannot parse typespec: %s\n", type); -    abort(); +    { +      objc_error(nil, OBJC_ERR_BAD_TYPE, +		 "objc_write_type: cannot parse typespec: %s\n", type); +      return 0; +    }    }  } @@ -1116,7 +1139,8 @@ objc_read_type(TypedStream* stream, const char* type, void* data)    case _C_ARY_B:      {        int len = atoi(type+1); -      while (isdigit(*++type)); +      while (isdigit(*++type)) +	;        return objc_read_array (stream, type, len, data);      }      break;  @@ -1125,8 +1149,9 @@ objc_read_type(TypedStream* stream, const char* type, void* data)      {        int acc_size = 0;        int align; -      while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */ -      while (*type != _C_STRUCT_E); +      while (*type != _C_STRUCT_E && *type++ != '=') +	; /* skip "<name>=" */ +      while (*type != _C_STRUCT_E)  	{  	  align = objc_alignof_type (type);       /* padd to alignment */  	  acc_size += ROUND (acc_size, align); @@ -1138,8 +1163,11 @@ objc_read_type(TypedStream* stream, const char* type, void* data)      }    default: -    fprintf(stderr, "objc_read_type: cannot parse typespec: %s\n", type); -    abort(); +    { +      objc_error(nil, OBJC_ERR_BAD_TYPE, +		 "objc_read_type: cannot parse typespec: %s\n", type); +      return 0; +    }    }  } @@ -1229,17 +1257,18 @@ objc_write_types (TypedStream* stream, const char* type, ...)  	{  	  int len = atoi(c+1);  	  const char* t = c; -	  while (isdigit(*++t)); +	  while (isdigit(*++t)) +	    ;  	  res = objc_write_array (stream, t, len, va_arg(args, void*));  	  t = objc_skip_typespec (t);  	  if (*t != _C_ARY_E) -	    __objc_fatal("expected `]', got: %s", t); +	    objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t);  	}  	break;         default: -	fprintf(stderr, "objc_write_types: cannot parse typespec: %s\n", type); -	abort(); +	objc_error(nil, OBJC_ERR_BAD_TYPE,  +		   "objc_write_types: cannot parse typespec: %s\n", type);        }      }    va_end(args); @@ -1320,17 +1349,18 @@ objc_read_types(TypedStream* stream, const char* type, ...)  	{  	  int len = atoi(c+1);  	  const char* t = c; -	  while (isdigit(*++t)); +	  while (isdigit(*++t)) +	    ;  	  res = objc_read_array (stream, t, len, va_arg(args, void*));  	  t = objc_skip_typespec (t);  	  if (*t != _C_ARY_E) -	    __objc_fatal("expected `]', got: %s", t); +	    objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t);  	}  	break;         default: -	fprintf(stderr, "objc_read_types: cannot parse typespec: %s\n", type); -	abort(); +	objc_error(nil, OBJC_ERR_BAD_TYPE,  +		   "objc_read_types: cannot parse typespec: %s\n", type);        }      }    va_end(args); @@ -1379,12 +1409,6 @@ objc_read_array (TypedStream* stream, const char* type,    return 1;  } -static void -__objc_free (void* p) -{ -  free (p); -} -  static int   __objc_fread(FILE* file, char* data, int len)  { @@ -1406,13 +1430,15 @@ __objc_feof(FILE* file)  static int   __objc_no_write(FILE* file, char* data, int len)  { -  __objc_fatal ("TypedStream not open for writing"); +  objc_error (nil, OBJC_ERR_NO_WRITE, "TypedStream not open for writing"); +  return 0;  }  static int   __objc_no_read(FILE* file, char* data, int len)  { -  __objc_fatal ("TypedStream not open for reading"); +  objc_error (nil, OBJC_ERR_NO_READ, "TypedStream not open for reading"); +  return 0;  }  static int @@ -1422,10 +1448,12 @@ __objc_read_typed_stream_signature (TypedStream* stream)    int pos = 0;    do      (*stream->read)(stream->physical, buffer+pos, 1); -  while (buffer[pos++] != '\0'); +  while (buffer[pos++] != '\0') +    ;    sscanf (buffer, "GNU TypedStream %d", &stream->version);    if (stream->version != OBJC_TYPED_STREAM_VERSION) -    __objc_fatal ("cannot handle TypedStream version %d", stream->version); +    objc_error (nil, OBJC_ERR_STREAM_VERSION, +		"cannot handle TypedStream version %d", stream->version);    return 1;  } @@ -1450,11 +1478,12 @@ static void __objc_finish_write_root_object(struct objc_typed_stream* stream)  static void __objc_finish_read_root_object(struct objc_typed_stream* stream)  {    node_ptr node; -  struct objc_list* free_list;    SEL awake_sel = sel_get_any_uid ("awake"); +  cache_ptr free_list = hash_new (64, +				  (hash_func_type) hash_ptr, +				  (compare_func_type) compare_ptrs);    /* resolve object forward references */ -  free_list = list_cons(NULL, NULL);    for (node = hash_next (stream->object_refs, NULL); node;         node = hash_next (stream->object_refs, node))      { @@ -1464,13 +1493,19 @@ static void __objc_finish_read_root_object(struct objc_typed_stream* stream)        while(reflist)  	{  	  *((id*)reflist->head) = object; -          if (list_find(&free_list, reflist) == NULL) -	    free_list = list_cons (reflist, free_list); +	  if (hash_value_for_key (free_list,reflist) == NULL) +	    hash_add (&free_list,reflist,reflist); +  	  reflist = reflist->tail;  	}      } -  list_mapcar (free_list, __objc_free); -  list_free (free_list); +     +  /* apply __objc_free to all objects stored in free_list */ +  for (node = hash_next (free_list, NULL); node; +       node = hash_next (free_list, node)) +    objc_free ((void *) node->key); + +  hash_delete (free_list);    /* empty object reference table */    hash_delete (stream->object_refs); @@ -1503,7 +1538,7 @@ static void __objc_finish_read_root_object(struct objc_typed_stream* stream)  TypedStream*   objc_open_typed_stream (FILE* physical, int mode)  { -  TypedStream* s = (TypedStream*)__objc_xmalloc(sizeof(TypedStream)); +  TypedStream* s = (TypedStream*)objc_malloc(sizeof(TypedStream));    s->mode = mode;    s->physical = physical; @@ -1590,7 +1625,7 @@ objc_close_typed_stream (TypedStream* stream)    if (stream->type == (OBJC_MANAGED_STREAM | OBJC_FILE_STREAM))      fclose ((FILE*)stream->physical); -  free (stream); +  objc_free(stream);  }  BOOL  | 
