198b9484cSchristos /* simple-object-common.h -- common structs for object file manipulation. 2*5173eb0aSchristos Copyright (C) 2010-2024 Free Software Foundation, Inc. 398b9484cSchristos 498b9484cSchristos This file is part of the libiberty library. 598b9484cSchristos Libiberty is free software; you can redistribute it and/or 698b9484cSchristos modify it under the terms of the GNU Library General Public 798b9484cSchristos License as published by the Free Software Foundation; either 898b9484cSchristos version 2 of the License, or (at your option) any later version. 998b9484cSchristos 1098b9484cSchristos Libiberty is distributed in the hope that it will be useful, 1198b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1298b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1398b9484cSchristos Library General Public License for more details. 1498b9484cSchristos 1598b9484cSchristos You should have received a copy of the GNU Library General Public 1698b9484cSchristos License along with libiberty; see the file COPYING.LIB. If not, 1798b9484cSchristos write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 1898b9484cSchristos Boston, MA 02110-1301, USA. */ 1998b9484cSchristos 2098b9484cSchristos /* Forward reference. */ 2198b9484cSchristos struct simple_object_functions; 2298b9484cSchristos 2398b9484cSchristos /* An object file opened for reading. */ 2498b9484cSchristos 2598b9484cSchristos struct simple_object_read_struct 2698b9484cSchristos { 2798b9484cSchristos /* The file descriptor. */ 2898b9484cSchristos int descriptor; 2998b9484cSchristos /* The offset within the file. */ 3098b9484cSchristos off_t offset; 3198b9484cSchristos /* The functions which do the actual work. */ 3298b9484cSchristos const struct simple_object_functions *functions; 3398b9484cSchristos /* Private data for the object file format. */ 3498b9484cSchristos void *data; 3598b9484cSchristos }; 3698b9484cSchristos 3798b9484cSchristos /* Object file attributes. */ 3898b9484cSchristos 3998b9484cSchristos struct simple_object_attributes_struct 4098b9484cSchristos { 4198b9484cSchristos /* The functions which do the actual work. */ 4298b9484cSchristos const struct simple_object_functions *functions; 4398b9484cSchristos /* Private data for the object file format. */ 4498b9484cSchristos void *data; 4598b9484cSchristos }; 4698b9484cSchristos 4798b9484cSchristos /* An object file being created. */ 4898b9484cSchristos 4998b9484cSchristos struct simple_object_write_struct 5098b9484cSchristos { 5198b9484cSchristos /* The functions which do the actual work. */ 5298b9484cSchristos const struct simple_object_functions *functions; 5398b9484cSchristos /* The segment_name argument from the user. */ 5498b9484cSchristos char *segment_name; 5598b9484cSchristos /* The start of the list of sections. */ 5698b9484cSchristos simple_object_write_section *sections; 5798b9484cSchristos /* The last entry in the list of sections. */ 5898b9484cSchristos simple_object_write_section *last_section; 5998b9484cSchristos /* Private data for the object file format. */ 6098b9484cSchristos void *data; 6198b9484cSchristos }; 6298b9484cSchristos 6398b9484cSchristos /* A section in an object file being created. */ 6498b9484cSchristos 6598b9484cSchristos struct simple_object_write_section_struct 6698b9484cSchristos { 6798b9484cSchristos /* Next in the list of sections attached to an 6898b9484cSchristos simple_object_write. */ 6998b9484cSchristos simple_object_write_section *next; 7098b9484cSchristos /* The name of this section. */ 7198b9484cSchristos char *name; 7298b9484cSchristos /* The required alignment. */ 7398b9484cSchristos unsigned int align; 7498b9484cSchristos /* The first data attached to this section. */ 7598b9484cSchristos struct simple_object_write_section_buffer *buffers; 7698b9484cSchristos /* The last data attached to this section. */ 7798b9484cSchristos struct simple_object_write_section_buffer *last_buffer; 7898b9484cSchristos }; 7998b9484cSchristos 8098b9484cSchristos /* Data attached to a section. */ 8198b9484cSchristos 8298b9484cSchristos struct simple_object_write_section_buffer 8398b9484cSchristos { 8498b9484cSchristos /* The next data for this section. */ 8598b9484cSchristos struct simple_object_write_section_buffer *next; 8698b9484cSchristos /* The size of the buffer. */ 8798b9484cSchristos size_t size; 8898b9484cSchristos /* The actual bytes. */ 8998b9484cSchristos const void *buffer; 9098b9484cSchristos /* A buffer to free, or NULL. */ 9198b9484cSchristos void *free_buffer; 9298b9484cSchristos }; 9398b9484cSchristos 9498b9484cSchristos /* The number of bytes we read from the start of the file to pass to 9598b9484cSchristos the match function. */ 9698b9484cSchristos #define SIMPLE_OBJECT_MATCH_HEADER_LEN (16) 9798b9484cSchristos 9898b9484cSchristos /* Format-specific object file functions. */ 9998b9484cSchristos 10098b9484cSchristos struct simple_object_functions 10198b9484cSchristos { 10298b9484cSchristos /* If this file matches these functions, return a new value for the 10398b9484cSchristos private data for an simple_object_read. HEADER is the first 16 10498b9484cSchristos bytes of the file. DESCRIPTOR, OFFSET, SEGMENT_NAME, ERRMSG, and 10598b9484cSchristos ERR are as for simple_object_open_read. If this file does not 10698b9484cSchristos match, this function should return NULL with *ERRMSG set to 10798b9484cSchristos NULL. */ 10898b9484cSchristos void *(*match) (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN], 10998b9484cSchristos int descriptor, off_t offset, const char *segment_name, 11098b9484cSchristos const char **errmsg, int *err); 11198b9484cSchristos 11298b9484cSchristos /* Implement simple_object_find_sections. */ 11398b9484cSchristos const char *(*find_sections) (simple_object_read *, 11498b9484cSchristos int (*pfn) (void *, const char *, 11598b9484cSchristos off_t offset, off_t length), 11698b9484cSchristos void *data, 11798b9484cSchristos int *err); 11898b9484cSchristos 11998b9484cSchristos /* Return the private data for the attributes for SOBJ. */ 12098b9484cSchristos void *(*fetch_attributes) (simple_object_read *sobj, const char **errmsg, 12198b9484cSchristos int *err); 12298b9484cSchristos 12398b9484cSchristos /* Release the private data for an simple_object_read. */ 12498b9484cSchristos void (*release_read) (void *); 12598b9484cSchristos 12698b9484cSchristos /* Merge the private data for the attributes of two files. If they 12798b9484cSchristos could be linked together, return NULL. Otherwise return an error 12898b9484cSchristos message. */ 12998b9484cSchristos const char *(*attributes_merge) (void *, void *, int *err); 13098b9484cSchristos 13198b9484cSchristos /* Release the private data for an simple_object_attributes. */ 13298b9484cSchristos void (*release_attributes) (void *); 13398b9484cSchristos 13498b9484cSchristos /* Start creating an object file. */ 13598b9484cSchristos void *(*start_write) (void *attributes_data, const char **errmsg, 13698b9484cSchristos int *err); 13798b9484cSchristos 13898b9484cSchristos /* Write the complete object file. */ 13998b9484cSchristos const char *(*write_to_file) (simple_object_write *sobj, int descriptor, 14098b9484cSchristos int *err); 14198b9484cSchristos 14298b9484cSchristos /* Release the private data for an simple_object_write. */ 14398b9484cSchristos void (*release_write) (void *); 1444559860eSchristos 1454559860eSchristos /* Copy LTO debug sections. */ 1464559860eSchristos const char *(*copy_lto_debug_sections) (simple_object_read *sobj, 1474559860eSchristos simple_object_write *dobj, 1484559860eSchristos char *(*pfn) (const char *), 1494559860eSchristos int *err); 15098b9484cSchristos }; 15198b9484cSchristos 15298b9484cSchristos /* The known object file formats. */ 15398b9484cSchristos 15498b9484cSchristos extern const struct simple_object_functions simple_object_coff_functions; 15598b9484cSchristos extern const struct simple_object_functions simple_object_elf_functions; 15698b9484cSchristos extern const struct simple_object_functions simple_object_mach_o_functions; 157a2e2270fSchristos extern const struct simple_object_functions simple_object_xcoff_functions; 15898b9484cSchristos 15998b9484cSchristos /* Read SIZE bytes from DESCRIPTOR at file offset OFFSET into BUFFER. 16098b9484cSchristos Return non-zero on success. On failure return 0 and set *ERRMSG 16198b9484cSchristos and *ERR. */ 16298b9484cSchristos 16398b9484cSchristos extern int 16498b9484cSchristos simple_object_internal_read (int descriptor, off_t offset, 16598b9484cSchristos unsigned char *buffer, size_t size, 16698b9484cSchristos const char **errmsg, int *err); 16798b9484cSchristos 16898b9484cSchristos /* Write SIZE bytes from BUFFER to DESCRIPTOR at file offset OFFSET. 16998b9484cSchristos Return non-zero on success. On failure return 0 and set *ERRMSG 17098b9484cSchristos and *ERR. */ 17198b9484cSchristos 17298b9484cSchristos extern int 17398b9484cSchristos simple_object_internal_write (int descriptor, off_t offset, 17498b9484cSchristos const unsigned char *buffer, size_t size, 17598b9484cSchristos const char **errmsg, int *err); 17698b9484cSchristos 17798b9484cSchristos /* Define ulong_type as an unsigned 64-bit type if available. 17898b9484cSchristos Otherwise just make it unsigned long. */ 17998b9484cSchristos 18098b9484cSchristos #ifdef UNSIGNED_64BIT_TYPE 18198b9484cSchristos __extension__ typedef UNSIGNED_64BIT_TYPE ulong_type; 18298b9484cSchristos #else 18398b9484cSchristos typedef unsigned long ulong_type; 18498b9484cSchristos #endif 18598b9484cSchristos 18698b9484cSchristos /* Fetch a big-endian 16-bit value. */ 18798b9484cSchristos 18898b9484cSchristos static inline unsigned short 18998b9484cSchristos simple_object_fetch_big_16 (const unsigned char *buf) 19098b9484cSchristos { 19198b9484cSchristos return ((unsigned short) buf[0] << 8) | (unsigned short) buf[1]; 19298b9484cSchristos } 19398b9484cSchristos 19498b9484cSchristos /* Fetch a little-endian 16-bit value. */ 19598b9484cSchristos 19698b9484cSchristos static inline unsigned short 19798b9484cSchristos simple_object_fetch_little_16 (const unsigned char *buf) 19898b9484cSchristos { 19998b9484cSchristos return ((unsigned short) buf[1] << 8) | (unsigned short) buf[0]; 20098b9484cSchristos } 20198b9484cSchristos 20298b9484cSchristos /* Fetch a big-endian 32-bit value. */ 20398b9484cSchristos 20498b9484cSchristos static inline unsigned int 20598b9484cSchristos simple_object_fetch_big_32 (const unsigned char *buf) 20698b9484cSchristos { 20798b9484cSchristos return (((unsigned int) buf[0] << 24) 20898b9484cSchristos | ((unsigned int) buf[1] << 16) 20998b9484cSchristos | ((unsigned int) buf[2] << 8) 21098b9484cSchristos | (unsigned int) buf[3]); 21198b9484cSchristos } 21298b9484cSchristos 21398b9484cSchristos /* Fetch a little-endian 32-bit value. */ 21498b9484cSchristos 21598b9484cSchristos static inline unsigned int 21698b9484cSchristos simple_object_fetch_little_32 (const unsigned char *buf) 21798b9484cSchristos { 21898b9484cSchristos return (((unsigned int) buf[3] << 24) 21998b9484cSchristos | ((unsigned int) buf[2] << 16) 22098b9484cSchristos | ((unsigned int) buf[1] << 8) 22198b9484cSchristos | (unsigned int) buf[0]); 22298b9484cSchristos } 22398b9484cSchristos 22498b9484cSchristos /* Fetch a big-endian 32-bit value as a ulong_type. */ 22598b9484cSchristos 22698b9484cSchristos static inline ulong_type 22798b9484cSchristos simple_object_fetch_big_32_ulong (const unsigned char *buf) 22898b9484cSchristos { 22998b9484cSchristos return (ulong_type) simple_object_fetch_big_32 (buf); 23098b9484cSchristos } 23198b9484cSchristos 23298b9484cSchristos /* Fetch a little-endian 32-bit value as a ulong_type. */ 23398b9484cSchristos 23498b9484cSchristos static inline ulong_type 23598b9484cSchristos simple_object_fetch_little_32_ulong (const unsigned char *buf) 23698b9484cSchristos { 23798b9484cSchristos return (ulong_type) simple_object_fetch_little_32 (buf); 23898b9484cSchristos } 23998b9484cSchristos 24098b9484cSchristos #ifdef UNSIGNED_64BIT_TYPE 24198b9484cSchristos 24298b9484cSchristos /* Fetch a big-endian 64-bit value. */ 24398b9484cSchristos 24498b9484cSchristos static inline ulong_type 24598b9484cSchristos simple_object_fetch_big_64 (const unsigned char *buf) 24698b9484cSchristos { 24798b9484cSchristos return (((ulong_type) buf[0] << 56) 24898b9484cSchristos | ((ulong_type) buf[1] << 48) 24998b9484cSchristos | ((ulong_type) buf[2] << 40) 25098b9484cSchristos | ((ulong_type) buf[3] << 32) 25198b9484cSchristos | ((ulong_type) buf[4] << 24) 25298b9484cSchristos | ((ulong_type) buf[5] << 16) 25398b9484cSchristos | ((ulong_type) buf[6] << 8) 25498b9484cSchristos | (ulong_type) buf[7]); 25598b9484cSchristos } 25698b9484cSchristos 25798b9484cSchristos /* Fetch a little-endian 64-bit value. */ 25898b9484cSchristos 25998b9484cSchristos static inline ulong_type 26098b9484cSchristos simple_object_fetch_little_64 (const unsigned char *buf) 26198b9484cSchristos { 26298b9484cSchristos return (((ulong_type) buf[7] << 56) 26398b9484cSchristos | ((ulong_type) buf[6] << 48) 26498b9484cSchristos | ((ulong_type) buf[5] << 40) 26598b9484cSchristos | ((ulong_type) buf[4] << 32) 26698b9484cSchristos | ((ulong_type) buf[3] << 24) 26798b9484cSchristos | ((ulong_type) buf[2] << 16) 26898b9484cSchristos | ((ulong_type) buf[1] << 8) 26998b9484cSchristos | (ulong_type) buf[0]); 27098b9484cSchristos } 27198b9484cSchristos 27298b9484cSchristos #endif 27398b9484cSchristos 27498b9484cSchristos /* Store a big-endian 16-bit value. */ 27598b9484cSchristos 27698b9484cSchristos static inline void 27798b9484cSchristos simple_object_set_big_16 (unsigned char *buf, unsigned short val) 27898b9484cSchristos { 27998b9484cSchristos buf[0] = (val >> 8) & 0xff; 28098b9484cSchristos buf[1] = val & 0xff; 28198b9484cSchristos } 28298b9484cSchristos 28398b9484cSchristos /* Store a little-endian 16-bit value. */ 28498b9484cSchristos 28598b9484cSchristos static inline void 28698b9484cSchristos simple_object_set_little_16 (unsigned char *buf, unsigned short val) 28798b9484cSchristos { 28898b9484cSchristos buf[1] = (val >> 8) & 0xff; 28998b9484cSchristos buf[0] = val & 0xff; 29098b9484cSchristos } 29198b9484cSchristos 29298b9484cSchristos /* Store a big-endian 32-bit value. */ 29398b9484cSchristos 29498b9484cSchristos static inline void 29598b9484cSchristos simple_object_set_big_32 (unsigned char *buf, unsigned int val) 29698b9484cSchristos { 29798b9484cSchristos buf[0] = (val >> 24) & 0xff; 29898b9484cSchristos buf[1] = (val >> 16) & 0xff; 29998b9484cSchristos buf[2] = (val >> 8) & 0xff; 30098b9484cSchristos buf[3] = val & 0xff; 30198b9484cSchristos } 30298b9484cSchristos 30398b9484cSchristos /* Store a little-endian 32-bit value. */ 30498b9484cSchristos 30598b9484cSchristos static inline void 30698b9484cSchristos simple_object_set_little_32 (unsigned char *buf, unsigned int val) 30798b9484cSchristos { 30898b9484cSchristos buf[3] = (val >> 24) & 0xff; 30998b9484cSchristos buf[2] = (val >> 16) & 0xff; 31098b9484cSchristos buf[1] = (val >> 8) & 0xff; 31198b9484cSchristos buf[0] = val & 0xff; 31298b9484cSchristos } 31398b9484cSchristos 31498b9484cSchristos /* Store a big-endian 32-bit value coming in as a ulong_type. */ 31598b9484cSchristos 31698b9484cSchristos static inline void 31798b9484cSchristos simple_object_set_big_32_ulong (unsigned char *buf, ulong_type val) 31898b9484cSchristos { 31998b9484cSchristos simple_object_set_big_32 (buf, val); 32098b9484cSchristos } 32198b9484cSchristos 32298b9484cSchristos /* Store a little-endian 32-bit value coming in as a ulong_type. */ 32398b9484cSchristos 32498b9484cSchristos static inline void 32598b9484cSchristos simple_object_set_little_32_ulong (unsigned char *buf, ulong_type val) 32698b9484cSchristos { 32798b9484cSchristos simple_object_set_little_32 (buf, val); 32898b9484cSchristos } 32998b9484cSchristos 33098b9484cSchristos #ifdef UNSIGNED_64BIT_TYPE 33198b9484cSchristos 33298b9484cSchristos /* Store a big-endian 64-bit value. */ 33398b9484cSchristos 33498b9484cSchristos static inline void 33598b9484cSchristos simple_object_set_big_64 (unsigned char *buf, ulong_type val) 33698b9484cSchristos { 33798b9484cSchristos buf[0] = (val >> 56) & 0xff; 33898b9484cSchristos buf[1] = (val >> 48) & 0xff; 33998b9484cSchristos buf[2] = (val >> 40) & 0xff; 34098b9484cSchristos buf[3] = (val >> 32) & 0xff; 34198b9484cSchristos buf[4] = (val >> 24) & 0xff; 34298b9484cSchristos buf[5] = (val >> 16) & 0xff; 34398b9484cSchristos buf[6] = (val >> 8) & 0xff; 34498b9484cSchristos buf[7] = val & 0xff; 34598b9484cSchristos } 34698b9484cSchristos 34798b9484cSchristos /* Store a little-endian 64-bit value. */ 34898b9484cSchristos 34998b9484cSchristos static inline void 35098b9484cSchristos simple_object_set_little_64 (unsigned char *buf, ulong_type val) 35198b9484cSchristos { 35298b9484cSchristos buf[7] = (val >> 56) & 0xff; 35398b9484cSchristos buf[6] = (val >> 48) & 0xff; 35498b9484cSchristos buf[5] = (val >> 40) & 0xff; 35598b9484cSchristos buf[4] = (val >> 32) & 0xff; 35698b9484cSchristos buf[3] = (val >> 24) & 0xff; 35798b9484cSchristos buf[2] = (val >> 16) & 0xff; 35898b9484cSchristos buf[1] = (val >> 8) & 0xff; 35998b9484cSchristos buf[0] = val & 0xff; 36098b9484cSchristos } 36198b9484cSchristos 36298b9484cSchristos #endif 363