gold: Handle local IFUNC symbol for APLT
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 1 May 2020 15:53:47 +0000 (08:53 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 1 May 2020 15:59:32 +0000 (08:59 -0700)
Handle local IFUNC symbol for APLT like global IFUNC symbol.

PR gold/25872
* x86_64.cc (Output_data_plt_x86_64_bnd::do_address_for_local):
Handle local IFUNC symbol.
(Output_data_plt_x86_64_ibt::do_address_for_local): Likewise.

gold/ChangeLog
gold/x86_64.cc

index 4466f4d1dfad966f5e003800a99b42d29d2d4357..cc62a3e827573c6d048f96aadd67ea4b20e77cae 100644 (file)
@@ -1,3 +1,10 @@
+2020-05-01  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gold/25872
+       * x86_64.cc (Output_data_plt_x86_64_bnd::do_address_for_local):
+       Handle local IFUNC symbol.
+       (Output_data_plt_x86_64_ibt::do_address_for_local): Likewise.
+
 2020-03-19  Fangrui Song  <maskray@google.com>
 
     * options.h (General_options): Add --no-rosegment option.
index 8b6027e72c309ffa96f8364f4bb112d7b4c35e84..6219c8e306fffc4d7ccec2e85872d3264db552fa 100644 (file)
@@ -2086,7 +2086,12 @@ Output_data_plt_x86_64_bnd::do_address_for_local(const Relobj* object,
                                                 unsigned int r_sym)
 {
   // Convert the PLT offset into an APLT offset.
-  unsigned int plt_offset = ((object->local_plt_offset(r_sym) - plt_entry_size)
+  const Sized_relobj_file<64, false>* sized_relobj =
+    static_cast<const Sized_relobj_file<64, false>*>(object);
+  const Symbol_value<64>* psymval = sized_relobj->local_symbol(r_sym);
+  unsigned int plt_offset = ((object->local_plt_offset(r_sym)
+                             - (psymval->is_ifunc_symbol()
+                                ? 0 : plt_entry_size))
                             / (plt_entry_size / aplt_entry_size));
   return (this->address()
          + this->aplt_offset_
@@ -2260,7 +2265,12 @@ Output_data_plt_x86_64_ibt<size>::do_address_for_local(const Relobj* object,
                                                 unsigned int r_sym)
 {
   // Convert the PLT offset into an APLT offset.
-  unsigned int plt_offset = ((object->local_plt_offset(r_sym) - plt_entry_size)
+  const Sized_relobj_file<size, false>* sized_relobj =
+    static_cast<const Sized_relobj_file<size, false>*>(object);
+  const Symbol_value<size>* psymval = sized_relobj->local_symbol(r_sym);
+  unsigned int plt_offset = ((object->local_plt_offset(r_sym)
+                             - (psymval->is_ifunc_symbol()
+                                ? 0 : plt_entry_size))
                             / (plt_entry_size / aplt_entry_size));
   return (this->address()
          + this->aplt_offset_