A patch for binutils (Re: the setrlimit changes in glibc 2.1.3)
H . J . Lu
hjl@lucon.org
Thu Jan 13 11:23:00 GMT 2000
> > >
> > > Install glibc 2.1.2 (before the setrlimit changes), do a "make libfoo.so",
> > > then upgrade to the current glibc and in the same directory do a "make
> > > test". The link will fail.
> > >
> >
> > Thanks. It is what I need. I will try to fix the linker.
>
> I happen to have this testcase handy. It may be easier to deal with
> (it could actually be turned into an expect test for the linker).
>
> Just do 'make'. It should build properly, but it doesn't.
>
Thanks. Here is a patch for binutils 2.9.5.0.22. Ian, what do you
think?
H.J.
----
Thu Jan 13 11:03:29 2000 H.J. Lu <hjl@gnu.org>
* elflink.h (elf_link_add_object_symbols): Bound the external
references to the default version to the hidden version.
Index: elflink.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elflink.h,v
retrieving revision 1.14
diff -u -p -r1.14 elflink.h
--- elflink.h 1999/11/01 22:47:51 1.14
+++ elflink.h 2000/01/13 19:18:31
@@ -1463,7 +1463,12 @@ elf_link_add_object_symbols (abfd, info)
version, we create an indirect symbol from the default
name to the fully decorated name. This will cause
external references which do not specify a version to be
- bound to this version of the symbol. */
+ bound to this version of the symbol.
+
+ If this symbol is hidden, we create an indirect symbol
+ from the default version the hidden one. This will cause
+ external references to the default version to be bound to
+ this symbol. */
if (definition)
{
char *p;
@@ -1738,6 +1743,117 @@ elf_link_add_object_symbols (abfd, info)
& ELF_LINK_HASH_REF_REGULAR) != 0)
dynsym = true;
}
+ }
+ }
+ }
+ }
+ else if (p != NULL)
+ {
+ char *defaultversion;
+ struct elf_link_hash_entry *hi;
+ boolean override;
+
+ defaultversion = bfd_hash_allocate (&info->hash->table,
+ strlen (name) + 2);
+ if (defaultversion == NULL)
+ goto error_return;
+ strncpy (defaultversion, name, p - name + 1);
+ defaultversion[p - name + 1] = ELF_VER_CHR;
+ strcpy (&defaultversion[p - name + 2], p + 1);
+
+ /* We are going to create a new symbol. Merge it
+ with any existing symbol with this name. For the
+ purposes of the merge, act as though we were
+ defining the symbol we just defined, although we
+ actually going to define an indirect symbol. */
+ type_change_ok = false;
+ size_change_ok = false;
+ if (! elf_merge_symbol (abfd, info, defaultversion, &sym, &sec,
+ &value, &hi, &override,
+ &type_change_ok, &size_change_ok))
+ goto error_return;
+
+ if (override
+ || ! (_bfd_generic_link_add_one_symbol
+ (info, abfd, defaultversion, BSF_INDIRECT,
+ bfd_ind_section_ptr, (bfd_vma) 0, name, false,
+ collect, (struct bfd_link_hash_entry **) &hi)))
+ goto error_return;
+
+ /* If there is a duplicate definition somewhere,
+ then HI may not point to an indirect symbol. We
+ will have reported an error to the user in that
+ case. */
+
+ if (hi->root.type == bfd_link_hash_indirect)
+ {
+ struct elf_link_hash_entry *ht;
+
+ /* If the symbol became indirect, then we assume
+ that we have not seen a definition before. */
+ BFD_ASSERT ((hi->elf_link_hash_flags
+ & (ELF_LINK_HASH_DEF_DYNAMIC
+ | ELF_LINK_HASH_DEF_REGULAR))
+ == 0);
+
+ ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
+
+ /* Copy down any references that we may have
+ already seen to the symbol which just became
+ indirect. */
+ ht->elf_link_hash_flags |=
+ (hi->elf_link_hash_flags
+ & (ELF_LINK_HASH_REF_DYNAMIC
+ | ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR_NONWEAK
+ | ELF_LINK_NON_GOT_REF));
+
+ /* Copy over the global and procedure linkage table
+ offset entries. These may have been already set
+ up by a check_relocs routine. */
+ if (ht->got.offset == (bfd_vma) -1)
+ {
+ ht->got.offset = hi->got.offset;
+ hi->got.offset = (bfd_vma) -1;
+ }
+ BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
+
+ if (ht->plt.offset == (bfd_vma) -1)
+ {
+ ht->plt.offset = hi->plt.offset;
+ hi->plt.offset = (bfd_vma) -1;
+ }
+ BFD_ASSERT (hi->plt.offset == (bfd_vma) -1);
+
+ if (ht->dynindx == -1)
+ {
+ ht->dynindx = hi->dynindx;
+ ht->dynstr_index = hi->dynstr_index;
+ hi->dynindx = -1;
+ hi->dynstr_index = 0;
+ }
+ BFD_ASSERT (hi->dynindx == -1);
+
+ /* FIXME: There may be other information to copy
+ over for particular targets. */
+
+ /* See if the new flags lead us to realize that
+ the symbol must be dynamic. */
+ if (! dynsym)
+ {
+ if (! dynamic)
+ {
+ if (info->shared
+ || ((hi->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_DYNAMIC)
+ != 0))
+ dynsym = true;
+ }
+ else
+ {
+ if ((hi->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0)
+ dynsym = true;
}
}
}
More information about the Libc-hacker
mailing list