public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* RFC: PATCH: PR x86_64/584: Detect call on protected symbol
@ 2005-01-19 22:49 H. J. Lu
  2005-01-19 23:06 ` Jakub Jelinek
  0 siblings, 1 reply; 16+ messages in thread
From: H. J. Lu @ 2005-01-19 22:49 UTC (permalink / raw)
  To: binutils

X86_64 uses R_X86_64_PC32 for both branch and store/load. Linker
can't tell if a protected symbol reference is local or global just
by relocation. This patch disassembles the code to check for call.


H.J.
----
bfd/

2005-01-19  H.J. Lu  <hongjiu.lu@intel.com>

	PR 584
	* elf64-x86-64.c: Include "dis-asm.h" and "libiberty.h".
	(elf64_x86_64_disasm): New.
	(elf64_x86_64_relocate_section): Disassembly the instruction
	for R_X86_64_PC32 relocation on a protected function symbol
	when building shared library for call instruction.

ld/

2005-01-19  H.J. Lu  <hongjiu.lu@intel.com>

	PR 584
	* Makefile.am (BFDLIB): Change it to @BFDLIB@.
	(eelf_x86_64.c): Also depend on $(srcdir)/emultempl/needdisasm.em.
	(eelf_x86_64_fbsd.c): Likewise.

	* configure.in (BFDLIB): New. Substitute
	(TESTBFDLIB): Updated.

	* configure.tgt (need_opcodes): Set to "yes" for ELF/x86_64.

	* emulparams/elf_x86_64.sh (EXTRA_EM_FILE): Set to needdisasm.

	* emultempl/needdisasm.em: New.

	* Makefile.in: Regenerated.
	* configure: Likewise.

--- binutils/bfd/elf64-x86-64.c.prot	2005-01-11 09:10:28.000000000 -0800
+++ binutils/bfd/elf64-x86-64.c	2005-01-19 13:02:51.582973722 -0800
@@ -25,6 +25,16 @@
 #include "libbfd.h"
 #include "elf-bfd.h"
 
+/* Used to check which instruction R_X86_64_PC32 is used for.  */
+#include "dis-asm.h"
+#include "libiberty.h"
+
+extern void init_disassemble_info
+  (struct disassemble_info *, void *, fprintf_ftype) __attribute__((weak));
+extern void disassemble_init_for_target
+  (struct disassemble_info *) __attribute__((weak));
+extern disassembler_ftype disassembler (bfd *) __attribute__((weak));
+
 #include "elf/x86-64.h"
 
 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
@@ -1745,6 +1755,12 @@ tpoff (struct bfd_link_info *info, bfd_v
   return address - htab->tls_size - htab->tls_sec->vma;
 }
 
+static int
+elf64_x86_64_disasm (void)
+{
+  return 0;
+}
+
 /* Relocate an x86_64 ELF section.  */
 
 static bfd_boolean
@@ -1760,6 +1776,7 @@ elf64_x86_64_relocate_section (bfd *outp
   bfd_vma *local_got_offsets;
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
+  bfd_vma last_offset;
 
   if (info->relocatable)
     return TRUE;
@@ -1769,6 +1786,7 @@ elf64_x86_64_relocate_section (bfd *outp
   sym_hashes = elf_sym_hashes (input_bfd);
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
+  last_offset = 0;
   rel = relocs;
   relend = relocs + input_section->reloc_count;
   for (; rel < relend; rel++)
@@ -1952,13 +1970,72 @@ elf64_x86_64_relocate_section (bfd *outp
 	      && (input_section->flags & SEC_ALLOC) != 0
 	      && (input_section->flags & SEC_READONLY) != 0)
 	    {
-	      (*_bfd_error_handler)
-		(_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
-		 input_bfd,
-		 x86_64_elf_howto_table[r_type].name,
-		 (h) ? h->root.root.string : "a local symbol");
-	      bfd_set_error (bfd_error_bad_value);
-	      return FALSE;
+	      bfd_boolean call;
+	      int octets = -1;
+
+	      if (!init_disassemble_info)
+		call = FALSE;
+	      else if (h->def_regular
+		       && r_type == R_X86_64_PC32
+		       && h->type == STT_FUNC
+		       && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+		{
+		  static struct disassemble_info *dis;
+		  static disassembler_ftype dis_fn;
+		  bfd_vma offset;
+
+		  if (dis == NULL && init_disassemble_info)
+		    {
+		      dis = xmalloc (sizeof (*dis));
+		      init_disassemble_info (dis, NULL,
+					    (fprintf_ftype) elf64_x86_64_disasm);
+		      dis->flavour = bfd_get_flavour (input_bfd);
+		      dis->arch = bfd_get_arch (input_bfd);
+		      dis->mach = bfd_get_mach (input_bfd);
+		      dis->octets_per_byte = bfd_octets_per_byte (input_bfd);
+		      if (bfd_big_endian (input_bfd))
+			dis->display_endian = dis->endian = BFD_ENDIAN_BIG;
+		      else
+			dis->display_endian = dis->endian = BFD_ENDIAN_LITTLE;
+		      disassemble_init_for_target (dis);
+		      dis_fn = disassembler (input_bfd);
+		    }
+
+		  dis->buffer = contents;
+		  dis->buffer_vma = input_section->vma;
+		  dis->buffer_length = input_section->size;
+		  dis->section = input_section;
+
+		  for (offset = last_offset; offset < rel->r_offset;)
+		    {
+		      octets = (*dis_fn) (input_section->vma + offset,
+					  dis);
+		      if (octets < 0)
+			break;
+		      else
+			offset += octets / dis->octets_per_byte;
+		    }
+
+		  /* Check if the current instruction is call.  */
+		  if (octets > 0
+		      && *(contents + offset - octets) == 0xe8)
+		    call = TRUE;
+		  else
+		    call = FALSE;
+		}
+	      else
+		call = FALSE;
+
+	      if (! call)
+		{
+		  (*_bfd_error_handler)
+		    (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+		     input_bfd,
+		     x86_64_elf_howto_table[r_type].name,
+		     (h) ? h->root.root.string : "a local symbol");
+		  bfd_set_error (bfd_error_bad_value);
+		  return FALSE;
+		}
 	    }
 	  /* Fall through.  */
 
@@ -2454,6 +2531,11 @@ elf64_x86_64_relocate_section (bfd *outp
 	      return FALSE;
 	    }
 	}
+
+      if (last_offset == 0)
+	last_offset = rel->r_offset;
+      else if (rel->r_offset < last_offset)
+	last_offset = rel->r_offset;
     }
 
   return TRUE;
--- binutils/ld/Makefile.am.prot	2005-01-19 09:08:58.000000000 -0800
+++ binutils/ld/Makefile.am	2005-01-19 13:47:14.696641705 -0800
@@ -104,7 +104,7 @@ man_MANS = ld.1
 
 INCLUDES = -D_GNU_SOURCE -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) -I$(top_srcdir)/../intl -I../intl $(HDEFINES) $(CFLAGS) -DLOCALEDIR="\"$(datadir)/locale\""
 
-BFDLIB = ../bfd/libbfd.la
+BFDLIB = @BFDLIB@
 LIBIBERTY = ../libiberty/libiberty.a
 
 ALL_EMULATIONS = \
@@ -843,11 +843,13 @@ eelf_i386.c: $(srcdir)/emulparams/elf_i3
   $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_i386 "$(tdir_elf_i386)"
 eelf_x86_64.c: $(srcdir)/emulparams/elf_x86_64.sh \
-  $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+  $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/needdisasm.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_x86_64 "$(tdir_elf_x86_64)"
 eelf_x86_64_fbsd.c: $(srcdir)/emulparams/elf_x86_64_fbsd.sh \
   $(srcdir)/emulparams/elf_x86_64.sh \
-  $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+  $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/needdisasm.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_x86_64_fbsd "$(tdir_elf_x86_64_fbsd)"
 eelf_i386_be.c: $(srcdir)/emulparams/elf_i386_be.sh \
   $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
--- binutils/ld/configure.in.prot	2005-01-17 09:32:46.000000000 -0800
+++ binutils/ld/configure.in	2005-01-19 14:30:50.926558757 -0800
@@ -250,10 +250,26 @@ AC_SUBST(LIB_PATH)
 EMULATION_LIBPATH=$all_libpath
 AC_SUBST(EMULATION_LIBPATH)
 
+# do we need the opcodes library?
+case "${need_opcodes}" in
+yes)
+  BFDLIB="../bfd/libbfd.la ../opcodes/libopcodes.la"
+  if test x${enable_static} = xno; then
+    TESTBFDLIB="--rpath ../opcodes/.libs ../opcodes/.libs/libopcodes.so"
+  else
+    TESTBFDLIB="../opcodes/.libs/libopcodes.a"
+  fi
+  ;;
+*)
+  BFDLIB="../bfd/libbfd.la"
+  ;;
+esac
+AC_SUBST(BFDLIB)
+
 if test x${enable_static} = xno; then
-  TESTBFDLIB="--rpath ../bfd/.libs ../bfd/.libs/libbfd.so"
+  TESTBFDLIB="--rpath ../bfd/.libs ../bfd/.libs/libbfd.so $TESTBFDLIB"
 else
-  TESTBFDLIB="../bfd/.libs/libbfd.a"
+  TESTBFDLIB="../bfd/.libs/libbfd.a $TESTBFDLIB"
 fi
 AC_SUBST(TESTBFDLIB)
 
--- binutils/ld/configure.tgt.prot	2005-01-19 09:08:58.000000000 -0800
+++ binutils/ld/configure.tgt	2005-01-19 13:43:01.696239040 -0800
@@ -11,6 +11,9 @@
 #  targ_extra_ofiles	additional objects needed by the emulation
 #  NATIVE_LIB_DIRS	library directories to search on this host
 #			(if we are a native or sysrooted linker)
+#  need_opcodes		if libopcodes is needed.
+
+need_opcodes=no
 
 targ_extra_emuls=
 targ_extra_ofiles=
@@ -165,6 +168,7 @@ i[3-7]86-*-linux-gnu*)	targ_emul=elf_i38
 			targ_extra_emuls=i386linux
 			if test x${want64} = xtrue; then
 			  targ_extra_emuls="$targ_extra_emuls elf_x86_64"
+			  need_opcodes=yes
 			fi
 			tdir_i386linux=${targ_alias}aout
 			;;
@@ -173,10 +177,12 @@ x86_64-*-linux-gnu*)	targ_emul=elf_x86_6
 			targ_extra_libpath=elf_i386
 			tdir_i386linux=`echo ${targ_alias}aout | sed -e 's/x86_64/i386/'`
 			tdir_elf_i386=`echo ${targ_alias} | sed -e 's/x86_64/i386/'`
+			need_opcodes=yes
 			;;
 i[3-7]86-*-sysv[45]*)	targ_emul=elf_i386 ;;
 i[3-7]86-*-solaris2*)	targ_emul=elf_i386_ldso
                         targ_extra_emuls="elf_i386 elf_x86_64"
+			need_opcodes=yes
                         ;;
 i[3-7]86-*-unixware)	targ_emul=elf_i386 ;;
 i[3-7]86-*-solaris*)	targ_emul=elf_i386_ldso
@@ -205,6 +211,7 @@ x86_64-*-netbsd*)	targ_emul=elf_x86_64
 				    sed -e 's/netbsd/netbsdelf/'`
 				;;
 			esac
