summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/elf-vxworks.c67
-rw-r--r--bfd/elf-vxworks.h3
2 files changed, 70 insertions, 0 deletions
diff --git a/bfd/elf-vxworks.c b/bfd/elf-vxworks.c
index 98d2dfca98..074430c78f 100644
--- a/bfd/elf-vxworks.c
+++ b/bfd/elf-vxworks.c
@@ -25,6 +25,7 @@
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf-vxworks.h"
+#include "elf/vxworks.h"
/* Return true if symbol NAME, as defined by ABFD, is one of the special
__GOTT_BASE__ or __GOTT_INDEX__ symbols. */
@@ -225,3 +226,69 @@ elf_vxworks_final_write_processing (bfd *abfd,
if (sec)
d->this_hdr.sh_info = elf_section_data (sec)->this_idx;
}
+
+/* Add the dynamic entries required by VxWorks. These point to the
+ tls sections. */
+
+bfd_boolean
+elf_vxworks_add_dynamic_entries (bfd *output_bfd, struct bfd_link_info *info)
+{
+ if (bfd_get_section_by_name (output_bfd, ".tls_data"))
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_START, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_SIZE, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_ALIGN, 0))
+ return FALSE;
+ }
+ if (bfd_get_section_by_name (output_bfd, ".tls_vars"))
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_START, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_SIZE, 0))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* If *DYN is one of the VxWorks-specific dynamic entries, then fill
+ in the value now and return TRUE. Otherwise return FALSE. */
+
+bfd_boolean
+elf_vxworks_finish_dynamic_entry (bfd *output_bfd, Elf_Internal_Dyn *dyn)
+{
+ asection *sec;
+
+ switch (dyn->d_tag)
+ {
+ default:
+ return FALSE;
+
+ case DT_VX_WRS_TLS_DATA_START:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+ dyn->d_un.d_ptr = sec->vma;
+ break;
+
+ case DT_VX_WRS_TLS_DATA_SIZE:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+ dyn->d_un.d_val = sec->size;
+ break;
+
+ case DT_VX_WRS_TLS_DATA_ALIGN:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+ dyn->d_un.d_val
+ = (bfd_size_type)1 << bfd_get_section_alignment (abfd, sec);
+ break;
+
+ case DT_VX_WRS_TLS_VARS_START:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_vars");
+ dyn->d_un.d_ptr = sec->vma;
+ break;
+
+ case DT_VX_WRS_TLS_VARS_SIZE:
+ sec = bfd_get_section_by_name (output_bfd, ".tls_vars");
+ dyn->d_un.d_val = sec->size;
+ break;
+ }
+ return TRUE;
+}
+
+
diff --git a/bfd/elf-vxworks.h b/bfd/elf-vxworks.h
index 1b461d0ea4..6850b3e300 100644
--- a/bfd/elf-vxworks.h
+++ b/bfd/elf-vxworks.h
@@ -33,3 +33,6 @@ bfd_boolean elf_vxworks_emit_relocs
void elf_vxworks_final_write_processing (bfd *, bfd_boolean);
bfd_boolean elf_vxworks_create_dynamic_sections
(bfd *, struct bfd_link_info *, asection **);
+bfd_boolean elf_vxworks_add_dynamic_entries (bfd *, struct bfd_link_info *);
+bfd_boolean elf_vxworks_finish_dynamic_entry (bfd *, Elf_Internal_Dyn *);
+