This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
More Solaris 2 ABI fixes: emit local _START_, _END_
- From: Rainer Orth <ro at CeBiTec dot Uni-Bielefeld dot DE>
- To: binutils at sourceware dot org
- Date: Mon, 27 Sep 2010 19:11:05 +0200
- Subject: More Solaris 2 ABI fixes: emit local _START_, _END_
As a followup to
More Solaris 2 ABI fixes: emit _DYNAMIC etc. into .dynsym
http://sourceware.org/ml/binutils/2010-09/msg00482.html
there's one element of the Solaris 2 ABI that gld doesn't follow yet:
the LLM
Linker and Libraries Guide
Chapter 2, Link-Editor, Generating the Output File
http://docs.sun.com/app/docs/doc/819-0690/chapter2-88783?a=view
requires that two symbols with local binding are emitted in every
dynamic executable or shared object:
_END_
The same as _end. The symbol has local scope and, together with
_START_, provides a means of establishing an object's address
range.
_START_
The first location within the text segment. The symbol has local
scope and, together with _END_, provides a means of establishing an
object's address range.
I tried to implement this, but failed so far, so I'm asking for advice.
While it is easy to generate those symbols from a linker script (I've
used
TEXT_START_SYMBOLS='_START_ = .;'
OTHER_END_SYMBOLS='_END_ = .;'
defined in a new ld/emulparams/solaris2.sh and included from the other
ld/emulparams/*sol2.sh files), those symbols become global and I found
no reliable way to change their binding to local. At first I tried to
add a default anonymous version script to the end of
ld/scripttempl/elf.sc (via some VERSION_SCRIPT variable only defined in
ld/emulparams/solaris2.sh):
VERSION
{
{
local:
_START_;
_END_;
};
};
While this had the desired effect for dynamic executables and
unversioned shared objects, it broke for versioned shared objects (like
libgcc_s.so.1):
gld: anonymous version tag cannot be combined with other version tags
no doubt due to the code in ld/emultempl/solaris2.em
(elf_solaris2_before_allocation).
My next attempt was to achieve this directly in ld/emultempl/solaris2.em
with C code: I tried all of gld${EMULATION_NAME}_before_allocation,
_after_allocation, and _finish with a snippet like this
/* Do this for both executables and shared objects. */
if (!link_info.relocatable)
{
struct elf_link_hash_entry *h;
/* Add _START_ and _END_. */
/* FIXME: Error handling. */
h = elf_link_hash_lookup (elf_hash_table (&link_info), "_start",
FALSE, FALSE, FALSE);
if (h != NULL)
{
if (!_bfd_generic_link_add_one_symbol (&link_info,
link_info.output_bfd,
"_START_", BSF_LOCAL,
h->root.u.def.section,
h->root.u.def.value,
NULL, FALSE, FALSE, NULL))
fprintf (stderr, "Couldn't add _START_\n");
}
else
fprintf (stderr, "_start not found\n");
But always got `_start not found'. I've no idea what I'm doing wrong,
and the BFD API is a complete mystery to me with its mixture of generic
and ELF-specific code.
Any suggestions on how to achieve this properly?
Thanks.
Rainer
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University