+			need_opcodes=yes
 			;;
 i[3-7]86-*-netware)	targ_emul=i386nw ;;
 i[3-7]86-*-elf*)	targ_emul=elf_i386 ;;
@@ -219,6 +226,7 @@ x86_64-*-freebsd* | x86_64-*-kfreebsd*-g
 			targ_extra_emuls="elf_i386_fbsd elf_x86_64 elf_i386"
 			tdir_elf_i386=`echo ${targ_alias} \
 			    | sed -e 's/x86_64/i386/'`
+			need_opcodes=yes
 			;;
 i[3-7]86-*-sysv*)	targ_emul=i386coff ;;
 i[3-7]86-*-ptx*)	targ_emul=i386coff ;;
--- binutils/ld/emulparams/elf_x86_64.sh.prot	2004-05-11 13:34:35.000000000 -0700
+++ binutils/ld/emulparams/elf_x86_64.sh	2005-01-19 13:30:54.792473055 -0800
@@ -13,6 +13,7 @@ GENERATE_SHLIB_SCRIPT=yes
 GENERATE_PIE_SCRIPT=yes
 NO_SMALL_DATA=yes
 SEPARATE_GOTPLT=24
+EXTRA_EM_FILE=needdisasm
 
 if [ "x${host}" = "x${target}" ]; then
   case " $EMULATION_LIBPATH " in
