This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix gcj on ppc*-linux


Hi!

After the recent change which turned on -funit-at-a-time for java,
gcj broke on ppc*-linux (e.g. gcj-dbtool hanged).
The problem is with .rodata.jutf8.* constants.
ppc* uses -fsection-anchors and with that option align directives
aren't emitted everywhere.  gcj cheats and declares all utf8 constants
with utf8const_type (i.e. 4 byte) type, eventhough their DECL_INITIAL is
longer (includes the string).  So while e.g. i?86 outputs
.section        .rodata.jutf8.6,"aM",@progbits,6
        .section        .rodata.jutf8.6
        .align 2
        .type   _Utf126, @object
        .size   _Utf126, 4
_Utf126:
# hash:
        .value  42
# length:
        .value  1
# data:
        .ascii  "*"
        .zero   1
        .align 2
        .type   _Utf125, @object
        .size   _Utf125, 4
_Utf125:
# hash:
        .value  0
# length:
        .value  0
# data:
        .zero   1
        .section        .rodata.jutf8.6
        .align 2
        .type   _Utf168, @object
        .size   _Utf168, 4
_Utf168:
# hash:
        .value  47
# length:
        .value  1
# data:
        .ascii  "/"
        .zero   1
where the .align 2 directives (.balign in i?86 case) ensure the
padding is added, on ppc-linux we get:
	.section        .rodata.jutf8.6,"aM",@progbits,6
        .section        .rodata.jutf8.6
        .align 1
        .type   _Utf126, @object
        .size   _Utf126, 4
_Utf126:
 # hash:
        .short  42
 # length:
        .short  1
 # data:
        .ascii  "*"
        .zero   1
        .type   _Utf125, @object
        .size   _Utf125, 4
_Utf125:
 # hash:
        .short  0
 # length:
        .short  0
 # data:
        .zero   1
        .type   _Utf168, @object
        .size   _Utf168, 4
_Utf168:
 # hash:
        .short  47
 # length:
        .short  1
 # data:
        .ascii  "/"
        .zero   1
where there is just one .align 1 (.p2align in ppc case) directive
at the beginning.  This means _Utf125 object is actually just 5
bytes long, which is fatal for SHF_MERGE section with entsize 6
- suddenly many strings will have incorrect hashes, lengths around
64K-epsilon and unexpected data.
Fixed thusly, gcj will now emit .zero 2 in the above case where
the string size without trailing '\0' is a multiple of 2, instead
of .zero 1.

Without this patch, libjava build hangs in gcj-dbtool command, with
this patch it built fine and is now in make check.

Ok for trunk?

2008-07-28  Jakub Jelinek  <jakub@redhat.com>

	* class.c (build_utf8_ref): Pad initializer string to utf8const_type's
	alignment.

--- gcc/java/class.c.jj	2008-07-19 22:06:59.000000000 +0200
+++ gcc/java/class.c	2008-07-28 15:03:31.000000000 +0200
@@ -930,8 +930,8 @@ static GTY(()) tree utf8_decl_list = NUL
 tree
 build_utf8_ref (tree name)
 {
-  const char * name_ptr = IDENTIFIER_POINTER(name);
-  int name_len = IDENTIFIER_LENGTH(name);
+  const char * name_ptr = IDENTIFIER_POINTER (name);
+  int name_len = IDENTIFIER_LENGTH (name), name_pad;
   char buf[60];
   tree ctype, field = NULL_TREE, str_type, cinit, string;
   static int utf8_count = 0;
@@ -942,8 +942,11 @@ build_utf8_ref (tree name)
     return ref;
 
   ctype = make_node (RECORD_TYPE);
+  /* '\0' byte plus padding to utf8const_type's alignment.  */
+  name_pad = TYPE_ALIGN_UNIT (utf8const_type)
+	     - (name_len & (TYPE_ALIGN_UNIT (utf8const_type) - 1));
   str_type = build_prim_array_type (unsigned_byte_type_node,
-				    name_len + 1); /* Allow for final '\0'. */
+				    name_len + name_pad);
   PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node);
   PUSH_FIELD (ctype, field, "length", unsigned_short_type_node);
   PUSH_FIELD (ctype, field, "data", str_type);
@@ -973,8 +976,7 @@ build_utf8_ref (tree name)
     {
       int decl_size;
       /* Ensure decl_size is a multiple of utf8const_type's alignment. */
-      decl_size = (name_len + 5 + TYPE_ALIGN_UNIT (utf8const_type) - 1)
-	& ~(TYPE_ALIGN_UNIT (utf8const_type) - 1);
+      decl_size = name_len + 4 + name_pad;
       if (flag_merge_constants && decl_size < 256)
 	{
 	  char buf[32];

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]