PATCH: Improve ELF linker for non-ELF input
H. J. Lu
hjl@lucon.org
Fri Apr 23 01:22:00 GMT 2004
On Thu, Apr 22, 2004 at 01:39:34PM -0700, H. J. Lu wrote:
> The current ELF linker can link in non-ELF input if it doesn't
> reference symbols in DSO. This patch improves it a little bit so
> that simple function call to DSO works.
>
>
> H.J.
> ------
> 2004-04-22 H.J. Lu <hongjiu.lu@intel.com>
>
> * elflink.c (_bfd_elf_link_create_dynamic_sections): Clear
> the ELF_LINK_NON_ELF bit on _DYNAMIC.
> (_bfd_elf_fix_symbol_flags): Increment PLT count for dynamic
> symbols referenced by non-ELF files.
>
This patch is incomplete. Here is the new one. With it, I can link
non-ELF input on Linux to generate working ELF executable.
H.J.
-------------- next part --------------
2004-04-22 H.J. Lu <hongjiu.lu@intel.com>
* elf.c (_bfd_elf_link_hash_copy_indirect): Also copy
ELF_LINK_NON_ELF.
* elf32-i386.c (ELIMINATE_COPY_RELOCS): Add hash as an argument.
FALSE if the ELF_LINK_NON_ELF bit is set. Update usages.
* elflink.c (_bfd_elf_link_create_dynamic_sections): Clear
the ELF_LINK_NON_ELF bit on _DYNAMIC.
(_bfd_elf_fix_symbol_flags): Increment PLT count for dynamic
function symbols referenced by non-ELF files. Set the
ELF_LINK_NON_GOT_REF bit for dynamic object symbols
referenced by non-ELF files.
--- bfd/elf.c.mix 2004-04-22 11:08:27.000000000 -0700
+++ bfd/elf.c 2004-04-22 16:25:06.000000000 -0700
@@ -1360,6 +1360,7 @@ _bfd_elf_link_hash_copy_indirect (const
| ELF_LINK_HASH_REF_REGULAR
| ELF_LINK_HASH_REF_REGULAR_NONWEAK
| ELF_LINK_NON_GOT_REF
+ | ELF_LINK_NON_ELF
| ELF_LINK_HASH_NEEDS_PLT
| ELF_LINK_POINTER_EQUALITY_NEEDED);
--- bfd/elf32-i386.c.mix 2004-04-22 08:19:28.000000000 -0700
+++ bfd/elf32-i386.c 2004-04-22 14:50:20.000000000 -0700
@@ -464,7 +464,8 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Int
copying dynamic variables from a shared lib into an app's dynbss
section, and instead use a dynamic relocation to point into the
shared lib. */
-#define ELIMINATE_COPY_RELOCS 1
+#define ELIMINATE_COPY_RELOCS(h) \
+ (!(h) || !((h)->elf_link_hash_flags & ELF_LINK_NON_ELF))
/* The size in bytes of an entry in the procedure linkage table. */
@@ -782,7 +783,7 @@ elf_i386_copy_indirect_symbol (const str
eind->tls_type = GOT_UNKNOWN;
}
- if (ELIMINATE_COPY_RELOCS
+ if (ELIMINATE_COPY_RELOCS (dir)
&& ind->root.type != bfd_link_hash_indirect
&& (dir->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
/* If called to transfer flags for a weakdef during processing
@@ -1056,7 +1057,7 @@ elf_i386_check_relocs (bfd *abfd,
|| h->root.type == bfd_link_hash_defweak
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0))))
- || (ELIMINATE_COPY_RELOCS
+ || (ELIMINATE_COPY_RELOCS (h)
&& !info->shared
&& (sec->flags & SEC_ALLOC) != 0
&& h != NULL
@@ -1361,7 +1362,7 @@ elf_i386_adjust_dynamic_symbol (struct b
|| h->weakdef->root.type == bfd_link_hash_defweak);
h->root.u.def.section = h->weakdef->root.u.def.section;
h->root.u.def.value = h->weakdef->root.u.def.value;
- if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
+ if (ELIMINATE_COPY_RELOCS (h) || info->nocopyreloc)
h->elf_link_hash_flags
= ((h->elf_link_hash_flags & ~ELF_LINK_NON_GOT_REF)
| (h->weakdef->elf_link_hash_flags & ELF_LINK_NON_GOT_REF));
@@ -1390,7 +1391,7 @@ elf_i386_adjust_dynamic_symbol (struct b
return TRUE;
}
- if (ELIMINATE_COPY_RELOCS)
+ if (ELIMINATE_COPY_RELOCS (h))
{
struct elf_i386_link_hash_entry * eh;
struct elf_i386_dyn_relocs *p;
@@ -1628,7 +1629,7 @@ allocate_dynrelocs (struct elf_link_hash
&& h->root.type == bfd_link_hash_undefweak)
eh->dyn_relocs = NULL;
}
- else if (ELIMINATE_COPY_RELOCS)
+ else if (ELIMINATE_COPY_RELOCS (h))
{
/* For the non-shared case, discard space for relocs against
symbols which turn out to need copy relocs or are not
@@ -2321,7 +2322,7 @@ elf_i386_relocate_section (bfd *output_b
|| h->root.type != bfd_link_hash_undefweak)
&& (r_type != R_386_PC32
|| !SYMBOL_CALLS_LOCAL (info, h)))
- || (ELIMINATE_COPY_RELOCS
+ || (ELIMINATE_COPY_RELOCS (h)
&& !info->shared
&& h != NULL
&& h->dynindx != -1
--- bfd/elflink.c.mix 2004-04-22 08:20:09.000000000 -0700
+++ bfd/elflink.c 2004-04-22 18:05:35.000000000 -0700
@@ -218,6 +218,7 @@ _bfd_elf_link_create_dynamic_sections (b
return FALSE;
h = (struct elf_link_hash_entry *) bh;
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
h->type = STT_OBJECT;
if (! info->executable
@@ -2087,6 +2088,22 @@ _bfd_elf_fix_symbol_flags (struct elf_li
eif->failed = TRUE;
return FALSE;
}
+
+ switch (h->type)
+ {
+ case STT_OBJECT:
+ /* It doesn't use GOT. */
+ h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+ break;
+
+ case STT_FUNC:
+ /* We need it to keep the PLT entry. */
+ h->plt.refcount++;
+ break;
+
+ default:
+ break;
+ }
}
}
else
More information about the Binutils
mailing list