--- binutils/ld/emultempl/needdisasm.em.prot	2005-01-19 13:30:02.508198053 -0800
+++ binutils/ld/emultempl/needdisasm.em	2005-01-19 13:36:40.558345995 -0800
@@ -0,0 +1,34 @@
+# This shell script emits a C file. -*- C -*-
+#   Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of GLD, the Gnu Linker.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+# This file is sourced from elf32.em.  It is used by targets which
+# need disassembler.
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+#include "dis-asm.h"
+
+void (*disassembler_dummy []) (void) =
+{
+  (void (*) (void)) init_disassemble_info,
+  (void (*) (void)) disassemble_init_for_target,
+  (void (*) (void)) disassembler,
+};
+EOF

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-19 22:49 RFC: PATCH: PR x86_64/584: Detect call on protected symbol H. J. Lu
@ 2005-01-19 23:06 ` Jakub Jelinek
  2005-01-20  0:40   ` H. J. Lu
  0 siblings, 1 reply; 16+ messages in thread
From: Jakub Jelinek @ 2005-01-19 23:06 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Wed, Jan 19, 2005 at 02:48:34PM -0800, H. J. Lu wrote:
> X86_64 uses R_X86_64_PC32 for both branch and store/load. Linker
> can't tell if a protected symbol reference is local or global just
> by relocation. This patch disassembles the code to check for call.

Eh, why you need the disassembler there?
Isn't it enough just to check if R_X86_64_PC32's r_offset > 0 and
contents[r_offset - 1] == 0xe8?

	Jakub

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-19 23:06 ` Jakub Jelinek
@ 2005-01-20  0:40   ` H. J. Lu
  2005-01-20  0:51     ` H. J. Lu
  2005-01-20  1:55     ` Alan Modra
  0 siblings, 2 replies; 16+ messages in thread
From: H. J. Lu @ 2005-01-20  0:40 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: binutils

On Thu, Jan 20, 2005 at 12:05:44AM +0100, Jakub Jelinek wrote:
> On Wed, Jan 19, 2005 at 02:48:34PM -0800, H. J. Lu wrote:
> > X86_64 uses R_X86_64_PC32 for both branch and store/load. Linker
> > can't tell if a protected symbol reference is local or global just
> > by relocation. This patch disassembles the code to check for call.
> 
> Eh, why you need the disassembler there?
> Isn't it enough just to check if R_X86_64_PC32's r_offset > 0 and
> contents[r_offset - 1] == 0xe8?

Can we be sure that contents[r_offset - 1] == 0xe8 will be call?


