This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
STT_GNU_IFUNC dependency on ELFOSABI_LINUX [Re: Add support for STT_GNU_IFUNC?]
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: Nick Clifton <nickc at redhat dot com>
- Cc: "H.J. Lu" <hjl dot tools at gmail dot com>, binutils at sourceware dot org, Ulrich Drepper <drepper at redhat dot com>, Mark Kettenis <mark dot kettenis at xs4all dot nl>
- Date: Mon, 15 Feb 2010 23:22:24 +0100
- Subject: STT_GNU_IFUNC dependency on ELFOSABI_LINUX [Re: Add support for STT_GNU_IFUNC?]
- References: <6dc9ffc80904200944v77680623i123be7edbda5f2d3@mail.gmail.com> <49ECA7B7.7040401@redhat.com> <6dc9ffc80904230847s581adc1h5bc7077d548c2995@mail.gmail.com> <49F9C7FB.4070102@redhat.com>
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