Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/outfmt.src
Original file line number Diff line number Diff line change
Expand Up @@ -1415,6 +1415,15 @@ Declaring the type and size of global symbols is necessary when
writing shared library code. For more information, see
\k{picglobal}.

NASM supports the GNU indirect function symbol type using the keyword
\c{gnu_ifunc}. This marks the symbol as \c{STT_GNU_IFUNC} and causes the
dynamic loader to call the symbol as a resolver at runtime. For example:

\c global func_ifunc:function
\c
\c global func:gnu_ifunc
\c func equ func_ifunc


\S{elfextrn} \c{elf} Extensions to the \c{EXTERN} Directive\I{EXTERN,
elf extensions to}\I{EXTERN, elf extensions to}
Expand Down
1 change: 1 addition & 0 deletions output/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@
#define STT_COMMON 5 /* Symbol is a common data object */
#define STT_TLS 6 /* Symbol is thread-local data object */
#define STT_NUM 7 /* Number of defined types */
#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */

/* Symbol visibilities */
#define STV_DEFAULT 0 /* Default symbol visibility rules */
Expand Down
2 changes: 2 additions & 0 deletions output/outelf.c
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,8 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset,
case 9:
if (!nasm_strnicmp(spcword, "protected", wlen))
sym->other = STV_PROTECTED;
else if (!nasm_strnicmp(spcword, "gnu_ifunc", wlen))
type = STT_GNU_IFUNC;
else
ok = false;
break;
Expand Down
14 changes: 14 additions & 0 deletions travis/test/gnu_ifunc.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
section .text

global __foo_ifunc:function
global __foo_impl:function

__foo_impl:
ret

__foo_ifunc:
lea rax, [rel __foo_impl]
ret

global foo:gnu_ifunc
foo equ __foo_ifunc
11 changes: 11 additions & 0 deletions travis/test/gnu_ifunc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"description": "Test for GNU indirect function (STT_GNU_IFUNC) symbol emission",
"id": "gnu_ifunc",
"format": "elf64",
"source": "gnu_ifunc.asm",
"target": [
{ "output": "gnu_ifunc.o" }
]
}
]
Binary file added travis/test/gnu_ifunc.o.t
Binary file not shown.