H.J.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-20  0:40   ` H. J. Lu
@ 2005-01-20  0:51     ` H. J. Lu
  2005-01-20  1:55     ` Alan Modra
  1 sibling, 0 replies; 16+ messages in thread
From: H. J. Lu @ 2005-01-20  0:51 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: binutils

On Wed, Jan 19, 2005 at 04:40:32PM -0800, H. J. Lu wrote:
> On Thu, Jan 20, 2005 at 12:05:44AM +0100, Jakub Jelinek wrote:
> > On Wed, Jan 19, 2005 at 02:48:34PM -0800, H. J. Lu wrote:
> > > X86_64 uses R_X86_64_PC32 for both branch and store/load. Linker
> > > can't tell if a protected symbol reference is local or global just
> > > by relocation. This patch disassembles the code to check for call.
> > 
> > Eh, why you need the disassembler there?
> > Isn't it enough just to check if R_X86_64_PC32's r_offset > 0 and
> > contents[r_offset - 1] == 0xe8?
> 
> Can we be sure that contents[r_offset - 1] == 0xe8 will be call?
> 
> 

If we are, here is a patch.


H.J.
----
2005-01-19  H.J. Lu  <hongjiu.lu@intel.com>

	PR 584
	* elf64-x86-64.c (elf64_x86_64_relocate_section): Alllow
	R_X86_64_PC32 on a protected function symbol when building
	shared library for call instruction.

--- bfd/elf64-x86-64.c.prot	2005-01-11 09:10:28.000000000 -0800
+++ bfd/elf64-x86-64.c	2005-01-19 16:47:36.561055001 -0800
@@ -1950,7 +1950,12 @@ elf64_x86_64_relocate_section (bfd *outp
 	  if (info->shared
 	      && !SYMBOL_REFERENCES_LOCAL (info, h)
 	      && (input_section->flags & SEC_ALLOC) != 0
-	      && (input_section->flags & SEC_READONLY) != 0)
+	      && (input_section->flags & SEC_READONLY) != 0
+	      && (!h->def_regular
+		  || r_type != R_X86_64_PC32
+		  || h->type != STT_FUNC
+		  || ELF_ST_VISIBILITY (h->other) != STV_PROTECTED
+		  || contents [rel->r_offset - 1] != 0xe8))
 	    {
 	      (*_bfd_error_handler)
 		(_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-20  0:40   ` H. J. Lu
  2005-01-20  0:51     ` H. J. Lu
@ 2005-01-20  1:55     ` Alan Modra
  2005-01-20  3:17       ` H. J. Lu
  1 sibling, 1 reply; 16+ messages in thread
From: Alan Modra @ 2005-01-20  1:55 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Jakub Jelinek, binutils

On Wed, Jan 19, 2005 at 04:40:32PM -0800, H. J. Lu wrote:
> On Thu, Jan 20, 2005 at 12:05:44AM +0100, Jakub Jelinek wrote:
> > On Wed, Jan 19, 2005 at 02:48:34PM -0800, H. J. Lu wrote:
> > > X86_64 uses R_X86_64_PC32 for both branch and store/load. Linker
> > > can't tell if a protected symbol reference is local or global just
> > > by relocation. This patch disassembles the code to check for call.
> > 
> > Eh, why you need the disassembler there?
> > Isn't it enough just to check if R_X86_64_PC32's r_offset > 0 and
> > contents[r_offset - 1] == 0xe8?
> 
> Can we be sure that contents[r_offset - 1] == 0xe8 will be call?

Not if the PC32 reloc happens to be in data.  Also, I suspect some of
the possible load/store insns might have a sib byte of 0xE8.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-20  1:55     ` Alan Modra
@ 2005-01-20  3:17       ` H. J. Lu
  2005-01-20  4:22         ` Alan Modra
  0 siblings, 1 reply; 16+ messages in thread
From: H. J. Lu @ 2005-01-20  3:17 UTC (permalink / raw)
  To: Jakub Jelinek, binutils

On Thu, Jan 20, 2005 at 12:25:19PM +1030, Alan Modra wrote:
> On Wed, Jan 19, 2005 at 04:40:32PM -0800, H. J. Lu wrote:
> > On Thu, Jan 20, 2005 at 12:05:44AM +0100, Jakub Jelinek wrote:
> > > On Wed, Jan 19, 2005 at 02:48:34PM -0800, H. J. Lu wrote:
> > > > X86_64 uses R_X86_64_PC32 for both branch and store/load. Linker
> > > > can't tell if a protected symbol reference is local or global just
> > > > by relocation. This patch disassembles the code to check for call.
> > > 
> > > Eh, why you need the disassembler there?
> > > Isn't it enough just to check if R_X86_64_PC32's r_offset > 0 and
> > > contents[r_offset - 1] == 0xe8?
> > 
> > Can we be sure that contents[r_offset - 1] == 0xe8 will be call?
> 
> Not if the PC32 reloc happens to be in data.  Also, I suspect some of

We can check if the input section is executable. The worst case is that
you may get a runtime error instead of a linktime one.

> the possible load/store insns might have a sib byte of 0xE8.

I think 0xe8 SIB is [RAX + RIP * 8], which can't have R_X86_64_PC32.


