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] PR gold/17729: [gold] gold failed to build x32 libgo


> +  if (size == 32)
> +    {
> +      // For X32
> +      // cmp %fs:NN,%esp
> +      cmp_insn = "\x64\x3b\x24\x25";
> +      cmp_insn_len = 4;
> +      // lea NN(%rsp),%r10d
> +      // lea NN(%rsp),%r11d
> +      lea_r10_insn = "\x44\x8d\x94\x24";
> +      lea_r11_insn = "\x44\x8d\x9c\x24";
> +      nop_insn_len = 7;
> +    }
> ...

The rest of this patch is OK, but in do_calls_non_split(), I'd prefer
something like this (note also the depedency between nop_size and the
test against fnsize for the cmp instruction):

--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -4457,6 +4457,14 @@ Target_x86_64<size>::do_ehframe_datarel_base() const
 // code.  We have to change the function so that it always ensures
 // that it has enough stack space to run some random function.

+static const unsigned char cmp_insn_32[] = { 0x64, 0x3b, 0x24, 0x25 };
+static const unsigned char lea_r10_insn_32[] = { 0x44, 0x8d, 0x94, 0x24 };
+static const unsigned char lea_r11_insn_32[] = { 0x44, 0x8d, 0x9c, 0x24 };
+
+static const unsigned char cmp_insn_64[] = { 0x64, 0x48, 0x3b, 0x24, 0x25 };
+static const unsigned char lea_r10_insn_64[] = { 0x4c, 0x8d, 0x94, 0x24 };
+static const unsigned char lea_r11_insn_64[] = { 0x4c, 0x8d, 0x9c, 0x24 };
+
 template<int size>
 void
 Target_x86_64<size>::do_calls_non_split(Relobj* object, unsigned int shndx,
@@ -4467,25 +4475,40 @@
Target_x86_64<size>::do_calls_non_split(Relobj* object, unsigned int
shndx,
                                        std::string* from,
                                        std::string* to) const
 {
+  const char* const cmp_insn = reinterpret_cast<const char*>
+      (size == 32 ? cmp_insn_32 : cmp_insn_64);
+  const char* const lea_r10_insn = reinterpret_cast<const char*>
+      (size == 32 ? lea_r10_insn_32 : lea_r10_insn_64);
+  const char* const lea_r11_insn = reinterpret_cast<const char*>
+      (size == 32 ? lea_r11_insn_32 : lea_r11_insn_64);
+
+  const size_t cmp_insn_len =
+      (size == 32 ? sizeof(cmp_insn_32) : sizeof(cmp_insn_64));
+  const size_t lea_r10_insn_len =
+      (size == 32 ? sizeof(lea_r10_insn_32) : sizeof(lea_r10_insn_64));
+  const size_t lea_r11_insn_len =
+      (size == 32 ? sizeof(lea_r11_insn_32) : sizeof(lea_r11_insn_64));
+  const size_t nop_len = (size == 32 ? 7 : 8);
+
   // The function starts with a comparison of the stack pointer and a
   // field in the TCB.  This is followed by a jump.

   // cmp %fs:NN,%rsp
-  if (this->match_view(view, view_size, fnoffset, "\x64\x48\x3b\x24\x25", 5)
-      && fnsize > 9)
+  if (this->match_view(view, view_size, fnoffset, cmp_insn, cmp_insn_len)
+      && fnsize > nop_len + 1)
     {
       // We will call __morestack if the carry flag is set after this
       // comparison.  We turn the comparison into an stc instruction
       // and some nops.
       view[fnoffset] = '\xf9';
-      this->set_view_to_nop(view, view_size, fnoffset + 1, 8);
+      this->set_view_to_nop(view, view_size, fnoffset + 1, nop_len);
     }
   // lea NN(%rsp),%r10
   // lea NN(%rsp),%r11
   else if ((this->match_view(view, view_size, fnoffset,
-                            "\x4c\x8d\x94\x24", 4)
+                            lea_r10_insn, lea_r10_insn_len)
            || this->match_view(view, view_size, fnoffset,
-                               "\x4c\x8d\x9c\x24", 4))
+                               lea_r11_insn, lea_r11_insn_len))
           && fnsize > 8)
     {
       // This is loading an offset from the stack pointer for a


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