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]

STT_GNU_IFUNC dependency on ELFOSABI_LINUX [Re: Add support for STT_GNU_IFUNC?]


Hi Nick,

On Thu, 30 Apr 2009 17:47:07 +0200, Nick Clifton wrote:
> OK - I have checked in the attached patch.  I am still not happy
> with it, but at least it is a starting point.

> *** bfd/elfcode.h	23 Dec 2008 09:01:45 -0000	1.93
> --- bfd/elfcode.h	30 Apr 2009 14:00:26 -0000
> *************** elf_slurp_symbol_table (bfd *abfd, asymb
> *** 1311,1316 ****
> --- 1311,1319 ----
>   	    case STT_SRELC:
>   	      sym->symbol.flags |= BSF_SRELC;
>   	      break;
> + 	    case STT_GNU_IFUNC:
> + 	      sym->symbol.flags |= BSF_GNU_INDIRECT_FUNCTION;
> + 	      break;
>   	    }

this means BSF_GNU_INDIRECT_FUNCTION is set for STT_GNU_IFUNC present in any
OS/ABI despite STT_GNU_IFUNC is in the STT_LOOS..STT_HIOS range.

Mark Kettenis moreover defends STT_GNU_IFUNC should be recognized as valid not
only for GNU (Linux) but also at least for BSD and Solaris.  In his words:
	http://sourceware.org/ml/gdb-patches/2010-02/msg00355.html

If it is really only a GNU/Linux type then is the attached patch approved?

No regressions on {x86_64,i686}-fedora12-linux-gnu.

The testcase is ugly and may be dropped, moreover it does not test the code
fix as binutils/readelf.c already contains:
	if (type == STT_GNU_IFUNC
	    && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
		/* GNU/Linux is still using the default value 0.  */
		|| elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
	  return "IFUNC";
	snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);


A bit offtopic question - does it make sense to recognize IFUNCs in
ELFOSABI_NONE?  Removal of the ELFOSABI_NONE check would not be
straightforward as it has regressions, though.  Also ET_REL files currently
still have ELFOSABI_NONE set while they contain IFUNC symbols, ELFOSABI_LINUX
gets set only for final ET_DYN.  (It seems to me the current allowance of
ELFOSABI_NONE for IFUNCs is a workaround for existing binutils/bfd code.)


Thanks,
Jan


bfd/
2010-02-15  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* elfcode.h (elf_slurp_symbol_table) <STT_GNU_IFUNC>: Verify ELF_OSABI.

gas/testsuite/
2010-02-15  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gas/elf/elf.exp (run_elf_list_test): New parameter hook.  Call it.
	(set ELFOSABI_NONE, elf type-invalidifunc list): New.
	* gas/elf/type-invalidifunc.s, gas/elf/type-invalidifunc.e: New.

--- bfd/elfcode.h
+++ bfd/elfcode.h
@@ -1347,7 +1347,10 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
 	      sym->symbol.flags |= BSF_SRELC;
 	      break;
 	    case STT_GNU_IFUNC:
-	      sym->symbol.flags |= BSF_GNU_INDIRECT_FUNCTION;
+	      if (ebd->elf_osabi == ELFOSABI_LINUX
+		  /* GNU/Linux is still using the default value 0.  */
+		  || ebd->elf_osabi == ELFOSABI_NONE)
+		sym->symbol.flags |= BSF_GNU_INDIRECT_FUNCTION;
 	      break;
 	    }
 
--- gas/testsuite/gas/elf/elf.exp
+++ gas/testsuite/gas/elf/elf.exp
@@ -2,7 +2,7 @@
 # elf tests
 #
 
-proc run_elf_list_test { name suffix opts readelf_opts readelf_pipe } {
+proc run_elf_list_test { name suffix opts readelf_opts readelf_pipe {hook {} } } {
     global READELF
     global srcdir subdir
     set testname "elf $name list"
@@ -14,6 +14,7 @@ proc run_elf_list_test { name suffix opts readelf_opts readelf_pipe } {
 	verbose "output is [file_contents "dump.out"]" 2
 	return
     }
+    eval $hook
     send_log "$READELF $readelf_opts dump.o $readelf_pipe > dump.out\n"
     set status [gas_host_run "$READELF $readelf_opts dump.o" ">readelf.out"]
     if { [lindex $status 0] != 0 || ![string match "" [lindex $status 1]] } then {
@@ -152,7 +153,29 @@ if { ([istarget "*-*-*elf*"]
 	    run_elf_list_test "type-noifunc" "" "" "-s" "| grep \"1 *\\\[FONTC\\\]\""
     } else {
     	    run_dump_test ifunc-1
-	    run_elf_list_test "type" "" "" "-s" "| grep \"1 *\\\[FIONTCU\\\]\""
+	    run_elf_list_test "type" "" "" "-s" "| grep \"1 *\\\[FIONTCU<\\\]\""
+
+	    run_elf_list_test "type-invalidifunc" "" "" "-s" "| grep \"1 *\\\[FIONTCU<\\\]\"" {
+		set test "set ELFOSABI_NONE"
+		set fi [open "dump.o" r+]
+		fconfigure $fi -translation binary
+		if {[read $fi 4] != "\177ELF"} {
+		    fail $test
+		} else {
+		    seek $fi 7
+		    set osabi [read $fi 1]
+		    # GNU/Linux is still using the default value 0.
+		    if {$osabi != "\003" && $osabi != "\000"} {
+			fail $test
+		    } else {
+			seek $fi 7
+			# ELFOSABI_STANDALONE
+			puts -nonewline $fi "\377"
+			pass $test
+		    }
+		}
+		close $fi
+	    }
     }
 
     run_dump_test "section6" 
--- /dev/null
+++ gas/testsuite/gas/elf/type-invalidifunc.e
@@ -0,0 +1 @@
+ +.: 0+ +1 +<OS specific>: 10 +LOCAL +DEFAULT +. indirect_function
--- /dev/null
+++ gas/testsuite/gas/elf/type-invalidifunc.s
@@ -0,0 +1,6 @@
+	.text
+
+	.size	indirect_function,1
+	.type	indirect_function,%gnu_indirect_function
+indirect_function:
+	.byte	0x0


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