H.J.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-20  3:17       ` H. J. Lu
@ 2005-01-20  4:22         ` Alan Modra
  2005-01-20  6:38           ` H. J. Lu
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Modra @ 2005-01-20  4:22 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Jakub Jelinek, binutils

On Wed, Jan 19, 2005 at 07:17:09PM -0800, H. J. Lu wrote:
> On Thu, Jan 20, 2005 at 12:25:19PM +1030, Alan Modra wrote:
> > On Wed, Jan 19, 2005 at 04:40:32PM -0800, H. J. Lu wrote:
> > > Can we be sure that contents[r_offset - 1] == 0xe8 will be call?
> > 
> > Not if the PC32 reloc happens to be in data.  Also, I suspect some of
> 
> We can check if the input section is executable. The worst case is that
> you may get a runtime error instead of a linktime one.
> 
> > the possible load/store insns might have a sib byte of 0xE8.
> 
> I think 0xe8 SIB is [RAX + RIP * 8], which can't have R_X86_64_PC32.

Ah, no disp field.  A modrm of 0xE8 won't have the PC32 reloc either.
So the only problem is when people put things like jump tables in .text.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-20  4:22         ` Alan Modra
@ 2005-01-20  6:38           ` H. J. Lu
  2005-01-20 10:19             ` Andreas Schwab
  0 siblings, 1 reply; 16+ messages in thread
From: H. J. Lu @ 2005-01-20  6:38 UTC (permalink / raw)
  To: Jakub Jelinek, binutils

On Thu, Jan 20, 2005 at 02:52:34PM +1030, Alan Modra wrote:
> On Wed, Jan 19, 2005 at 07:17:09PM -0800, H. J. Lu wrote:
> > On Thu, Jan 20, 2005 at 12:25:19PM +1030, Alan Modra wrote:
> > > On Wed, Jan 19, 2005 at 04:40:32PM -0800, H. J. Lu wrote:
> > > > Can we be sure that contents[r_offset - 1] == 0xe8 will be call?
> > > 
> > > Not if the PC32 reloc happens to be in data.  Also, I suspect some of
> > 
> > We can check if the input section is executable. The worst case is that
> > you may get a runtime error instead of a linktime one.
> > 
> > > the possible load/store insns might have a sib byte of 0xE8.
> > 
> > I think 0xe8 SIB is [RAX + RIP * 8], which can't have R_X86_64_PC32.
> 
> Ah, no disp field.  A modrm of 0xE8 won't have the PC32 reloc either.
> So the only problem is when people put things like jump tables in .text.

I don't think jump table uses R_X86_64_PC32. Does R_X86_64_PC32
only come from "branch label" or "insn label(%rip),xxx"? I don't
think we should worry about anything, like wrong insn, r_offset == 0,
jump table or data section.

H.J.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-20  6:38           ` H. J. Lu
@ 2005-01-20 10:19             ` Andreas Schwab
  2005-01-20 17:34               ` H. J. Lu
  0 siblings, 1 reply; 16+ messages in thread
From: Andreas Schwab @ 2005-01-20 10:19 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Jakub Jelinek, binutils

"H. J. Lu" <hjl@lucon.org> writes:

> I don't think we should worry about anything, like wrong insn, r_offset
> == 0, jump table or data section.

At least we shouldn't crash.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: RFC: PATCH: PR x86_64/584: Detect call on protected symbol
  2005-01-20 10:19             ` Andreas Schwab
@ 2005-01-20 17:34               ` H. J. Lu
  2005-01-24 23:26                 ` PATCH: Properly handle protected function for ia32 and x86_64 H. J. Lu
  0 siblings, 1 reply; 16+ messages in thread
From: H. J. Lu @ 2005-01-20 17:34 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jakub Jelinek, binutils

On Thu, Jan 20, 2005 at 11:17:55AM +0100, Andreas Schwab wrote:
> "H. J. Lu" <hjl@lucon.org> writes:
> 
> > I don't think we should worry about anything, like wrong insn, r_offset
> > == 0, jump table or data section.
> 
> At least we shouldn't crash.

How about this patch?


H.J.
----
2005-01-20  H.J. Lu  <hongjiu.lu@intel.com>

	PR 584
	* elf64-x86-64.c (is_32bit_relative_branch): New.
	(elf64_x86_64_relocate_section): Alllow R_X86_64_PC32 on a
	protected function symbol when building shared library for
	32bit relative branch instruction.

--- bfd/elf64-x86-64.c.prot	2005-01-11 09:10:28.000000000 -0800
+++ bfd/elf64-x86-64.c	2005-01-20 09:31:25.100049886 -0800
@@ -1745,6 +1745,24 @@ tpoff (struct bfd_link_info *info, bfd_v
   return address - htab->tls_size - htab->tls_sec->vma;
 }
 
+/* Is the instruction before OFFSET in CONTENTS a 32bit relative
+   branch?  */
+
+static bfd_boolean
+is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
+{
+  /* Opcode		Instruction
+     0xe8		call
+     0xe9		jump
+     0x0f 0x8x		conditional jump */
+  return ((offset > 0
+	   && (contents [offset - 1] == 0xe8
+	       || contents [offset - 1] == 0xe9))
+	  || (offset > 1
+	      && contents [offset - 2] == 0x0f
+	      && (contents [offset - 1] & 0xf0) == 0x80));
+}
+
 /* Relocate an x86_64 ELF section.  */
 
 static bfd_boolean
