Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: bfd/elf64-x86-64.c

Issue 23903052: fix Base URL: http://git.chromium.org/native_client/nacl-binutils.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « bfd/elf32-i386.c ('k') | binutils/ar.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: bfd/elf64-x86-64.c
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index bb76be6e4fa857fd15801fab1e29a06809062fb2..63f1b0be1264d2910bbf379ef4991df72b3bd721 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -900,6 +900,14 @@ elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
if ((rel + 1) >= relend)
return FALSE;
+ /* Check transition from GD or LD access model.
+ lea foo@tlsgd/tlsld(%rip), %rdi
+ nop*
+ call __tls_get_addr
+ can transit to different access model. */
+
+ /* NACLHACK: we hope for the best and check nothing! */
+#if 0
if (r_type == R_X86_64_TLSGD)
{
/* Check transition from GD access model. Only
@@ -933,6 +941,7 @@ elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
if (op.i != ld.i)
return FALSE;
}
+#endif
r_symndx = ELF64_R_SYM (rel[1].r_info);
if (r_symndx < symtab_hdr->sh_info)
@@ -976,6 +985,7 @@ elf64_x86_64_check_tls_transition (bfd *abfd, asection *sec,
val = bfd_get_8 (abfd, contents + offset - 2);
if (val != 0x8b && val != 0x03)
return FALSE;
+#endif
val = bfd_get_8 (abfd, contents + offset - 1);
return (val & 0xc7) == 5;
@@ -1139,6 +1149,28 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
return TRUE;
}
+/* NACLHACK: add reference to __nacl_add_tp (or __nacl_read_tp) symbol. */
+static struct elf_link_hash_entry *
+nacl_add_tp_symbol (struct bfd_link_info *info, const char* name)
+{
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh = NULL;
+
+ if (!(_bfd_generic_link_add_one_symbol
+ (info, info->output_bfd, name, BSF_GLOBAL,
+ bfd_und_section_ptr, (bfd_vma) 0, NULL, TRUE,
+ FALSE, &bh)))
+ return NULL;
+
+ h = (struct elf_link_hash_entry *) bh;
+ h->needs_plt = 1;
+ h->plt.refcount += 1;
+ return h;
+}
+
+static struct elf_link_hash_entry *nacl_add_tp_entry = NULL;
+static struct elf_link_hash_entry *nacl_read_tp_entry = NULL;
+
/* Look through the relocs for a section during the first phase, and
calculate needed space in the global offset table, procedure
linkage table, and dynamic reloc sections. */
@@ -2660,6 +2692,9 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
+ /* NACLHACK: new variable for NACL rewrites. */
+ struct elf_link_hash_entry *h_subst = NULL;
+
BFD_ASSERT (is_x86_64_elf (input_bfd));
htab = elf64_x86_64_hash_table (info);
@@ -2726,6 +2761,27 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
h->root.u.def.section = sec;
}
}
+ else if (h_subst)
+ {
+ /* NACLHACK: Replace symbol to relocate.
+
+ This is somewhat hacky, as relies on not using r_symndx any more,
+ which is currently true for R_X86_64_PLT32 involved in NaCl TLS
+ code sequences.
+
+ Doing this in a more reliable way means either splitting this
+ glorious function or copy-pasting code that processes relocations
+ of interest. Any volunteers? */
+
+ bfd_boolean warned;
+
+ h = h_subst;
+ h_subst = NULL;
+
+ RELOC_FOR_GLOBAL_SYM_HASH (info, input_bfd, input_section, rel,
+ h, sec, relocation,
+ unresolved_reloc, warned);
+ }
else
{
bfd_boolean warned;
@@ -3380,6 +3436,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
contents + roff + 8);
/* Skip R_X86_64_PC32/R_X86_64_PLT32. */
rel++;
+#endif
continue;
}
else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
@@ -3628,6 +3685,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
contents + roff + 8);
/* Skip R_X86_64_PLT32. */
rel++;
+#endif
continue;
}
else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
@@ -3694,6 +3752,15 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (r_type != R_X86_64_TLSLD)
{
+ /* NACLHACK: use __nacl_add_tp instead of __tls_get_addr. */
+ /* Rewrite lea to nop. */
+ memcpy (contents + rel->r_offset - 3,
+ "\x0f\x1f\x80\x00\x00\x00\x00", 7);
+
+ /* Call __nacl_read_tp instead of __tls_get_addr. */
+ h_subst = nacl_read_tp_entry;
+#if 0
+ /* NACLHACK: Original LD->LE transition disabled. */
/* LD->LE transition:
leaq foo@tlsld(%rip), %rdi; call __tls_get_addr.
We change it into:
@@ -3704,6 +3771,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
"\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
/* Skip R_X86_64_PC32/R_X86_64_PLT32. */
rel++;
+#endif
continue;
}
« no previous file with comments | « bfd/elf32-i386.c ('k') | binutils/ar.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698