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