@@ -1950,7 +1968,12 @@ elf64_x86_64_relocate_section (bfd *outp
 	  if (info->shared
 	      && !SYMBOL_REFERENCES_LOCAL (info, h)
 	      && (input_section->flags & SEC_ALLOC) != 0
-	      && (input_section->flags & SEC_READONLY) != 0)
+	      && (input_section->flags & SEC_READONLY) != 0
+	      && (!h->def_regular
+		  || r_type != R_X86_64_PC32
+		  || h->type != STT_FUNC
+		  || ELF_ST_VISIBILITY (h->other) != STV_PROTECTED
+		  || !is_32bit_relative_branch (contents, rel->r_offset)))
 	    {
 	      (*_bfd_error_handler)
 		(_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),

^ permalink raw reply	[flat|nested] 16+ messages in thread

* PATCH: Properly handle protected function for ia32 and x86_64
  2005-01-20 17:34               ` H. J. Lu
@ 2005-01-24 23:26                 ` H. J. Lu
  2005-01-30 10:22                   ` Andreas Jaeger
  0 siblings, 1 reply; 16+ messages in thread
From: H. J. Lu @ 2005-01-24 23:26 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jakub Jelinek, binutils

On Thu, Jan 20, 2005 at 09:33:54AM -0800, H. J. Lu wrote:
> On Thu, Jan 20, 2005 at 11:17:55AM +0100, Andreas Schwab wrote:
> > "H. J. Lu" <hjl@lucon.org> writes:
> > 
> > > I don't think we should worry about anything, like wrong insn, r_offset
> > > == 0, jump table or data section.
> > 
> > At least we shouldn't crash.
> 
> How about this patch?
> 
> 

I updated the patch to make ia32 and x86_64 the same in dealing with
protected function symbols. On ia32, I disallow R_386_GOTOFF on
protected function and on x86_64, I allow 32bit relative branch on
protected function. Since we only warn global symbols, there is no
need to check if h is NULL. Also I updated error message.


H.J.
----
2005-01-24  H.J. Lu  <hongjiu.lu@intel.com>

	* elf32-i386.c (elf_i386_relocate_section): Disallow R_386_GOTOFF
	against protected function when building shared library.

	PR 584
	* elf64-x86-64.c (is_32bit_relative_branch): New.
	(elf64_x86_64_relocate_section): Alllow R_X86_64_PC32 on a
	protected function symbol when building shared library for
	32bit relative branch instruction.

--- bfd/elf32-i386.c.prot	2005-01-11 09:09:27.000000000 -0800
+++ bfd/elf32-i386.c	2005-01-24 12:52:26.233408808 -0800
@@ -2274,6 +2274,22 @@ elf_i386_relocate_section (bfd *output_b
 	  /* Relocation is relative to the start of the global offset
 	     table.  */
 
+	  /* Check to make sure it isn't a protected function symbol
+	     for shared library since it may not be local when used
+	     as function address.  */
+	  if (info->shared
+	      && h
+	      && h->def_regular
+	      && h->type == STT_FUNC
+	      && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+	    {
+	      (*_bfd_error_handler)
+		(_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"),
+		 input_bfd, h->root.root.string);
+	      bfd_set_error (bfd_error_bad_value);
+	      return FALSE;
+	    }
+
 	  /* Note that sgot is not involved in this
 	     calculation.  We always want the start of .got.plt.  If we
 	     defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
--- bfd/elf64-x86-64.c.prot	2005-01-11 09:10:28.000000000 -0800
+++ bfd/elf64-x86-64.c	2005-01-24 13:08:28.622633929 -0800
@@ -1745,6 +1745,24 @@ tpoff (struct bfd_link_info *info, bfd_v
   return address - htab->tls_size - htab->tls_sec->vma;
 }
 
+/* Is the instruction before OFFSET in CONTENTS a 32bit relative
+   branch?  */
+
+static bfd_boolean
+is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
+{
+  /* Opcode		Instruction
+     0xe8		call
+     0xe9		jump
+     0x0f 0x8x		conditional jump */
+  return ((offset > 0
+	   && (contents [offset - 1] == 0xe8
+	       || contents [offset - 1] == 0xe9))
+	  || (offset > 1
+	      && contents [offset - 2] == 0x0f
+	      && (contents [offset - 1] & 0xf0) == 0x80));
+}
+
 /* Relocate an x86_64 ELF section.  */
 
 static bfd_boolean
@@ -1950,13 +1968,26 @@ elf64_x86_64_relocate_section (bfd *outp
 	  if (info->shared
 	      && !SYMBOL_REFERENCES_LOCAL (info, h)
 	      && (input_section->flags & SEC_ALLOC) != 0
-	      && (input_section->flags & SEC_READONLY) != 0)
+	      && (input_section->flags & SEC_READONLY) != 0
+	      && (!h->def_regular
+		  || r_type != R_X86_64_PC32
+		  || h->type != STT_FUNC
+		  || ELF_ST_VISIBILITY (h->other) != STV_PROTECTED
+		  || !is_32bit_relative_branch (contents,
+						rel->r_offset)))
 	    {
-	      (*_bfd_error_handler)
-		(_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
-		 input_bfd,
-		 x86_64_elf_howto_table[r_type].name,
-		 (h) ? h->root.root.string : "a local symbol");
+	      if (h->def_regular
+		  && r_type == R_X86_64_PC32
+		  && h->type == STT_FUNC
+		  && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
+		(*_bfd_error_handler)
+		   (_("%B: relocation R_X86_64_PC32 against protected function `%s' can not be used when making a shared object"),
+		    input_bfd, h->root.root.string);
+	      else
+		(*_bfd_error_handler)
+		  (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
+		   input_bfd, x86_64_elf_howto_table[r_type].name,
+		   h->root.root.string);
 	      bfd_set_error (bfd_error_bad_value);
 	      return FALSE;
 	    }

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PATCH: Properly handle protected function for ia32 and x86_64
  2005-01-24 23:26                 ` PATCH: Properly handle protected function for ia32 and x86_64 H. J. Lu
@ 2005-01-30 10:22                   ` Andreas Jaeger
  2005-02-01  4:51                     ` Alan Modra
  0 siblings, 1 reply; 16+ messages in thread
From: Andreas Jaeger @ 2005-01-30 10:22 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Andreas Schwab, Jakub Jelinek, binutils

[-- Attachment #1: Type: text/plain, Size: 1638 bytes --]

"H. J. Lu" <hjl@lucon.org> writes:

> On Thu, Jan 20, 2005 at 09:33:54AM -0800, H. J. Lu wrote:
>> On Thu, Jan 20, 2005 at 11:17:55AM +0100, Andreas Schwab wrote:
>> > "H. J. Lu" <hjl@lucon.org> writes:
>> > 
>> > > I don't think we should worry about anything, like wrong insn, r_offset
>> > > == 0, jump table or data section.
>> > 
>> > At least we shouldn't crash.
>> 
>> How about this patch?
>> 
>> 
>
> I updated the patch to make ia32 and x86_64 the same in dealing with
> protected function symbols. On ia32, I disallow R_386_GOTOFF on
> protected function and on x86_64, I allow 32bit relative branch on
> protected function. Since we only warn global symbols, there is no
> need to check if h is NULL. Also I updated error message.
>
>
> H.J.
> ----
> 2005-01-24  H.J. Lu  <hongjiu.lu@intel.com>
>
> 	* elf32-i386.c (elf_i386_relocate_section): Disallow R_386_GOTOFF
> 	against protected function when building shared library.
>
> 	PR 584
> 	* elf64-x86-64.c (is_32bit_relative_branch): New.
> 	(elf64_x86_64_relocate_section): Alllow R_X86_64_PC32 on a
> 	protected function symbol when building shared library for
> 	32bit relative branch instruction.

I guess this bug is the reason for this one:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19664

I approve the x86-64 part of the patch but would suggest that you wait
another day for comments before checking in,

thanks,
Andreas
-- 
 Andreas Jaeger, aj@suse.de, http://www.suse.de/~aj
  SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
   GPG fingerprint = 93A3 365E CE47 B889 DF7F  FED1 389A 563C C272 A126

[-- Attachment #2: Type: application/pgp-signature, Size: 188 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PATCH: Properly handle protected function for ia32 and x86_64
  2005-01-30 10:22                   ` Andreas Jaeger
