xref: /freebsd-src/lib/libkldelf/kldelf.h (revision 72e15f76a1b3e7bddb5fa1b0429e41d07950af65)
1968bcca2SKa Ho Ng /*-
2968bcca2SKa Ho Ng  * SPDX-License-Identifier: BSD-4-Clause
3968bcca2SKa Ho Ng  *
4968bcca2SKa Ho Ng  * Copyright (c) 2000, Boris Popov
5968bcca2SKa Ho Ng  * All rights reserved.
6968bcca2SKa Ho Ng  *
7968bcca2SKa Ho Ng  * Redistribution and use in source and binary forms, with or without
8968bcca2SKa Ho Ng  * modification, are permitted provided that the following conditions
9968bcca2SKa Ho Ng  * are met:
10968bcca2SKa Ho Ng  * 1. Redistributions of source code must retain the above copyright
11968bcca2SKa Ho Ng  *    notice, this list of conditions and the following disclaimer.
12968bcca2SKa Ho Ng  * 2. Redistributions in binary form must reproduce the above copyright
13968bcca2SKa Ho Ng  *    notice, this list of conditions and the following disclaimer in the
14968bcca2SKa Ho Ng  *    documentation and/or other materials provided with the distribution.
15968bcca2SKa Ho Ng  * 3. All advertising materials mentioning features or use of this software
16968bcca2SKa Ho Ng  *    must display the following acknowledgement:
17968bcca2SKa Ho Ng  *    This product includes software developed by Boris Popov.
18968bcca2SKa Ho Ng  * 4. Neither the name of the author nor the names of any co-contributors
19968bcca2SKa Ho Ng  *    may be used to endorse or promote products derived from this software
20968bcca2SKa Ho Ng  *    without specific prior written permission.
21968bcca2SKa Ho Ng  *
22968bcca2SKa Ho Ng  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23968bcca2SKa Ho Ng  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24968bcca2SKa Ho Ng  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25968bcca2SKa Ho Ng  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26968bcca2SKa Ho Ng  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27968bcca2SKa Ho Ng  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28968bcca2SKa Ho Ng  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29968bcca2SKa Ho Ng  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30968bcca2SKa Ho Ng  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31968bcca2SKa Ho Ng  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32968bcca2SKa Ho Ng  * SUCH DAMAGE.
33968bcca2SKa Ho Ng  */
34968bcca2SKa Ho Ng 
35968bcca2SKa Ho Ng #ifndef _KLDELF_H_
36968bcca2SKa Ho Ng #define _KLDELF_H_
37968bcca2SKa Ho Ng 
38968bcca2SKa Ho Ng #include <sys/linker_set.h>
39968bcca2SKa Ho Ng #include <stdbool.h>
40968bcca2SKa Ho Ng 
41968bcca2SKa Ho Ng #define EF_CLOSE(ef) \
42968bcca2SKa Ho Ng     (ef)->ef_ops->close((ef)->ef_ef)
43968bcca2SKa Ho Ng #define EF_SEG_READ_REL(ef, address, len, dest) \
44968bcca2SKa Ho Ng     (ef)->ef_ops->seg_read_rel((ef)->ef_ef, address, len, dest)
45968bcca2SKa Ho Ng #define EF_SEG_READ_STRING(ef, address, len, dest) \
46968bcca2SKa Ho Ng     (ef)->ef_ops->seg_read_string((ef)->ef_ef, address, len, dest)
47968bcca2SKa Ho Ng #define EF_SYMADDR(ef, symidx) \
48968bcca2SKa Ho Ng     (ef)->ef_ops->symaddr((ef)->ef_ef, symidx)
49968bcca2SKa Ho Ng #define EF_LOOKUP_SET(ef, name, startp, stopp, countp) \
50968bcca2SKa Ho Ng     (ef)->ef_ops->lookup_set((ef)->ef_ef, name, startp, stopp, countp)
51*72e15f76SKa Ho Ng #define EF_LOOKUP_SYMBOL(ef, name, sym, see_local) \
52*72e15f76SKa Ho Ng     (ef)->ef_ops->lookup_symbol((ef)->ef_ef, name, sym, see_local)
53968bcca2SKa Ho Ng 
54968bcca2SKa Ho Ng /* XXX, should have a different name. */
55968bcca2SKa Ho Ng typedef struct ef_file *elf_file_t;
56968bcca2SKa Ho Ng 
57968bcca2SKa Ho Ng /* FreeBSD's headers define additional typedef's for ELF structures. */
58968bcca2SKa Ho Ng typedef Elf64_Size GElf_Size;
59968bcca2SKa Ho Ng typedef Elf64_Hashelt GElf_Hashelt;
60968bcca2SKa Ho Ng 
61968bcca2SKa Ho Ng struct elf_file;
62968bcca2SKa Ho Ng 
63968bcca2SKa Ho Ng struct elf_file_ops {
64968bcca2SKa Ho Ng 	void (*close)(elf_file_t ef);
65968bcca2SKa Ho Ng 	int (*seg_read_rel)(elf_file_t ef, GElf_Addr address, size_t len,
66968bcca2SKa Ho Ng 	    void *dest);
67968bcca2SKa Ho Ng 	int (*seg_read_string)(elf_file_t ef, GElf_Addr address, size_t len,
68968bcca2SKa Ho Ng 	    char *dest);
69968bcca2SKa Ho Ng 	GElf_Addr (*symaddr)(elf_file_t ef, GElf_Size symidx);
70968bcca2SKa Ho Ng 	int (*lookup_set)(elf_file_t ef, const char *name, GElf_Addr *startp,
71968bcca2SKa Ho Ng 	    GElf_Addr *stopp, long *countp);
72*72e15f76SKa Ho Ng 	int (*lookup_symbol)(elf_file_t ef, const char *name, GElf_Sym **sym,
73*72e15f76SKa Ho Ng 	    bool see_local);
74968bcca2SKa Ho Ng };
75968bcca2SKa Ho Ng 
76968bcca2SKa Ho Ng typedef int (elf_reloc_t)(struct elf_file *ef, const void *reldata,
77968bcca2SKa Ho Ng     Elf_Type reltype, GElf_Addr relbase, GElf_Addr dataoff, size_t len,
78968bcca2SKa Ho Ng     void *dest);
79968bcca2SKa Ho Ng 
80968bcca2SKa Ho Ng struct elf_reloc_data {
81968bcca2SKa Ho Ng 	unsigned char class;
82968bcca2SKa Ho Ng 	unsigned char data;
83968bcca2SKa Ho Ng 	GElf_Half machine;
84968bcca2SKa Ho Ng 	elf_reloc_t *reloc;
85968bcca2SKa Ho Ng };
86968bcca2SKa Ho Ng 
87968bcca2SKa Ho Ng #define	ELF_RELOC(_class, _data, _machine, _reloc)			\
88968bcca2SKa Ho Ng 	static struct elf_reloc_data __CONCAT(elf_reloc_data_, __LINE__) = { \
89968bcca2SKa Ho Ng 	    .class = (_class),						\
90968bcca2SKa Ho Ng 	    .data = (_data),						\
91968bcca2SKa Ho Ng 	    .machine = (_machine),					\
92968bcca2SKa Ho Ng 	    .reloc = (_reloc)						\
93968bcca2SKa Ho Ng 	};								\
94968bcca2SKa Ho Ng 	DATA_SET(elf_reloc, __CONCAT(elf_reloc_data_, __LINE__))
95968bcca2SKa Ho Ng 
96968bcca2SKa Ho Ng struct elf_file {
97968bcca2SKa Ho Ng 	elf_file_t ef_ef;
98968bcca2SKa Ho Ng 	struct elf_file_ops *ef_ops;
99968bcca2SKa Ho Ng 	const char *ef_filename;
100968bcca2SKa Ho Ng 	Elf *ef_elf;
101968bcca2SKa Ho Ng 	elf_reloc_t *ef_reloc;
102968bcca2SKa Ho Ng 	GElf_Ehdr ef_hdr;
103968bcca2SKa Ho Ng 	size_t ef_pointer_size;
104968bcca2SKa Ho Ng 	int ef_fd;
105968bcca2SKa Ho Ng };
106968bcca2SKa Ho Ng 
107968bcca2SKa Ho Ng #define	elf_machine(ef)		((ef)->ef_hdr.e_machine)
108968bcca2SKa Ho Ng #define	elf_class(ef)		((ef)->ef_hdr.e_ident[EI_CLASS])
109968bcca2SKa Ho Ng #define	elf_encoding(ef)	((ef)->ef_hdr.e_ident[EI_DATA])
110968bcca2SKa Ho Ng 
111968bcca2SKa Ho Ng /*
112968bcca2SKa Ho Ng  * "Generic" versions of module metadata structures.
113968bcca2SKa Ho Ng  */
114968bcca2SKa Ho Ng struct Gmod_depend {
115968bcca2SKa Ho Ng 	int	md_ver_minimum;
116968bcca2SKa Ho Ng 	int	md_ver_preferred;
117968bcca2SKa Ho Ng 	int	md_ver_maximum;
118968bcca2SKa Ho Ng };
119968bcca2SKa Ho Ng 
120968bcca2SKa Ho Ng struct Gmod_version {
121968bcca2SKa Ho Ng 	int	mv_version;
122968bcca2SKa Ho Ng };
123968bcca2SKa Ho Ng 
124968bcca2SKa Ho Ng struct Gmod_metadata {
125968bcca2SKa Ho Ng 	int		md_version;	/* structure version MDTV_* */
126968bcca2SKa Ho Ng 	int		md_type;	/* type of entry MDT_* */
127968bcca2SKa Ho Ng 	GElf_Addr	md_data;	/* specific data */
128968bcca2SKa Ho Ng 	GElf_Addr	md_cval;	/* common string label */
129968bcca2SKa Ho Ng };
130968bcca2SKa Ho Ng 
131968bcca2SKa Ho Ng struct Gmod_pnp_match_info
132968bcca2SKa Ho Ng {
133968bcca2SKa Ho Ng 	GElf_Addr	descr;	/* Description of the table */
134968bcca2SKa Ho Ng 	GElf_Addr	bus;	/* Name of the bus for this table */
135968bcca2SKa Ho Ng 	GElf_Addr	table;	/* Pointer to pnp table */
136968bcca2SKa Ho Ng 	int entry_len;		/* Length of each entry in the table (may be */
137968bcca2SKa Ho Ng 				/*   longer than descr describes). */
138968bcca2SKa Ho Ng 	int num_entry;		/* Number of entries in the table */
139968bcca2SKa Ho Ng };
140968bcca2SKa Ho Ng 
141968bcca2SKa Ho Ng __BEGIN_DECLS
142968bcca2SKa Ho Ng 
143968bcca2SKa Ho Ng /*
144968bcca2SKa Ho Ng  * Attempt to parse an open ELF file as either an executable or DSO
145968bcca2SKa Ho Ng  * (ef_open) or an object file (ef_obj_open).  On success, these
146968bcca2SKa Ho Ng  * routines initialize the 'ef_ef' and 'ef_ops' members of 'ef'.
147968bcca2SKa Ho Ng  */
148968bcca2SKa Ho Ng int ef_open(struct elf_file *ef, int verbose);
149968bcca2SKa Ho Ng int ef_obj_open(struct elf_file *ef, int verbose);
150968bcca2SKa Ho Ng 
151968bcca2SKa Ho Ng /*
152968bcca2SKa Ho Ng  * Direct operations on an ELF file regardless of type.  Many of these
153968bcca2SKa Ho Ng  * use libelf.
154968bcca2SKa Ho Ng  */
155968bcca2SKa Ho Ng 
156968bcca2SKa Ho Ng /*
157968bcca2SKa Ho Ng  * Open an ELF file with libelf.  Populates fields other than ef_ef
158968bcca2SKa Ho Ng  * and ef_ops in '*efile'.
159968bcca2SKa Ho Ng  */
160968bcca2SKa Ho Ng int	elf_open_file(struct elf_file *efile, const char *filename,
161968bcca2SKa Ho Ng     int verbose);
162968bcca2SKa Ho Ng 
163968bcca2SKa Ho Ng /* Close an ELF file. */
164968bcca2SKa Ho Ng void	elf_close_file(struct elf_file *efile);
165968bcca2SKa Ho Ng 
166968bcca2SKa Ho Ng /* Is an ELF file the same architecture as hdr? */
167968bcca2SKa Ho Ng bool	elf_compatible(struct elf_file *efile, const GElf_Ehdr *hdr);
168968bcca2SKa Ho Ng 
169968bcca2SKa Ho Ng /* The size of a single object of 'type'. */
170968bcca2SKa Ho Ng size_t	elf_object_size(struct elf_file *efile, Elf_Type type);
171968bcca2SKa Ho Ng 
172968bcca2SKa Ho Ng /* The size of a pointer in architecture of 'efile'. */
173968bcca2SKa Ho Ng size_t	elf_pointer_size(struct elf_file *efile);
174968bcca2SKa Ho Ng 
175968bcca2SKa Ho Ng /*
176968bcca2SKa Ho Ng  * Read and convert an array of a data type from an ELF file.  This is
177968bcca2SKa Ho Ng  * a wrapper around gelf_xlatetom() which reads an array of raw ELF
178968bcca2SKa Ho Ng  * objects from the file and converts them into host structures using
179968bcca2SKa Ho Ng  * native endianness.  The data is returned in a dynamically-allocated
180968bcca2SKa Ho Ng  * buffer.
181968bcca2SKa Ho Ng  */
182968bcca2SKa Ho Ng int	elf_read_data(struct elf_file *efile, Elf_Type type, off_t offset,
183968bcca2SKa Ho Ng     size_t len, void **out);
184968bcca2SKa Ho Ng 
185968bcca2SKa Ho Ng /* Reads "raw" data from an ELF file without any translation. */
186968bcca2SKa Ho Ng int	elf_read_raw_data(struct elf_file *efile, off_t offset, void *dst,
187968bcca2SKa Ho Ng     size_t len);
188968bcca2SKa Ho Ng 
189968bcca2SKa Ho Ng /*
190968bcca2SKa Ho Ng  * A wrapper around elf_read_raw_data which returns the data in a
191968bcca2SKa Ho Ng  * dynamically-allocated buffer.
192968bcca2SKa Ho Ng  */
193968bcca2SKa Ho Ng int	elf_read_raw_data_alloc(struct elf_file *efile, off_t offset,
194968bcca2SKa Ho Ng     size_t len, void **out);
195968bcca2SKa Ho Ng 
196968bcca2SKa Ho Ng /* Reads a single string at the given offset from an ELF file. */
197968bcca2SKa Ho Ng int	elf_read_raw_string(struct elf_file *efile, off_t offset, char *dst,
198968bcca2SKa Ho Ng     size_t len);
199968bcca2SKa Ho Ng 
200968bcca2SKa Ho Ng /*
201968bcca2SKa Ho Ng  * Read relocated data from an ELF file and return it in a
202968bcca2SKa Ho Ng  * dynamically-allocated buffer.  Note that no translation
203968bcca2SKa Ho Ng  * (byte-swapping for endianness, 32-vs-64) is performed on the
204968bcca2SKa Ho Ng  * returned data, but any ELF relocations which affect the contents
205968bcca2SKa Ho Ng  * are applied to the returned data.  The address parameter gives the
206968bcca2SKa Ho Ng  * address of the data buffer if the ELF file were loaded into memory
207968bcca2SKa Ho Ng  * rather than a direct file offset.
208968bcca2SKa Ho Ng  */
209968bcca2SKa Ho Ng int	elf_read_relocated_data(struct elf_file *efile, GElf_Addr address,
210968bcca2SKa Ho Ng     size_t len, void **buf);
211968bcca2SKa Ho Ng 
212968bcca2SKa Ho Ng /*
213968bcca2SKa Ho Ng  * Read the program headers from an ELF file and return them in a
214968bcca2SKa Ho Ng  * dynamically-allocated array of GElf_Phdr objects.
215968bcca2SKa Ho Ng  */
216968bcca2SKa Ho Ng int	elf_read_phdrs(struct elf_file *efile, size_t *nphdrp,
217968bcca2SKa Ho Ng     GElf_Phdr **phdrp);
218968bcca2SKa Ho Ng 
219968bcca2SKa Ho Ng /*
220968bcca2SKa Ho Ng  * Read the section headers from an ELF file and return them in a
221968bcca2SKa Ho Ng  * dynamically-allocated array of GElf_Shdr objects.
222968bcca2SKa Ho Ng  */
223968bcca2SKa Ho Ng int	elf_read_shdrs(struct elf_file *efile, size_t *nshdrp,
224968bcca2SKa Ho Ng     GElf_Shdr **shdrp);
225968bcca2SKa Ho Ng 
226968bcca2SKa Ho Ng /*
227968bcca2SKa Ho Ng  * Read the dynamic table from a section of an ELF file into a
228968bcca2SKa Ho Ng  * dynamically-allocated array of GElf_Dyn objects.
229968bcca2SKa Ho Ng  */
230968bcca2SKa Ho Ng int	elf_read_dynamic(struct elf_file *efile, int section_index, size_t *ndynp,
231968bcca2SKa Ho Ng     GElf_Dyn **dynp);
232968bcca2SKa Ho Ng 
233968bcca2SKa Ho Ng /*
234968bcca2SKa Ho Ng  * Read a symbol table from a section of an ELF file into a
235968bcca2SKa Ho Ng  * dynamically-allocated array of GElf_Sym objects.
236968bcca2SKa Ho Ng  */
237968bcca2SKa Ho Ng int	elf_read_symbols(struct elf_file *efile, int section_index,
238968bcca2SKa Ho Ng     size_t *nsymp, GElf_Sym **symp);
239968bcca2SKa Ho Ng 
240968bcca2SKa Ho Ng /*
241968bcca2SKa Ho Ng  * Read a string table described by a section header of an ELF file
242968bcca2SKa Ho Ng  * into a dynamically-allocated buffer.
243968bcca2SKa Ho Ng  */
244968bcca2SKa Ho Ng int	elf_read_string_table(struct elf_file *efile, const GElf_Shdr *shdr,
245968bcca2SKa Ho Ng     long *strcnt, char **strtab);
246968bcca2SKa Ho Ng 
247968bcca2SKa Ho Ng /*
248968bcca2SKa Ho Ng  * Read a table of relocation objects from a section of an ELF file
249968bcca2SKa Ho Ng  * into a dynamically-allocated array of GElf_Rel objects.
250968bcca2SKa Ho Ng  */
251968bcca2SKa Ho Ng int	elf_read_rel(struct elf_file *efile, int section_index, long *nrelp,
252968bcca2SKa Ho Ng     GElf_Rel **relp);
253968bcca2SKa Ho Ng 
254968bcca2SKa Ho Ng /*
255968bcca2SKa Ho Ng  * Read a table of relocation-with-addend objects from a section of an
256968bcca2SKa Ho Ng  * ELF file into a dynamically-allocated array of GElf_Rela objects.
257968bcca2SKa Ho Ng  */
258968bcca2SKa Ho Ng int	elf_read_rela(struct elf_file *efile, int section_index, long *nrelap,
259968bcca2SKa Ho Ng     GElf_Rela **relap);
260968bcca2SKa Ho Ng 
261968bcca2SKa Ho Ng /*
262968bcca2SKa Ho Ng  * Read a string from an ELF file and return it in the provided
263968bcca2SKa Ho Ng  * buffer.  If the string is longer than the buffer, this fails with
264968bcca2SKa Ho Ng  * EFAULT.  The address parameter gives the address of the data buffer
265968bcca2SKa Ho Ng  * if the ELF file were loaded into memory rather than a direct file
266968bcca2SKa Ho Ng  * offset.
267968bcca2SKa Ho Ng  */
268968bcca2SKa Ho Ng int	elf_read_string(struct elf_file *efile, GElf_Addr address, void *dst,
269968bcca2SKa Ho Ng     size_t len);
270968bcca2SKa Ho Ng 
271968bcca2SKa Ho Ng /* Return the address extracted from a target pointer stored at 'p'. */
272968bcca2SKa Ho Ng GElf_Addr elf_address_from_pointer(struct elf_file *efile, const void *p);
273968bcca2SKa Ho Ng 
274968bcca2SKa Ho Ng /*
275968bcca2SKa Ho Ng  * Read a linker set and return an array of addresses extracted from the
276968bcca2SKa Ho Ng  * relocated pointers in the linker set.
277968bcca2SKa Ho Ng  */
278968bcca2SKa Ho Ng int	elf_read_linker_set(struct elf_file *efile, const char *name,
279968bcca2SKa Ho Ng     GElf_Addr **buf, long *countp);
280968bcca2SKa Ho Ng 
281968bcca2SKa Ho Ng /*
282968bcca2SKa Ho Ng  * Read and convert a target 'struct mod_depend' into a host
283968bcca2SKa Ho Ng  * 'struct Gmod_depend'.
284968bcca2SKa Ho Ng  */
285968bcca2SKa Ho Ng int	elf_read_mod_depend(struct elf_file *efile, GElf_Addr addr,
286968bcca2SKa Ho Ng     struct Gmod_depend *mdp);
287968bcca2SKa Ho Ng 
288968bcca2SKa Ho Ng /*
289968bcca2SKa Ho Ng  * Read and convert a target 'struct mod_version' into a host
290968bcca2SKa Ho Ng  * 'struct Gmod_version'.
291968bcca2SKa Ho Ng  */
292968bcca2SKa Ho Ng int	elf_read_mod_version(struct elf_file *efile, GElf_Addr addr,
293968bcca2SKa Ho Ng     struct Gmod_version *mdv);
294968bcca2SKa Ho Ng 
295968bcca2SKa Ho Ng /*
296968bcca2SKa Ho Ng  * Read and convert a target 'struct mod_metadata' into a host
297968bcca2SKa Ho Ng  * 'struct Gmod_metadata'.
298968bcca2SKa Ho Ng  */
299968bcca2SKa Ho Ng int	elf_read_mod_metadata(struct elf_file *efile, GElf_Addr addr,
300968bcca2SKa Ho Ng     struct Gmod_metadata *md);
301968bcca2SKa Ho Ng 
302968bcca2SKa Ho Ng /*
303968bcca2SKa Ho Ng  * Read and convert a target 'struct mod_pnp_match_info' into a host
304968bcca2SKa Ho Ng  * 'struct Gmod_pnp_match_info'.
305968bcca2SKa Ho Ng  */
306968bcca2SKa Ho Ng int	elf_read_mod_pnp_match_info(struct elf_file *efile, GElf_Addr addr,
307968bcca2SKa Ho Ng     struct Gmod_pnp_match_info *pnp);
308968bcca2SKa Ho Ng 
309968bcca2SKa Ho Ng /*
310968bcca2SKa Ho Ng  * Apply relocations to the values obtained from the file. `relbase' is the
311968bcca2SKa Ho Ng  * target relocation address of the section, and `dataoff/len' is the region
312968bcca2SKa Ho Ng  * that is to be relocated, and has been copied to *dest
313968bcca2SKa Ho Ng  */
314968bcca2SKa Ho Ng int	elf_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
315968bcca2SKa Ho Ng     GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest);
316968bcca2SKa Ho Ng 
31743628a31SKa Ho Ng /*
31843628a31SKa Ho Ng  * Find the symbol with the specified symbol name 'name' within the given
31943628a31SKa Ho Ng  * 'efile'. 0 is returned when such a symbol is found, otherwise ENOENT is
32043628a31SKa Ho Ng  * returned.
32143628a31SKa Ho Ng  */
32243628a31SKa Ho Ng int	elf_lookup_symbol(struct elf_file *efile, const char *name,
323*72e15f76SKa Ho Ng     GElf_Sym **sym, bool see_local);
32443628a31SKa Ho Ng 
325968bcca2SKa Ho Ng __END_DECLS
326968bcca2SKa Ho Ng 
327968bcca2SKa Ho Ng #endif /* _KLDELF_H_*/
328