1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
So you want to add an interface to libc...
CASE I: internal symbols
A) used in a single file
Duh: use whatever name you want and make it static
B) used in multiple files
Give it a name in the implementation namespace (leading underbar)
and declare it in a __{BEGIN,END}_HIDDEN_DECLS block in a .h
file inside libc. If it's used in just a single subdir of
libc *and* that subdir has an appropriate .h file in it, then
declare it there.
Example: stdio/local.h.
Otherwise, declare it in one of the hidden/* files.
Example: _mktemp() in hidden/stdio.h
CASE II: external symbols
First of all, add your symbol to Symbols.list. MD symbols go in
arch/*/Symbols.list (shock, I know)
Declare your function in the appropriate header. It almost certainly
should be in a public header installed under /usr/include/. Exceptions
are symbols that are just shared between libc and libpthread/csu/ld.so
which are only declared in libc/include/* or just in each .c file.
A) objects (variables)
That's it, you're done.
B) plain C functions (not syscalls)
1) functions that are *not* called from inside libc
If this function is specified in the ISO C standard or its
name begins with an underbar, then in the hidden/* version
of the header where you declared the function, add this line:
PROTO_STD_DEPRECATED(your_function_name);
Otherwise, this is *not* a function specified in the ISO C
standard and its name begins with a letter. In the hidden/*
version of the header where you declared the function, add
this line:
PROTO_DEPRECATED(your_function_name);
2) functions that are called from inside libc
In the hidden/* version of the header where you declared
the function, add this line:
PROTO_NORMAL(your_function_name);
Then, in the .c file(s) where the function is defined:
- if the function is specified in the ISO C standard or
its name begins with an underbar, add
DEF_STRONG(your_function_name);
- otherwise, add:
DEF_WEAK(your_function_name);
C) syscalls that require cancellation or other libpthread wrappers
You're done in libc, but go to libpthread and add the wrapper there.
D) syscalls that require libc wrappers for other reasons
First of all, make sure this really is the Right Thing. Talk
with kettenis, deraadt, miod, and guenther.
1) If the actual syscall doesn't have the same calling convention
as the C interface, then maybe it shouldn't be exported at
all and you should just have an ASM stub, like SYS___tfork
--> __tfork_thread() or SYS_break --> brk() and sbrk(). If
it _could_ be called from C, then give the syscall a name
different from the C API. Syscalls that fail this for
historical reasons (e.g., getlogin) are generated with
PSEUDO in libc/sys/Makefile.inc, so the ASM stub has a
leading underbar. Go read gen/getlogin.c for an example
of how to do this.
2) Otherwise, you're sane and have a syscall like sigaction()
which requires a wrapper but whose syscall API is the same
as the C API. Then:
- generate the ASM stub with HIDDEN in libc/sys/Makefile.inc
- in the proper hidden/*.h file add
PROTO_WRAP(your_function_name)
- the wrapper function should be defined in
libc/sys/w_your_function_name.c
which should define WRAP(your_function_name) and
follow it with DEF_WRAP(your_function_name). Look at
libc/sys/w_sigaction.c for an example.
- by default, libc code that calls your_function_name()
will get the real syscall and *not* the wrapper. libc
calls that needd to go through the wrapper should invoke
WRAP(your_function_name)
E) syscalls that don't require any wrapping
In the hidden/* version of the header where you declared the
function, add this line:
PROTO_NORMAL(your_function_name);
|