@ 2005-02-01  4:51                     ` Alan Modra
  2005-02-01  5:50                       ` H. J. Lu
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Modra @ 2005-02-01  4:51 UTC (permalink / raw)
  To: Andreas Jaeger; +Cc: H. J. Lu, Andreas Schwab, Jakub Jelinek, binutils

On Sun, Jan 30, 2005 at 11:22:29AM +0100, Andreas Jaeger wrote:
> "H. J. Lu" <hjl@lucon.org> writes:
> > 	* elf32-i386.c (elf_i386_relocate_section): Disallow R_386_GOTOFF
> > 	against protected function when building shared library.
> >
> > 	PR 584
> > 	* elf64-x86-64.c (is_32bit_relative_branch): New.
> > 	(elf64_x86_64_relocate_section): Alllow R_X86_64_PC32 on a
> > 	protected function symbol when building shared library for
> > 	32bit relative branch instruction.
> 
> I approve the x86-64 part of the patch but would suggest that you wait
> another day for comments before checking in,

I'm not happy with the i386 one, because conceptually there isn't any
reason why the GOT of a shared library can't contain an entry for a
protected symbol.  I believe such a shared lib will work properly, so it
isn't appropriate to issue an error.  The problem occurs when an
executable tries to reference such a symbol, and copy relocs are
involved.

