PATCH: Fix alignment of common symbol
H. J. Lu
hjl@lucon.org
Thu Apr 10 18:26:00 GMT 2003
When there is a alignment differnce between common/normal symbols or
common symbols, ld doesn't check alignment. Here is a testcase:
gcc -O -g -c main.c
gcc -O -g -c foo.c
gcc -o foo1 -B./ main.o foo.o
/usr/bin/ld: Warning: size of symbol `foo' changed from 2 to 21 in foo.o
gcc -o foo2 -B./ foo.o main.o
for f in foo1 foo2; do echo "Running: $f"; ./$f; \
if [ $? != 0 ]; then echo Failed; fi; done
Running: foo1
0x8049421: 1
0x8049536: 2
Running: foo2
0x8049421: 1
0x8049550: 16
I also include a patch.
H.J.
-------------- next part --------------
2003-04-10 H.J. Lu <hjl@gnu.org>
* elflink.h (elf_link_add_object_symbols): Properly handle
alignment for common symbols.
--- bfd/elflink.h.common 2003-04-08 10:56:49.000000000 -0700
+++ bfd/elflink.h 2003-04-10 11:14:24.000000000 -0700
@@ -1999,6 +1999,8 @@ elf_link_add_object_symbols (abfd, info)
is specified and no other alignments have been specified. */
|| (isym->st_value == 1 && old_alignment == 0))
h->root.u.c.p->alignment_power = align;
+ else
+ h->root.u.c.p->alignment_power = old_alignment;
}
if (info->hash->creator->flavour == bfd_target_elf_flavour)
@@ -2007,6 +2009,42 @@ elf_link_add_object_symbols (abfd, info)
bfd_boolean dynsym;
int new_flag;
+ /* Check the alignment when a common symbol is involved. It
+ can happen when a common symbol is overriden by a normal
+ definition or a common symbol is ignored due to the old
+ normal definition. We need to make sure the maximum
+ alignment is maintained. */
+ if ((old_alignment || isym->st_shndx == SHN_COMMON)
+ && h->root.type != bfd_link_hash_common)
+ {
+ unsigned int common_align, normal_align, symbol_align;
+
+ symbol_align = ffs (h->root.u.def.value) - 1;
+ if ((h->root.u.def.section->owner->flags & DYNAMIC) == 0)
+ {
+ normal_align = h->root.u.def.section->alignment_power;
+ if (normal_align > symbol_align)
+ normal_align = symbol_align;
+ }
+ else
+ normal_align = symbol_align;
+
+ if (old_alignment)
+ common_align = old_alignment;
+ else
+ common_align = bfd_log2 (isym->st_value);
+
+ if (normal_align < common_align)
+ {
+ (*_bfd_error_handler)
+ (_("alignment of symbol `%s' changed from %u to %u in %s"),
+ name, 1 << common_align, 1 << normal_align,
+ bfd_archive_filename (abfd));
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
+ }
+ }
+
/* Remember the symbol size and type. */
if (isym->st_size != 0
&& (definition || h->size == 0))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bug.tar.gz
Type: application/x-gzip
Size: 662 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20030410/20bd1204/attachment.bin>
More information about the Binutils
mailing list