This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix gcj on ppc*-linux
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Andrew Haley <aph at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 28 Jul 2008 11:55:02 -0400
- Subject: [PATCH] Fix gcj on ppc*-linux
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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