I think you should *warn* that a shared library built with protected
data symbols may result in non-shared text pages for apps linked against
the lib, and force elimination of the copy reloc when building apps
against such libs.  Another issue is whether seeing a GOTOFF reloc
against a protected symbol is a sufficient indicator of a problematic
shared lib.  ie. Perhaps there are other relocs used when different code
sequences in a shared lib access the lib's protected data.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PATCH: Properly handle protected function for ia32 and x86_64
  2005-02-01  4:51                     ` Alan Modra
@ 2005-02-01  5:50                       ` H. J. Lu
  2005-02-01  7:44                         ` Alan Modra
  0 siblings, 1 reply; 16+ messages in thread
From: H. J. Lu @ 2005-02-01  5:50 UTC (permalink / raw)
  To: Andreas Jaeger, Andreas Schwab, Jakub Jelinek, binutils

On Tue, Feb 01, 2005 at 03:21:10PM +1030, Alan Modra wrote:
> On Sun, Jan 30, 2005 at 11:22:29AM +0100, Andreas Jaeger wrote:
> > "H. J. Lu" <hjl@lucon.org> writes:
> > > 	* elf32-i386.c (elf_i386_relocate_section): Disallow R_386_GOTOFF
> > > 	against protected function when building shared library.
> > >
> > > 	PR 584
> > > 	* elf64-x86-64.c (is_32bit_relative_branch): New.
> > > 	(elf64_x86_64_relocate_section): Alllow R_X86_64_PC32 on a
> > > 	protected function symbol when building shared library for
> > > 	32bit relative branch instruction.
> > 
> > I approve the x86-64 part of the patch but would suggest that you wait
> > another day for comments before checking in,
> 
> I'm not happy with the i386 one, because conceptually there isn't any
> reason why the GOT of a shared library can't contain an entry for a
> protected symbol.  I believe such a shared lib will work properly, so it
> isn't appropriate to issue an error.  The problem occurs when an
> executable tries to reference such a symbol, and copy relocs are
> involved.

Please check it again. It is R_386_GOTOFF against protected FUNCTION
symbol. It has nothing to do with copy relocation. It is the function
pointer problem with protected function.

> 
> I think you should *warn* that a shared library built with protected
> data symbols may result in non-shared text pages for apps linked against
> the lib, and force elimination of the copy reloc when building apps
> against such libs.  Another issue is whether seeing a GOTOFF reloc
> against a protected symbol is a sufficient indicator of a problematic
> shared lib.  ie. Perhaps there are other relocs used when different code
> sequences in a shared lib access the lib's protected data.
> 

What you described is my proposal:

http://sources.redhat.com/ml/binutils/2005-01/msg00349.html

I will implement it when I find time.


H.J.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PATCH: Properly handle protected function for ia32 and x86_64
  2005-02-01  5:50                       ` H. J. Lu
@ 2005-02-01  7:44                         ` Alan Modra
  2005-02-01 15:23                           ` H. J. Lu
  0 siblings, 1 reply; 16+ messages in thread
From: Alan Modra @ 2005-02-01  7:44 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Andreas Jaeger, Andreas Schwab, Jakub Jelinek, binutils

On Mon, Jan 31, 2005 at 09:50:18PM -0800, H. J. Lu wrote:
> On Tue, Feb 01, 2005 at 03:21:10PM +1030, Alan Modra wrote:
> > I'm not happy with the i386 one, because conceptually there isn't any
> > reason why the GOT of a shared library can't contain an entry for a
> > protected symbol.  I believe such a shared lib will work properly, so it
> > isn't appropriate to issue an error.  The problem occurs when an
> > executable tries to reference such a symbol, and copy relocs are
> > involved.
> 
> Please check it again. It is R_386_GOTOFF against protected FUNCTION
> symbol. It has nothing to do with copy relocation. It is the function
> pointer problem with protected function.

OK, I misunderstood the problem.  Do you have a testcase?

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: PATCH: Properly handle protected function for ia32 and x86_64
  2005-02-01  7:44                         ` Alan Modra
@ 2005-02-01 15:23                           ` H. J. Lu
  0 siblings, 0 replies; 16+ messages in thread
From: H. J. Lu @ 2005-02-01 15:23 UTC (permalink / raw)
  To: Andreas Jaeger, Andreas Schwab, Jakub Jelinek, binutils

On Tue, Feb 01, 2005 at 06:14:21PM +1030, Alan Modra wrote:
> On Mon, Jan 31, 2005 at 09:50:18PM -0800, H. J. Lu wrote:
> > On Tue, Feb 01, 2005 at 03:21:10PM +1030, Alan Modra wrote:
> > > I'm not happy with the i386 one, because conceptually there isn't any
> > > reason why the GOT of a shared library can't contain an entry for a
> > > protected symbol.  I believe such a shared lib will work properly, so it
> > > isn't appropriate to issue an error.  The problem occurs when an
> > > executable tries to reference such a symbol, and copy relocs are
> > > involved.
> > 
> > Please check it again. It is R_386_GOTOFF against protected FUNCTION
> > symbol. It has nothing to do with copy relocation. It is the function
> > pointer problem with protected function.
> 
> OK, I misunderstood the problem.  Do you have a testcase?
> 

There is a testcase in

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19520



H.J.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2005-02-01 15:23 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-19 22:49 RFC: PATCH: PR x86_64/584: Detect call on protected symbol H. J. Lu
2005-01-19 23:06 ` Jakub Jelinek
2005-01-20  0:40   ` H. J. Lu
2005-01-20  0:51     ` H. J. Lu
2005-01-20  1:55     ` Alan Modra
2005-01-20  3:17       ` H. J. Lu
2005-01-20  4:22         ` Alan Modra
2005-01-20  6:38           ` H. J. Lu
2005-01-20 10:19             ` Andreas Schwab
2005-01-20 17:34               ` H. J. Lu
2005-01-24 23:26                 ` PATCH: Properly handle protected function for ia32 and x86_64 H. J. Lu
2005-01-30 10:22                   ` Andreas Jaeger
2005-02-01  4:51                     ` Alan Modra
2005-02-01  5:50                       ` H. J. Lu
2005-02-01  7:44                         ` Alan Modra
2005-02-01 15:23                           ` H. J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).