xref: /netbsd-src/external/gpl3/gdb/dist/include/plugin-api.h (revision e663ba6e3a60083e70de702e9d54bf486a57b6a7)
198b9484cSchristos /* plugin-api.h -- External linker plugin API.  */
298b9484cSchristos 
3*e663ba6eSchristos /* Copyright (C) 2009-2024 Free Software Foundation, Inc.
498b9484cSchristos    Written by Cary Coutant <ccoutant@google.com>.
598b9484cSchristos 
698b9484cSchristos    This file is part of binutils.
798b9484cSchristos 
898b9484cSchristos    This program is free software; you can redistribute it and/or modify
998b9484cSchristos    it under the terms of the GNU General Public License as published by
1098b9484cSchristos    the Free Software Foundation; either version 3 of the License, or
1198b9484cSchristos    (at your option) any later version.
1298b9484cSchristos 
1398b9484cSchristos    This program is distributed in the hope that it will be useful,
1498b9484cSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1598b9484cSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698b9484cSchristos    GNU General Public License for more details.
1798b9484cSchristos 
1898b9484cSchristos    You should have received a copy of the GNU General Public License
1998b9484cSchristos    along with this program; if not, write to the Free Software
2098b9484cSchristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2198b9484cSchristos    MA 02110-1301, USA.  */
2298b9484cSchristos 
2398b9484cSchristos /* This file defines the interface for writing a linker plugin, which is
2498b9484cSchristos    described at < http://gcc.gnu.org/wiki/whopr/driver >.  */
2598b9484cSchristos 
2698b9484cSchristos #ifndef PLUGIN_API_H
2798b9484cSchristos #define PLUGIN_API_H
2898b9484cSchristos 
2998b9484cSchristos #ifdef HAVE_STDINT_H
3098b9484cSchristos #include <stdint.h>
3198b9484cSchristos #elif defined(HAVE_INTTYPES_H)
3298b9484cSchristos #include <inttypes.h>
3398b9484cSchristos #endif
3498b9484cSchristos #include <sys/types.h>
3598b9484cSchristos #if !defined(HAVE_STDINT_H) && !defined(HAVE_INTTYPES_H) && \
3698b9484cSchristos     !defined(UINT64_MAX) && !defined(uint64_t)
3798b9484cSchristos #error cannot find uint64_t type
3898b9484cSchristos #endif
3998b9484cSchristos 
40*e663ba6eSchristos /* Detect endianess based on gcc's (>=4.6.0) __BYTE_ORDER__ macro.  */
418dffb485Schristos #if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
428dffb485Schristos     defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_PDP_ENDIAN__)
438dffb485Schristos #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
448dffb485Schristos #define PLUGIN_LITTLE_ENDIAN 1
458dffb485Schristos #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
468dffb485Schristos #define PLUGIN_BIG_ENDIAN 1
478dffb485Schristos #elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
488dffb485Schristos #define PLUGIN_PDP_ENDIAN 1
498dffb485Schristos #endif
50*e663ba6eSchristos 
518dffb485Schristos #else
52*e663ba6eSchristos /* Include header files to define endian macros.  */
538dffb485Schristos #if defined(__GLIBC__) || defined(__GNU_LIBRARY__) || defined(__ANDROID__)
548dffb485Schristos #include <endian.h>
55*e663ba6eSchristos 
56*e663ba6eSchristos #elif defined(__SVR4) && defined(__sun)
57*e663ba6eSchristos #include <sys/byteorder.h>
58*e663ba6eSchristos 
59*e663ba6eSchristos #elif defined(__FreeBSD__) || defined(__NetBSD__) || \
60*e663ba6eSchristos       defined(__DragonFly__) || defined(__minix)
61*e663ba6eSchristos #include <sys/endian.h>
62*e663ba6eSchristos 
63*e663ba6eSchristos #elif defined(__OpenBSD__)
64*e663ba6eSchristos #include <machine/endian.h>
65*e663ba6eSchristos #endif
66*e663ba6eSchristos 
67*e663ba6eSchristos /* Detect endianess based on __BYTE_ORDER.  */
688dffb485Schristos #ifdef __BYTE_ORDER
698dffb485Schristos #if __BYTE_ORDER == __LITTLE_ENDIAN
708dffb485Schristos #define PLUGIN_LITTLE_ENDIAN 1
718dffb485Schristos #elif __BYTE_ORDER == __BIG_ENDIAN
728dffb485Schristos #define PLUGIN_BIG_ENDIAN 1
738dffb485Schristos #endif
74*e663ba6eSchristos 
758dffb485Schristos /* Detect endianess based on _BYTE_ORDER.  */
76*e663ba6eSchristos #elif defined _BYTE_ORDER
778dffb485Schristos #if _BYTE_ORDER == _LITTLE_ENDIAN
788dffb485Schristos #define PLUGIN_LITTLE_ENDIAN 1
798dffb485Schristos #elif _BYTE_ORDER == _BIG_ENDIAN
808dffb485Schristos #define PLUGIN_BIG_ENDIAN 1
818dffb485Schristos #endif
82*e663ba6eSchristos 
838dffb485Schristos /* Detect based on _WIN32.  */
84*e663ba6eSchristos #elif defined _WIN32
858dffb485Schristos #define PLUGIN_LITTLE_ENDIAN 1
86*e663ba6eSchristos 
878dffb485Schristos /* Detect based on __BIG_ENDIAN__ and __LITTLE_ENDIAN__ */
88*e663ba6eSchristos #elif defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
898dffb485Schristos #define PLUGIN_LITTLE_ENDIAN 1
90*e663ba6eSchristos #elif defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
918dffb485Schristos #define PLUGIN_BIG_ENDIAN 1
928dffb485Schristos #endif
938dffb485Schristos #endif
948dffb485Schristos 
9598b9484cSchristos #ifdef __cplusplus
9698b9484cSchristos extern "C"
9798b9484cSchristos {
9898b9484cSchristos #endif
9998b9484cSchristos 
10098b9484cSchristos /* Status code returned by most API routines.  */
10198b9484cSchristos 
10298b9484cSchristos enum ld_plugin_status
10398b9484cSchristos {
10498b9484cSchristos   LDPS_OK = 0,
10598b9484cSchristos   LDPS_NO_SYMS,         /* Attempt to get symbols that haven't been added. */
10698b9484cSchristos   LDPS_BAD_HANDLE,      /* No claimed object associated with given handle. */
10798b9484cSchristos   LDPS_ERR
10898b9484cSchristos   /* Additional Error codes TBD.  */
10998b9484cSchristos };
11098b9484cSchristos 
11198b9484cSchristos /* The version of the API specification.  */
11298b9484cSchristos 
11398b9484cSchristos enum ld_plugin_api_version
11498b9484cSchristos {
11598b9484cSchristos   LD_PLUGIN_API_VERSION = 1
11698b9484cSchristos };
11798b9484cSchristos 
11898b9484cSchristos /* The type of output file being generated by the linker.  */
11998b9484cSchristos 
12098b9484cSchristos enum ld_plugin_output_file_type
12198b9484cSchristos {
12298b9484cSchristos   LDPO_REL,
12398b9484cSchristos   LDPO_EXEC,
124a2e2270fSchristos   LDPO_DYN,
125a2e2270fSchristos   LDPO_PIE
12698b9484cSchristos };
12798b9484cSchristos 
12898b9484cSchristos /* An input file managed by the plugin library.  */
12998b9484cSchristos 
13098b9484cSchristos struct ld_plugin_input_file
13198b9484cSchristos {
13298b9484cSchristos   const char *name;
13398b9484cSchristos   int fd;
13498b9484cSchristos   off_t offset;
13598b9484cSchristos   off_t filesize;
13698b9484cSchristos   void *handle;
13798b9484cSchristos };
13898b9484cSchristos 
13998b9484cSchristos /* A symbol belonging to an input file managed by the plugin library.  */
14098b9484cSchristos 
14198b9484cSchristos struct ld_plugin_symbol
14298b9484cSchristos {
14398b9484cSchristos   char *name;
14498b9484cSchristos   char *version;
1458dffb485Schristos   /* This is for compatibility with older ABIs.  The older ABI defined
1468dffb485Schristos      only 'def' field.  */
1478dffb485Schristos #if PLUGIN_BIG_ENDIAN == 1
1488dffb485Schristos   char unused;
1498dffb485Schristos   char section_kind;
1508dffb485Schristos   char symbol_type;
1518dffb485Schristos   char def;
1528dffb485Schristos #elif PLUGIN_LITTLE_ENDIAN == 1
1538dffb485Schristos   char def;
1548dffb485Schristos   char symbol_type;
1558dffb485Schristos   char section_kind;
1568dffb485Schristos   char unused;
1578dffb485Schristos #elif PLUGIN_PDP_ENDIAN == 1
1588dffb485Schristos   char symbol_type;
1598dffb485Schristos   char def;
1608dffb485Schristos   char unused;
1618dffb485Schristos   char section_kind;
1628dffb485Schristos #else
1638dffb485Schristos #error "Could not detect architecture endianess"
1648dffb485Schristos #endif
16598b9484cSchristos   int visibility;
16698b9484cSchristos   uint64_t size;
16798b9484cSchristos   char *comdat_key;
16898b9484cSchristos   int resolution;
16998b9484cSchristos };
17098b9484cSchristos 
171a2e2270fSchristos /* An object's section.  */
172a2e2270fSchristos 
173a2e2270fSchristos struct ld_plugin_section
174a2e2270fSchristos {
175a2e2270fSchristos   const void* handle;
176a2e2270fSchristos   unsigned int shndx;
177a2e2270fSchristos };
178a2e2270fSchristos 
17998b9484cSchristos /* Whether the symbol is a definition, reference, or common, weak or not.  */
18098b9484cSchristos 
18198b9484cSchristos enum ld_plugin_symbol_kind
18298b9484cSchristos {
18398b9484cSchristos   LDPK_DEF,
18498b9484cSchristos   LDPK_WEAKDEF,
18598b9484cSchristos   LDPK_UNDEF,
18698b9484cSchristos   LDPK_WEAKUNDEF,
18798b9484cSchristos   LDPK_COMMON
18898b9484cSchristos };
18998b9484cSchristos 
19098b9484cSchristos /* The visibility of the symbol.  */
19198b9484cSchristos 
19298b9484cSchristos enum ld_plugin_symbol_visibility
19398b9484cSchristos {
19498b9484cSchristos   LDPV_DEFAULT,
19598b9484cSchristos   LDPV_PROTECTED,
19698b9484cSchristos   LDPV_INTERNAL,
19798b9484cSchristos   LDPV_HIDDEN
19898b9484cSchristos };
19998b9484cSchristos 
2008dffb485Schristos /* The type of the symbol.  */
2018dffb485Schristos 
2028dffb485Schristos enum ld_plugin_symbol_type
2038dffb485Schristos {
2048dffb485Schristos   LDST_UNKNOWN,
2058dffb485Schristos   LDST_FUNCTION,
2068dffb485Schristos   LDST_VARIABLE
2078dffb485Schristos };
2088dffb485Schristos 
2098dffb485Schristos enum ld_plugin_symbol_section_kind
2108dffb485Schristos {
2118dffb485Schristos   LDSSK_DEFAULT,
2128dffb485Schristos   LDSSK_BSS
2138dffb485Schristos };
2148dffb485Schristos 
21598b9484cSchristos /* How a symbol is resolved.  */
21698b9484cSchristos 
21798b9484cSchristos enum ld_plugin_symbol_resolution
21898b9484cSchristos {
21998b9484cSchristos   LDPR_UNKNOWN = 0,
22098b9484cSchristos 
22198b9484cSchristos   /* Symbol is still undefined at this point.  */
22298b9484cSchristos   LDPR_UNDEF,
22398b9484cSchristos 
22498b9484cSchristos   /* This is the prevailing definition of the symbol, with references from
22598b9484cSchristos      regular object code.  */
22698b9484cSchristos   LDPR_PREVAILING_DEF,
22798b9484cSchristos 
22898b9484cSchristos   /* This is the prevailing definition of the symbol, with no
22998b9484cSchristos      references from regular objects.  It is only referenced from IR
23098b9484cSchristos      code.  */
23198b9484cSchristos   LDPR_PREVAILING_DEF_IRONLY,
23298b9484cSchristos 
23398b9484cSchristos   /* This definition was pre-empted by a definition in a regular
23498b9484cSchristos      object file.  */
23598b9484cSchristos   LDPR_PREEMPTED_REG,
23698b9484cSchristos 
23798b9484cSchristos   /* This definition was pre-empted by a definition in another IR file.  */
23898b9484cSchristos   LDPR_PREEMPTED_IR,
23998b9484cSchristos 
24098b9484cSchristos   /* This symbol was resolved by a definition in another IR file.  */
24198b9484cSchristos   LDPR_RESOLVED_IR,
24298b9484cSchristos 
24398b9484cSchristos   /* This symbol was resolved by a definition in a regular object
24498b9484cSchristos      linked into the main executable.  */
24598b9484cSchristos   LDPR_RESOLVED_EXEC,
24698b9484cSchristos 
24798b9484cSchristos   /* This symbol was resolved by a definition in a shared object.  */
248a2e2270fSchristos   LDPR_RESOLVED_DYN,
249a2e2270fSchristos 
250a2e2270fSchristos   /* This is the prevailing definition of the symbol, with no
251a2e2270fSchristos      references from regular objects.  It is only referenced from IR
252a2e2270fSchristos      code, but the symbol is exported and may be referenced from
253a2e2270fSchristos      a dynamic object (not seen at link time).  */
254a2e2270fSchristos   LDPR_PREVAILING_DEF_IRONLY_EXP
25598b9484cSchristos };
25698b9484cSchristos 
25798b9484cSchristos /* The plugin library's "claim file" handler.  */
25898b9484cSchristos 
25998b9484cSchristos typedef
26098b9484cSchristos enum ld_plugin_status
26198b9484cSchristos (*ld_plugin_claim_file_handler) (
26298b9484cSchristos   const struct ld_plugin_input_file *file, int *claimed);
26398b9484cSchristos 
264*e663ba6eSchristos /* The plugin library's "claim file" handler, version 2.  */
265*e663ba6eSchristos 
266*e663ba6eSchristos typedef
267*e663ba6eSchristos enum ld_plugin_status
268*e663ba6eSchristos (*ld_plugin_claim_file_handler_v2) (
269*e663ba6eSchristos   const struct ld_plugin_input_file *file, int *claimed, int known_used);
270*e663ba6eSchristos 
27198b9484cSchristos /* The plugin library's "all symbols read" handler.  */
27298b9484cSchristos 
27398b9484cSchristos typedef
27498b9484cSchristos enum ld_plugin_status
27598b9484cSchristos (*ld_plugin_all_symbols_read_handler) (void);
27698b9484cSchristos 
27798b9484cSchristos /* The plugin library's cleanup handler.  */
27898b9484cSchristos 
27998b9484cSchristos typedef
28098b9484cSchristos enum ld_plugin_status
28198b9484cSchristos (*ld_plugin_cleanup_handler) (void);
28298b9484cSchristos 
28398b9484cSchristos /* The linker's interface for registering the "claim file" handler.  */
28498b9484cSchristos 
28598b9484cSchristos typedef
28698b9484cSchristos enum ld_plugin_status
28798b9484cSchristos (*ld_plugin_register_claim_file) (ld_plugin_claim_file_handler handler);
28898b9484cSchristos 
289*e663ba6eSchristos /* The linker's interface for registering the "claim file" handler,
290*e663ba6eSchristos    version 2.  */
291*e663ba6eSchristos 
292*e663ba6eSchristos typedef
293*e663ba6eSchristos enum ld_plugin_status
294*e663ba6eSchristos (*ld_plugin_register_claim_file_v2) (ld_plugin_claim_file_handler_v2 handler);
295*e663ba6eSchristos 
29698b9484cSchristos /* The linker's interface for registering the "all symbols read" handler.  */
29798b9484cSchristos 
29898b9484cSchristos typedef
29998b9484cSchristos enum ld_plugin_status
30098b9484cSchristos (*ld_plugin_register_all_symbols_read) (
30198b9484cSchristos   ld_plugin_all_symbols_read_handler handler);
30298b9484cSchristos 
30398b9484cSchristos /* The linker's interface for registering the cleanup handler.  */
30498b9484cSchristos 
30598b9484cSchristos typedef
30698b9484cSchristos enum ld_plugin_status
30798b9484cSchristos (*ld_plugin_register_cleanup) (ld_plugin_cleanup_handler handler);
30898b9484cSchristos 
30998b9484cSchristos /* The linker's interface for adding symbols from a claimed input file.  */
31098b9484cSchristos 
31198b9484cSchristos typedef
31298b9484cSchristos enum ld_plugin_status
31398b9484cSchristos (*ld_plugin_add_symbols) (void *handle, int nsyms,
31498b9484cSchristos                           const struct ld_plugin_symbol *syms);
31598b9484cSchristos 
31698b9484cSchristos /* The linker's interface for getting the input file information with
31798b9484cSchristos    an open (possibly re-opened) file descriptor.  */
31898b9484cSchristos 
31998b9484cSchristos typedef
32098b9484cSchristos enum ld_plugin_status
32198b9484cSchristos (*ld_plugin_get_input_file) (const void *handle,
32298b9484cSchristos                              struct ld_plugin_input_file *file);
32398b9484cSchristos 
32498b9484cSchristos typedef
32598b9484cSchristos enum ld_plugin_status
32698b9484cSchristos (*ld_plugin_get_view) (const void *handle, const void **viewp);
32798b9484cSchristos 
32898b9484cSchristos /* The linker's interface for releasing the input file.  */
32998b9484cSchristos 
33098b9484cSchristos typedef
33198b9484cSchristos enum ld_plugin_status
33298b9484cSchristos (*ld_plugin_release_input_file) (const void *handle);
33398b9484cSchristos 
33498b9484cSchristos /* The linker's interface for retrieving symbol resolution information.  */
33598b9484cSchristos 
33698b9484cSchristos typedef
33798b9484cSchristos enum ld_plugin_status
33898b9484cSchristos (*ld_plugin_get_symbols) (const void *handle, int nsyms,
33998b9484cSchristos                           struct ld_plugin_symbol *syms);
34098b9484cSchristos 
34198b9484cSchristos /* The linker's interface for adding a compiled input file.  */
34298b9484cSchristos 
34398b9484cSchristos typedef
34498b9484cSchristos enum ld_plugin_status
34598b9484cSchristos (*ld_plugin_add_input_file) (const char *pathname);
34698b9484cSchristos 
34798b9484cSchristos /* The linker's interface for adding a library that should be searched.  */
34898b9484cSchristos 
34998b9484cSchristos typedef
35098b9484cSchristos enum ld_plugin_status
35198b9484cSchristos (*ld_plugin_add_input_library) (const char *libname);
35298b9484cSchristos 
35398b9484cSchristos /* The linker's interface for adding a library path that should be searched.  */
35498b9484cSchristos 
35598b9484cSchristos typedef
35698b9484cSchristos enum ld_plugin_status
35798b9484cSchristos (*ld_plugin_set_extra_library_path) (const char *path);
35898b9484cSchristos 
35998b9484cSchristos /* The linker's interface for issuing a warning or error message.  */
36098b9484cSchristos 
36198b9484cSchristos typedef
36298b9484cSchristos enum ld_plugin_status
36398b9484cSchristos (*ld_plugin_message) (int level, const char *format, ...);
36498b9484cSchristos 
365a2e2270fSchristos /* The linker's interface for retrieving the number of sections in an object.
366a2e2270fSchristos    The handle is obtained in the claim_file handler.  This interface should
367a2e2270fSchristos    only be invoked in the claim_file handler.   This function sets *COUNT to
368a2e2270fSchristos    the number of sections in the object.  */
369a2e2270fSchristos 
370a2e2270fSchristos typedef
371a2e2270fSchristos enum ld_plugin_status
372a2e2270fSchristos (*ld_plugin_get_input_section_count) (const void* handle, unsigned int *count);
373a2e2270fSchristos 
374a2e2270fSchristos /* The linker's interface for retrieving the section type of a specific
375a2e2270fSchristos    section in an object.  This interface should only be invoked in the
376a2e2270fSchristos    claim_file handler.  This function sets *TYPE to an ELF SHT_xxx value.  */
377a2e2270fSchristos 
378a2e2270fSchristos typedef
379a2e2270fSchristos enum ld_plugin_status
380a2e2270fSchristos (*ld_plugin_get_input_section_type) (const struct ld_plugin_section section,
381a2e2270fSchristos                                      unsigned int *type);
382a2e2270fSchristos 
383a2e2270fSchristos /* The linker's interface for retrieving the name of a specific section in
384a2e2270fSchristos    an object. This interface should only be invoked in the claim_file handler.
385a2e2270fSchristos    This function sets *SECTION_NAME_PTR to a null-terminated buffer allocated
386a2e2270fSchristos    by malloc.  The plugin must free *SECTION_NAME_PTR.  */
387a2e2270fSchristos 
388a2e2270fSchristos typedef
389a2e2270fSchristos enum ld_plugin_status
390a2e2270fSchristos (*ld_plugin_get_input_section_name) (const struct ld_plugin_section section,
391a2e2270fSchristos                                      char **section_name_ptr);
392a2e2270fSchristos 
393a2e2270fSchristos /* The linker's interface for retrieving the contents of a specific section
394a2e2270fSchristos    in an object.  This interface should only be invoked in the claim_file
395a2e2270fSchristos    handler.  This function sets *SECTION_CONTENTS to point to a buffer that is
396a2e2270fSchristos    valid until clam_file handler returns.  It sets *LEN to the size of the
397a2e2270fSchristos    buffer.  */
398a2e2270fSchristos 
399a2e2270fSchristos typedef
400a2e2270fSchristos enum ld_plugin_status
401a2e2270fSchristos (*ld_plugin_get_input_section_contents) (const struct ld_plugin_section section,
402a2e2270fSchristos                                          const unsigned char **section_contents,
403a2e2270fSchristos                                          size_t* len);
404a2e2270fSchristos 
405a2e2270fSchristos /* The linker's interface for specifying the desired order of sections.
406a2e2270fSchristos    The sections should be specifed using the array SECTION_LIST in the
407a2e2270fSchristos    order in which they should appear in the final layout.  NUM_SECTIONS
408a2e2270fSchristos    specifies the number of entries in each array.  This should be invoked
409a2e2270fSchristos    in the all_symbols_read handler.  */
410a2e2270fSchristos 
411a2e2270fSchristos typedef
412a2e2270fSchristos enum ld_plugin_status
413a2e2270fSchristos (*ld_plugin_update_section_order) (const struct ld_plugin_section *section_list,
414a2e2270fSchristos 				   unsigned int num_sections);
415a2e2270fSchristos 
416a2e2270fSchristos /* The linker's interface for specifying that reordering of sections is
417a2e2270fSchristos    desired so that the linker can prepare for it.  This should be invoked
418a2e2270fSchristos    before update_section_order, preferably in the claim_file handler.  */
419a2e2270fSchristos 
420a2e2270fSchristos typedef
421a2e2270fSchristos enum ld_plugin_status
422a2e2270fSchristos (*ld_plugin_allow_section_ordering) (void);
423a2e2270fSchristos 
424a2e2270fSchristos /* The linker's interface for specifying that a subset of sections is
425a2e2270fSchristos    to be mapped to a unique segment.  If the plugin wants to call
426a2e2270fSchristos    unique_segment_for_sections, it must call this function from a
427a2e2270fSchristos    claim_file_handler or when it is first loaded.  */
428a2e2270fSchristos 
429a2e2270fSchristos typedef
430a2e2270fSchristos enum ld_plugin_status
431a2e2270fSchristos (*ld_plugin_allow_unique_segment_for_sections) (void);
432a2e2270fSchristos 
433a2e2270fSchristos /* The linker's interface for specifying that a specific set of sections
434a2e2270fSchristos    must be mapped to a unique segment.  ELF segments do not have names
435a2e2270fSchristos    and the NAME is used as the name of the newly created output section
436a2e2270fSchristos    that is then placed in the unique PT_LOAD segment.  FLAGS is used to
437a2e2270fSchristos    specify if any additional segment flags need to be set.  For instance,
438a2e2270fSchristos    a specific segment flag can be set to identify this segment.  Unsetting
439a2e2270fSchristos    segment flags that would be set by default is not possible.  The
440a2e2270fSchristos    parameter SEGMENT_ALIGNMENT when non-zero will override the default.  */
441a2e2270fSchristos 
442a2e2270fSchristos typedef
443a2e2270fSchristos enum ld_plugin_status
444a2e2270fSchristos (*ld_plugin_unique_segment_for_sections) (
445a2e2270fSchristos     const char* segment_name,
446a2e2270fSchristos     uint64_t segment_flags,
447a2e2270fSchristos     uint64_t segment_alignment,
448a2e2270fSchristos     const struct ld_plugin_section * section_list,
449a2e2270fSchristos     unsigned int num_sections);
450a2e2270fSchristos 
451ba340e45Schristos /* The linker's interface for retrieving the section alignment requirement
452ba340e45Schristos    of a specific section in an object.  This interface should only be invoked in the
453ba340e45Schristos    claim_file handler.  This function sets *ADDRALIGN to the ELF sh_addralign
454ba340e45Schristos    value of the input section.  */
455ba340e45Schristos 
456ba340e45Schristos typedef
457ba340e45Schristos enum ld_plugin_status
458ba340e45Schristos (*ld_plugin_get_input_section_alignment) (const struct ld_plugin_section section,
459ba340e45Schristos                                           unsigned int *addralign);
460ba340e45Schristos 
461ba340e45Schristos /* The linker's interface for retrieving the section size of a specific section
462ba340e45Schristos    in an object.  This interface should only be invoked in the claim_file handler.
463ba340e45Schristos    This function sets *SECSIZE to the ELF sh_size
464ba340e45Schristos    value of the input section.  */
465ba340e45Schristos 
466ba340e45Schristos typedef
467ba340e45Schristos enum ld_plugin_status
468ba340e45Schristos (*ld_plugin_get_input_section_size) (const struct ld_plugin_section section,
469ba340e45Schristos                                      uint64_t *secsize);
470ba340e45Schristos 
4714559860eSchristos typedef
4724559860eSchristos enum ld_plugin_status
4734559860eSchristos (*ld_plugin_new_input_handler) (const struct ld_plugin_input_file *file);
4744559860eSchristos 
4754559860eSchristos /* The linker's interface for registering the "new_input" handler. This handler
4764559860eSchristos    will be notified when a new input file has been added after the
4774559860eSchristos    all_symbols_read event, allowing the plugin to, for example, set a unique
4784559860eSchristos    segment for sections in plugin-generated input files. */
4794559860eSchristos 
4804559860eSchristos typedef
4814559860eSchristos enum ld_plugin_status
4824559860eSchristos (*ld_plugin_register_new_input) (ld_plugin_new_input_handler handler);
4834559860eSchristos 
4844559860eSchristos /* The linker's interface for getting the list of wrapped symbols using the
4854559860eSchristos    --wrap option. This sets *NUM_SYMBOLS to number of wrapped symbols and
4864559860eSchristos    *WRAP_SYMBOL_LIST to the list of wrapped symbols. */
4874559860eSchristos 
4884559860eSchristos typedef
4894559860eSchristos enum ld_plugin_status
4904559860eSchristos (*ld_plugin_get_wrap_symbols) (uint64_t *num_symbols,
4914559860eSchristos                                const char ***wrap_symbol_list);
4924559860eSchristos 
49398b9484cSchristos enum ld_plugin_level
49498b9484cSchristos {
49598b9484cSchristos   LDPL_INFO,
49698b9484cSchristos   LDPL_WARNING,
49798b9484cSchristos   LDPL_ERROR,
49898b9484cSchristos   LDPL_FATAL
49998b9484cSchristos };
50098b9484cSchristos 
5014b169a6bSchristos /* Contract between a plug-in and a linker.  */
5024b169a6bSchristos 
5034b169a6bSchristos enum linker_api_version
5044b169a6bSchristos {
5054b169a6bSchristos    /* The linker/plugin do not implement any of the API levels below, the API
5064b169a6bSchristos        is determined solely via the transfer vector.  */
5074b169a6bSchristos    LAPI_V0,
5084b169a6bSchristos 
5094b169a6bSchristos    /* API level v1.  The linker provides get_symbols_v3, add_symbols_v2,
5104b169a6bSchristos       the plugin will use that and not any lower versions.
5114b169a6bSchristos       claim_file is thread-safe on the plugin side and
5124b169a6bSchristos       add_symbols on the linker side.  */
5134b169a6bSchristos    LAPI_V1
5144b169a6bSchristos };
5154b169a6bSchristos 
5164b169a6bSchristos /* The linker's interface for API version negotiation.  A plug-in calls
5174b169a6bSchristos   the function (with its IDENTIFIER and VERSION), plus minimal and maximal
5184b169a6bSchristos   version of linker_api_version is provided.  Linker then returns selected
5194b169a6bSchristos   API version and provides its IDENTIFIER and VERSION.  The returned value
5204b169a6bSchristos   by linker must be in range [MINIMAL_API_SUPPORTED, MAXIMAL_API_SUPPORTED].
5214b169a6bSchristos   Identifier pointers remain valid as long as the plugin is loaded.  */
5224b169a6bSchristos 
5234b169a6bSchristos typedef
5244b169a6bSchristos int
5254b169a6bSchristos (*ld_plugin_get_api_version) (const char *plugin_identifier,
5264b169a6bSchristos 			      const char *plugin_version,
5274b169a6bSchristos 			      int minimal_api_supported,
5284b169a6bSchristos 			      int maximal_api_supported,
5294b169a6bSchristos 			      const char **linker_identifier,
5304b169a6bSchristos 			      const char **linker_version);
5314b169a6bSchristos 
53298b9484cSchristos /* Values for the tv_tag field of the transfer vector.  */
53398b9484cSchristos 
53498b9484cSchristos enum ld_plugin_tag
53598b9484cSchristos {
5364b169a6bSchristos   LDPT_NULL,
5374b169a6bSchristos   LDPT_API_VERSION,
5384b169a6bSchristos   LDPT_GOLD_VERSION,
5394b169a6bSchristos   LDPT_LINKER_OUTPUT,
5404b169a6bSchristos   LDPT_OPTION,
5414b169a6bSchristos   LDPT_REGISTER_CLAIM_FILE_HOOK,
5424b169a6bSchristos   LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
5434b169a6bSchristos   LDPT_REGISTER_CLEANUP_HOOK,
5444b169a6bSchristos   LDPT_ADD_SYMBOLS,
5454b169a6bSchristos   LDPT_GET_SYMBOLS,
5464b169a6bSchristos   LDPT_ADD_INPUT_FILE,
5474b169a6bSchristos   LDPT_MESSAGE,
5484b169a6bSchristos   LDPT_GET_INPUT_FILE,
5494b169a6bSchristos   LDPT_RELEASE_INPUT_FILE,
5504b169a6bSchristos   LDPT_ADD_INPUT_LIBRARY,
5514b169a6bSchristos   LDPT_OUTPUT_NAME,
5524b169a6bSchristos   LDPT_SET_EXTRA_LIBRARY_PATH,
5534b169a6bSchristos   LDPT_GNU_LD_VERSION,
5544b169a6bSchristos   LDPT_GET_VIEW,
5554b169a6bSchristos   LDPT_GET_INPUT_SECTION_COUNT,
5564b169a6bSchristos   LDPT_GET_INPUT_SECTION_TYPE,
5574b169a6bSchristos   LDPT_GET_INPUT_SECTION_NAME,
5584b169a6bSchristos   LDPT_GET_INPUT_SECTION_CONTENTS,
5594b169a6bSchristos   LDPT_UPDATE_SECTION_ORDER,
5604b169a6bSchristos   LDPT_ALLOW_SECTION_ORDERING,
5614b169a6bSchristos   LDPT_GET_SYMBOLS_V2,
5624b169a6bSchristos   LDPT_ALLOW_UNIQUE_SEGMENT_FOR_SECTIONS,
5634b169a6bSchristos   LDPT_UNIQUE_SEGMENT_FOR_SECTIONS,
5644b169a6bSchristos   LDPT_GET_SYMBOLS_V3,
5654b169a6bSchristos   LDPT_GET_INPUT_SECTION_ALIGNMENT,
5664b169a6bSchristos   LDPT_GET_INPUT_SECTION_SIZE,
5674b169a6bSchristos   LDPT_REGISTER_NEW_INPUT_HOOK,
5684b169a6bSchristos   LDPT_GET_WRAP_SYMBOLS,
5694b169a6bSchristos   LDPT_ADD_SYMBOLS_V2,
5704b169a6bSchristos   LDPT_GET_API_VERSION,
571*e663ba6eSchristos   LDPT_REGISTER_CLAIM_FILE_HOOK_V2
57298b9484cSchristos };
57398b9484cSchristos 
57498b9484cSchristos /* The plugin transfer vector.  */
57598b9484cSchristos 
57698b9484cSchristos struct ld_plugin_tv
57798b9484cSchristos {
57898b9484cSchristos   enum ld_plugin_tag tv_tag;
57998b9484cSchristos   union
58098b9484cSchristos   {
58198b9484cSchristos     int tv_val;
58298b9484cSchristos     const char *tv_string;
58398b9484cSchristos     ld_plugin_register_claim_file tv_register_claim_file;
584*e663ba6eSchristos     ld_plugin_register_claim_file_v2 tv_register_claim_file_v2;
58598b9484cSchristos     ld_plugin_register_all_symbols_read tv_register_all_symbols_read;
58698b9484cSchristos     ld_plugin_register_cleanup tv_register_cleanup;
58798b9484cSchristos     ld_plugin_add_symbols tv_add_symbols;
58898b9484cSchristos     ld_plugin_get_symbols tv_get_symbols;
58998b9484cSchristos     ld_plugin_add_input_file tv_add_input_file;
59098b9484cSchristos     ld_plugin_message tv_message;
59198b9484cSchristos     ld_plugin_get_input_file tv_get_input_file;
59298b9484cSchristos     ld_plugin_get_view tv_get_view;
59398b9484cSchristos     ld_plugin_release_input_file tv_release_input_file;
59498b9484cSchristos     ld_plugin_add_input_library tv_add_input_library;
59598b9484cSchristos     ld_plugin_set_extra_library_path tv_set_extra_library_path;
596a2e2270fSchristos     ld_plugin_get_input_section_count tv_get_input_section_count;
597a2e2270fSchristos     ld_plugin_get_input_section_type tv_get_input_section_type;
598a2e2270fSchristos     ld_plugin_get_input_section_name tv_get_input_section_name;
599a2e2270fSchristos     ld_plugin_get_input_section_contents tv_get_input_section_contents;
600a2e2270fSchristos     ld_plugin_update_section_order tv_update_section_order;
601a2e2270fSchristos     ld_plugin_allow_section_ordering tv_allow_section_ordering;
602a2e2270fSchristos     ld_plugin_allow_unique_segment_for_sections tv_allow_unique_segment_for_sections;
603a2e2270fSchristos     ld_plugin_unique_segment_for_sections tv_unique_segment_for_sections;
604ba340e45Schristos     ld_plugin_get_input_section_alignment tv_get_input_section_alignment;
605ba340e45Schristos     ld_plugin_get_input_section_size tv_get_input_section_size;
6064559860eSchristos     ld_plugin_register_new_input tv_register_new_input;
6074559860eSchristos     ld_plugin_get_wrap_symbols tv_get_wrap_symbols;
6084b169a6bSchristos     ld_plugin_get_api_version tv_get_api_version;
60998b9484cSchristos   } tv_u;
61098b9484cSchristos };
61198b9484cSchristos 
61298b9484cSchristos /* The plugin library's "onload" entry point.  */
61398b9484cSchristos 
61498b9484cSchristos typedef
61598b9484cSchristos enum ld_plugin_status
61698b9484cSchristos (*ld_plugin_onload) (struct ld_plugin_tv *tv);
61798b9484cSchristos 
61898b9484cSchristos #ifdef __cplusplus
61998b9484cSchristos }
62098b9484cSchristos #endif
62198b9484cSchristos 
62298b9484cSchristos #endif /* !defined(PLUGIN_API_H) */
623