This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Patch: Support toc relative access to dynamic symbols from static code.


On Tue, Nov 17, 2015 at 7:28 PM, Alan Modra <amodra@gmail.com> wrote:
> On Wed, Nov 18, 2015 at 01:37:50PM +1030, Alan Modra wrote:
>> On Tue, Nov 17, 2015 at 04:52:41PM -0800, Kyle Butt wrote:
>> > This patch allows TOC16_* relocations to reference external global
>> > symbols. Previously llvm was not emitting such accesses, but they are
>> > allowed by the abi.
>>
>> Huh?  The patch does nothing, besides making the source ugly.
>
> I take that back.  I'm not used to seeing switch statements without
> braces..

Sorry about that. I've attached an updated patch.

>However, I still don't like the idea of emitting dynamic
> R_PPC64_TOC16* relocs, if that is what you're trying to do.  That
> doesn't make sense at all since those relocs are not handled by
> glibc's ld.so.  It also doesn't make sense to emit plt entries or copy
> relocs for them.

They don't get emitted as dynamic relocations.

It does make sense to emit copy relocations for them, and plt entries.
Consider the two following sequences:

addis r3, r2, LC0@toc@ha
ld r3, LC0@toc@l(r3)

addis r3, r2, sym@toc@ha
addi r3, r3, sym@toc@l

At the end of both, r3 contains the value of sym, and so if it is a
function it needs a plt entry, just as if it was loaded from the toc.
If the reference is to data, a copy relocation is exactly what is
needed. A copy relocation would fix the second sequence whenever a
regular relocation would fix the first.

> --
> Alan Modra
> Australia Development Lab, IBM
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 3a013ef..7e330c3 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -6036,10 +6036,29 @@ Target_powerpc<size, big_endian>::Scan::global(
     case elfcpp::R_PPC64_ADDR16_HIGHESTA:
     case elfcpp::R_PPC64_ADDR16_DS:
     case elfcpp::R_PPC64_ADDR16_LO_DS:
+    case elfcpp::R_PPC64_TOC16:
+    case elfcpp::R_PPC64_TOC16_LO:
+    case elfcpp::R_PPC64_TOC16_HI:
+    case elfcpp::R_PPC64_TOC16_HA:
+    case elfcpp::R_PPC64_TOC16_DS:
+    case elfcpp::R_PPC64_TOC16_LO_DS:
     case elfcpp::R_POWERPC_ADDR14:
     case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
     case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
       {
+	// The toc-relative relocations need a GOT section
+	switch (r_type)
+	  {
+	  case elfcpp::R_PPC64_TOC16:
+	  case elfcpp::R_PPC64_TOC16_LO:
+	  case elfcpp::R_PPC64_TOC16_HI:
+	  case elfcpp::R_PPC64_TOC16_HA:
+	  case elfcpp::R_PPC64_TOC16_DS:
+	  case elfcpp::R_PPC64_TOC16_LO_DS:
+	    target->got_section(symtab, layout);
+	    break;
+	  }
+
 	// Make a PLT entry if necessary.
 	if (gsym->needs_plt_entry())
 	  {
@@ -6248,16 +6265,6 @@ Target_powerpc<size, big_endian>::Scan::global(
       }
       break;
 
-    case elfcpp::R_PPC64_TOC16:
-    case elfcpp::R_PPC64_TOC16_LO:
-    case elfcpp::R_PPC64_TOC16_HI:
-    case elfcpp::R_PPC64_TOC16_HA:
-    case elfcpp::R_PPC64_TOC16_DS:
-    case elfcpp::R_PPC64_TOC16_LO_DS:
-      // We need a GOT section.
-      target->got_section(symtab, layout);
-      break;
-
     case elfcpp::R_POWERPC_GOT_TLSGD16:
     case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
     case elfcpp::R_POWERPC_GOT_TLSGD16_HI:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]