[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
problem with dynamic symbols forced to local on Itanium linker
From: |
Lowney, Geoff |
Subject: |
problem with dynamic symbols forced to local on Itanium linker |
Date: |
Mon, 4 Mar 2002 20:19:04 -0800 |
3/4/02
I am running on an Itanium Linux system, using GNU ld version 020224
20020224, which I built locally. I am writing a binary optimizer
for Itanium, and I have a problem with the linker.
I am preserving the relocations in the final output (-q or
--emit-relocs). For dynamic symbols that are forced local, the linker
places a bad index into the relocation. (It leaves a -2 there.) The
linker also generates assertion failures when generating the image.
xxx/ld/ld-new: BFD 020224 20020224 assertion fail elflink.h:4561
xxx/ld/ld-new: BFD 020224 20020224 assertion fail elflink.h:456
Here is a scenario that generates the problem. I call the linker
with the follow shell script:
#!/bin/csh
~/myproj/gnu/ld/binutils-020224/ld/ld-new \
-q \
/proj/vssad/users/lowney/gnu/libc/ecc_static_build.1/csu/crt1.o \
/proj/vssad/users/lowney/gnu/libc/ecc_static_build.1/csu/crti.o \
/proj/vssad/users/lowney/electron/libdev/libcprts/__distrib/ia64-RH7.1/lib/c
rtxi.o \
-dynamic-linker \
/lib/ld-linux-ia64.so.2 \
-o \
a.out \
-relax \
hello.o \
-o \
hello \
-Qy \
-u \
___pseudo_link \
-L/opt/intel/compiler50/ia64/lib \
-L/usr/lib \
-lm \
/proj/vssad/users/lowney/electron/libdev/libcprts/__distrib/ia64-RH7.1/lib/l
ibcprts.a \
/proj/vssad/users/lowney/electron/libdev/libcprts/__distrib/ia64-RH7.1/lib/l
ibcxa.a \
/proj/vssad/users/lowney/electron/libdev/libcprts/__distrib/ia64-RH7.1/lib/l
ibcprts.a \
/proj/vssad/users/lowney/electron/libdev/libcprts/__distrib/ia64-RH7.1/lib/l
ibunwind.a \
-lc \
/proj/vssad/users/lowney/electron/libdev/libcprts/__distrib/ia64-RH7.1/lib/c
rtxn.o \
/proj/vssad/users/lowney/gnu/libc/ecc_static_build.1/csu/crtn.o
The problem symbol is __dso_handle. Here are the references to the
symbol in the files that are linked, using nm.
crt1.o
crti.o
crtxi.o
0000000000000000 D __dso_handle
libcprts.a
U __dso_handle
U __dso_handle
U __dso_handle
U __dso_handle
U __dso_handle
U __dso_handle
libcxa.a
U __dso_handle
libunwind.a
libc.so.6.1
w __dso_handle
crtxn.o
0000000000000008 C __dso_handle
crtn.o
/lib/ld-linux-ia64.so.2
Here is my interpretation of what happens:
1. crtxi.o defines __dso_handle as a global symbol, and, in
elf_link_add_object_symbols, it is entered into the
elf_link_hash_table as ELF_LINK_HASH_DEF_REGULAR.
2. libc.so.6.1 defines __dso_handle as a weak symbol, and sets
ELF_LINK_HASH_REF_REGULAR, ELF_LINK_HASH_REF_DYNAMIC, and then
forces it to ELF_LINK_FORCED_LOCAL
3. crtxn.o defines __dso_handle as a common symbol, and adds
ELF_LINK_HASH_REF_REGULAR_NONWEAK.
After all the calls to elf_link_add_object_symbols, __dso_handle has
the following flags:
ELF_LINK_HASH_REF_REGULAR
ELF_LINK_HASH_DEF_REGULAR
ELF_LINK_HASH_REF_DYNAMIC
ELF_LINK_HASH_REF_REGULAR_NONWEAK
ELF_LINK_FORCED_LOCAL
4. In elf_link_input_bfd, we set the rel_hash entry 'indx' field to
-2, to indicate that the symbol is used by a reloc.
5. In elf_bfd_final_link, we traverse the hash table
(elf_link_hash_traverse) to output the global symbols (calling
elf_link_output_extsym), but this routine explicitly skips over
ELF_LINK_FORCED_LOCAL symbols.
/* Decide whether to output this symbol in this pass. */
if (eoinfo->localsyms)
{
if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
return true;
}
else
{
if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
return true;
}
6. And then in elf_link_adjust_relocs, we iterate over all the rel_hash
entries, and assert on the indx field being set to -2.
for (i = 0; i < count; i++, rel_hash++)
{
if (*rel_hash == NULL)
continue;
BFD_ASSERT ((*rel_hash)->indx >= 0);
...
7. And we output a file with bad symbol index for the two relocations
which refer to __dso_handle.
Relocation section '.rela.text' at offset 0x34318 contains 730 entries:
Offset Info Type Symbol's Value
Symbol's Name Addend
4000000000000832 0000000e0000002b R_IA64_GPREL64I
4000000000000820 .text + 20
...
400000000002acf2 0000036000000049 R_IA64_PCREL21B
40000000000179e0 _Unwind_Resume + 0
400000000002ada0 fffffffe00000032 R_IA64_LTOFF22 bad symbol
index: fffffffe
400000000002adf2 000003ee00000049 R_IA64_PCREL21B
0000000000000000 __cxa_finalize@@GLIBC_2.2 + 0
...
Relocation section '.rela.data' at offset 0x3bb90 contains 249 entries:
Offset Info Type Symbol's Value
Symbol's Name Addend
600000000000edf0 fffffffe00000027 R_IA64_DIR64LSB bad symbol
index: fffffffe
600000000000ee00 0000032f00000047 R_IA64_FPTR64LSB
4000000000001ac0 _ZN25__Nexception_cpp_986 + 0
...
My fix:
I fixed this problem by removing the check for ELF_LINK_FORCED_LOCAL
for global symbols in elf_bfd_final_link. This removes the assertion
failures in this simple link, and does not output bad symbol indices
in the relocations.
/* Decide whether to output this symbol in this pass. */
if (eoinfo->localsyms)
{
if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
return true;
}
else
{
#if 0
if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
return true;
#endif
}
Is this correct? Why is the check there?
Is there more information I could provide that would clarify what the
linker should be doing in this case?
- problem with dynamic symbols forced to local on Itanium linker,
Lowney, Geoff <=