This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH, arm] Support for Thumb init/fini entry points
- From: Adam Nemet <anemet at Lnxw dot COM>
- To: Richard dot Earnshaw at arm dot com
- Cc: Nick Clifton <nickc at redhat dot com>, binutils at sources dot redhat dot com
- Date: 12 Aug 2002 23:00:14 -0700
- Subject: [PATCH, arm] Support for Thumb init/fini entry points
- References: <200208010854.JAA26181@cam-mail2.cambridge.arm.com>
Hi,
Since it seems that my Thumb PLT patch has to wait until the EABI spec
gets released, I separated the init/fini part that does not have any
ABI implications.
The idea is that I set the last bit of DT_INIT/FINI if the function is
of type STT_ARM_TFUNC. If this is acceptable we could probably do the
same thing for the entry point and then --thumb-entry would become
just an alias for --entry.
It was regtested together with the PLT patch on arm-elf.
Please apply if OK.
Adam
bfd/ChangeLog:
2002-08-12 Adam Nemet <anemet@lnxw.com>
* elflink.h (elf_bfd_final_link): Allow numbers in
link_info.{init,fini}_function.
ld/ChangeLog:
2002-08-12 Adam Nemet <anemet@lnxw.com>
* emultempl/armelf.em: Include elf-bfd.h and elf/arm.h.
(arm_elf_finish): Set the last bit of DT_INIT and DT_FINI
depending on the type of the function.
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.177
diff -c -p -r1.177 elflink.h
*** bfd/elflink.h 16 Jul 2002 12:31:35 -0000 1.177
--- bfd/elflink.h 17 Jul 2002 22:30:28 -0000
*************** elf_bfd_final_link (abfd, info)
*** 5662,5667 ****
--- 5662,5681 ----
elf_swap_dyn_out (dynobj, &dyn, dyncon);
}
+ else
+ {
+ bfd_vma val;
+ CONST char *send;
+
+ /* We couldn't find the entry symbol. Try parsing it as a
+ number. */
+ val = bfd_scan_vma (name, &send, 0);
+ if (*send == '\0')
+ {
+ dyn.d_un.d_val = val;
+ elf_swap_dyn_out (dynobj, &dyn, dyncon);
+ }
+ }
}
break;
Index: ld/emultempl/armelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/armelf.em,v
retrieving revision 1.27
diff -c -p -r1.27 armelf.em
*** ld/emultempl/armelf.em 1 Jul 2002 08:07:31 -0000 1.27
--- ld/emultempl/armelf.em 17 Jul 2002 22:30:28 -0000
***************
*** 24,33 ****
#
cat >>e${EMULATION_NAME}.c <<EOF
static int no_pipeline_knowledge = 0;
static char *thumb_entry_symbol = NULL;
static bfd *bfd_for_interwork;
!
static void
gld${EMULATION_NAME}_before_parse ()
--- 24,36 ----
#
cat >>e${EMULATION_NAME}.c <<EOF
+ #include "elf-bfd.h"
+ #include "elf/arm.h"
+
static int no_pipeline_knowledge = 0;
static char *thumb_entry_symbol = NULL;
static bfd *bfd_for_interwork;
*************** static void
*** 138,185 ****
arm_elf_finish ()
{
struct bfd_link_hash_entry * h;
/* Call the elf32.em routine. */
gld${EMULATION_NAME}_finish ();
! if (thumb_entry_symbol == NULL)
! return;
!
! h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol,
! false, false, true);
if (h != (struct bfd_link_hash_entry *) NULL
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak)
&& h->u.def.section->output_section != NULL)
{
static char buffer[32];
bfd_vma val;
!
! /* Special procesing is required for a Thumb entry symbol. The
! bottom bit of its address must be set. */
val = (h->u.def.value
+ bfd_get_section_vma (output_bfd,
h->u.def.section->output_section)
+ h->u.def.section->output_offset);
!
val |= 1;
! /* Now convert this value into a string and store it in entry_symbol
! where the lang_finish() function will pick it up. */
buffer[0] = '0';
buffer[1] = 'x';
!
sprintf_vma (buffer + 2, val);
! if (entry_symbol.name != NULL && entry_from_cmdline)
! einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
! thumb_entry_symbol, entry_symbol.name);
! entry_symbol.name = buffer;
}
- else
- einfo (_("%P: warning: connot find thumb start symbol %s\n"),
- thumb_entry_symbol);
}
EOF
--- 142,256 ----
arm_elf_finish ()
{
struct bfd_link_hash_entry * h;
+ struct elf_link_hash_entry * eh;
/* Call the elf32.em routine. */
gld${EMULATION_NAME}_finish ();
! if (thumb_entry_symbol != NULL)
! {
! h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol,
! false, false, true);
!
! if (h != (struct bfd_link_hash_entry *) NULL
! && (h->type == bfd_link_hash_defined
! || h->type == bfd_link_hash_defweak)
! && h->u.def.section->output_section != NULL)
! {
! static char buffer[32];
! bfd_vma val;
!
! /* Special procesing is required for a Thumb entry symbol. The
! bottom bit of its address must be set. */
! val = (h->u.def.value
! + bfd_get_section_vma (output_bfd,
! h->u.def.section->output_section)
! + h->u.def.section->output_offset);
!
! val |= 1;
!
! /* Now convert this value into a string and store it in entry_symbol
! where the lang_finish() function will pick it up. */
! buffer[0] = '0';
! buffer[1] = 'x';
!
! sprintf_vma (buffer + 2, val);
!
! if (entry_symbol.name != NULL && entry_from_cmdline)
! einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
! thumb_entry_symbol, entry_symbol.name);
! entry_symbol.name = buffer;
! }
! else
! einfo (_("%P: warning: connot find thumb start symbol %s\n"),
! thumb_entry_symbol);
! }
!
! /* If init is a Thumb function set the LSB. */
! h = bfd_link_hash_lookup (link_info.hash, link_info.init_function, false,
! false, true);
! eh = (struct elf_link_hash_entry *)h;
if (h != (struct bfd_link_hash_entry *) NULL
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak)
+ && ELF_ST_TYPE (eh->type) == STT_ARM_TFUNC
&& h->u.def.section->output_section != NULL)
{
static char buffer[32];
bfd_vma val;
!
! /* Special procesing is required for a Thumb symbol. The bottom
! bit of its address must be set. */
val = (h->u.def.value
+ bfd_get_section_vma (output_bfd,
h->u.def.section->output_section)
+ h->u.def.section->output_offset);
!
val |= 1;
! /* Now convert this value into a string and store it in
! init_function where the elf_bfd_final_link() function will
! pick it up. */
buffer[0] = '0';
buffer[1] = 'x';
!
sprintf_vma (buffer + 2, val);
+ link_info.init_function = buffer;
+ }
+
+ /* If fini is a Thumb function set the LSB. */
+ h = bfd_link_hash_lookup (link_info.hash, link_info.fini_function, false,
+ false, true);
+ eh = (struct elf_link_hash_entry *)h;
! if (h != (struct bfd_link_hash_entry *) NULL
! && (h->type == bfd_link_hash_defined
! || h->type == bfd_link_hash_defweak)
! && ELF_ST_TYPE (eh->type) == STT_ARM_TFUNC
! && h->u.def.section->output_section != NULL)
! {
! static char buffer[32];
! bfd_vma val;
!
! /* Special procesing is required for a Thumb symbol. The bottom
! bit of its address must be set. */
! val = (h->u.def.value
! + bfd_get_section_vma (output_bfd,
! h->u.def.section->output_section)
! + h->u.def.section->output_offset);
!
! val |= 1;
!
! /* Now convert this value into a string and store it in
! fini_function where the elf_bfd_final_link() function will
! pick it up. */
! buffer[0] = '0';
! buffer[1] = 'x';
!
! sprintf_vma (buffer + 2, val);
! link_info.fini_function = buffer;
}
}
EOF