diff options
Diffstat (limited to 'gcc-4.7/libiberty/simple-object-coff.c')
-rw-r--r-- | gcc-4.7/libiberty/simple-object-coff.c | 804 |
1 files changed, 0 insertions, 804 deletions
diff --git a/gcc-4.7/libiberty/simple-object-coff.c b/gcc-4.7/libiberty/simple-object-coff.c deleted file mode 100644 index a7802a520..000000000 --- a/gcc-4.7/libiberty/simple-object-coff.c +++ /dev/null @@ -1,804 +0,0 @@ -/* simple-object-coff.c -- routines to manipulate COFF object files. - Copyright 2010 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Google. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, 51 Franklin Street - Fifth Floor, -Boston, MA 02110-1301, USA. */ - -#include "config.h" -#include "libiberty.h" -#include "simple-object.h" - -#include <errno.h> -#include <stddef.h> - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif - -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#ifdef HAVE_INTTYPES_H -#include <inttypes.h> -#endif - -#include "simple-object-common.h" - -/* COFF structures and constants. */ - -/* COFF file header. */ - -struct external_filehdr -{ - unsigned char f_magic[2]; /* magic number */ - unsigned char f_nscns[2]; /* number of sections */ - unsigned char f_timdat[4]; /* time & date stamp */ - unsigned char f_symptr[4]; /* file pointer to symtab */ - unsigned char f_nsyms[4]; /* number of symtab entries */ - unsigned char f_opthdr[2]; /* sizeof(optional hdr) */ - unsigned char f_flags[2]; /* flags */ -}; - -/* Bits for filehdr f_flags field. */ - -#define F_EXEC (0x0002) -#define IMAGE_FILE_SYSTEM (0x1000) -#define IMAGE_FILE_DLL (0x2000) - -/* COFF section header. */ - -struct external_scnhdr -{ - unsigned char s_name[8]; /* section name */ - unsigned char s_paddr[4]; /* physical address, aliased s_nlib */ - unsigned char s_vaddr[4]; /* virtual address */ - unsigned char s_size[4]; /* section size */ - unsigned char s_scnptr[4]; /* file ptr to raw data for section */ - unsigned char s_relptr[4]; /* file ptr to relocation */ - unsigned char s_lnnoptr[4]; /* file ptr to line numbers */ - unsigned char s_nreloc[2]; /* number of relocation entries */ - unsigned char s_nlnno[2]; /* number of line number entries */ - unsigned char s_flags[4]; /* flags */ -}; - -/* The length of the s_name field in struct external_scnhdr. */ - -#define SCNNMLEN (8) - -/* Bits for scnhdr s_flags field. This includes some bits defined - only for PE. This may need to be moved into coff_magic. */ - -#define STYP_DATA (1 << 6) -#define IMAGE_SCN_MEM_DISCARDABLE (1 << 25) -#define IMAGE_SCN_MEM_SHARED (1 << 28) -#define IMAGE_SCN_MEM_READ (1 << 30) - -#define IMAGE_SCN_ALIGN_POWER_BIT_POS 20 -#define IMAGE_SCN_ALIGN_POWER_CONST(val) \ - (((val) + 1) << IMAGE_SCN_ALIGN_POWER_BIT_POS) - -/* COFF symbol table entry. */ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ - -struct external_syment -{ - union - { - unsigned char e_name[E_SYMNMLEN]; - - struct - { - unsigned char e_zeroes[4]; - unsigned char e_offset[4]; - } e; - } e; - - unsigned char e_value[4]; - unsigned char e_scnum[2]; - unsigned char e_type[2]; - unsigned char e_sclass[1]; - unsigned char e_numaux[1]; -}; - -/* Length allowed for filename in aux sym format 4. */ - -#define E_FILNMLEN 18 - -/* Omits x_sym and other unused variants. */ - -union external_auxent -{ - /* Aux sym format 4: file. */ - union - { - char x_fname[E_FILNMLEN]; - struct - { - unsigned char x_zeroes[4]; - unsigned char x_offset[4]; - } x_n; - } x_file; - /* Aux sym format 5: section. */ - struct - { - unsigned char x_scnlen[4]; /* section length */ - unsigned char x_nreloc[2]; /* # relocation entries */ - unsigned char x_nlinno[2]; /* # line numbers */ - unsigned char x_checksum[4]; /* section COMDAT checksum */ - unsigned char x_associated[2]; /* COMDAT assoc section index */ - unsigned char x_comdat[1]; /* COMDAT selection number */ - } x_scn; -}; - -/* Symbol-related constants. */ - -#define IMAGE_SYM_DEBUG (-2) -#define IMAGE_SYM_TYPE_NULL (0) -#define IMAGE_SYM_DTYPE_NULL (0) -#define IMAGE_SYM_CLASS_STATIC (3) -#define IMAGE_SYM_CLASS_FILE (103) - -#define IMAGE_SYM_TYPE \ - ((IMAGE_SYM_DTYPE_NULL << 4) | IMAGE_SYM_TYPE_NULL) - -/* Private data for an simple_object_read. */ - -struct simple_object_coff_read -{ - /* Magic number. */ - unsigned short magic; - /* Whether the file is big-endian. */ - unsigned char is_big_endian; - /* Number of sections. */ - unsigned short nscns; - /* File offset of symbol table. */ - off_t symptr; - /* Number of symbol table entries. */ - unsigned int nsyms; - /* Flags. */ - unsigned short flags; - /* Offset of section headers in file. */ - off_t scnhdr_offset; -}; - -/* Private data for an simple_object_attributes. */ - -struct simple_object_coff_attributes -{ - /* Magic number. */ - unsigned short magic; - /* Whether the file is big-endian. */ - unsigned char is_big_endian; - /* Flags. */ - unsigned short flags; -}; - -/* There is no magic number which indicates a COFF file as opposed to - any other sort of file. Instead, each COFF file starts with a - two-byte magic number which also indicates the type of the target. - This struct holds a magic number as well as characteristics of that - COFF format. */ - -struct coff_magic_struct -{ - /* Magic number. */ - unsigned short magic; - /* Whether this magic number is for a big-endian file. */ - unsigned char is_big_endian; - /* Flag bits, in the f_flags fields, which indicates that this file - is not a relocatable object file. There is no flag which - specifically indicates a relocatable object file, it is only - implied by the absence of these flags. */ - unsigned short non_object_flags; -}; - -/* This is a list of the COFF magic numbers which we recognize, namely - the ones used on Windows. More can be added as needed. */ - -static const struct coff_magic_struct coff_magic[] = -{ - /* i386. */ - { 0x14c, 0, F_EXEC | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL }, - /* x86_64. */ - { 0x8664, 0, F_EXEC | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL } -}; - -/* See if we have a COFF file. */ - -static void * -simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN], - int descriptor, off_t offset, - const char *segment_name ATTRIBUTE_UNUSED, - const char **errmsg, int *err) -{ - size_t c; - unsigned short magic_big; - unsigned short magic_little; - unsigned short magic; - size_t i; - int is_big_endian; - unsigned short (*fetch_16) (const unsigned char *); - unsigned int (*fetch_32) (const unsigned char *); - unsigned char hdrbuf[sizeof (struct external_filehdr)]; - unsigned short flags; - struct simple_object_coff_read *ocr; - - c = sizeof (coff_magic) / sizeof (coff_magic[0]); - magic_big = simple_object_fetch_big_16 (header); - magic_little = simple_object_fetch_little_16 (header); - for (i = 0; i < c; ++i) - { - if (coff_magic[i].is_big_endian - ? coff_magic[i].magic == magic_big - : coff_magic[i].magic == magic_little) - break; - } - if (i >= c) - { - *errmsg = NULL; - *err = 0; - return NULL; - } - is_big_endian = coff_magic[i].is_big_endian; - - magic = is_big_endian ? magic_big : magic_little; - fetch_16 = (is_big_endian - ? simple_object_fetch_big_16 - : simple_object_fetch_little_16); - fetch_32 = (is_big_endian - ? simple_object_fetch_big_32 - : simple_object_fetch_little_32); - - if (!simple_object_internal_read (descriptor, offset, hdrbuf, sizeof hdrbuf, - errmsg, err)) - return NULL; - - flags = fetch_16 (hdrbuf + offsetof (struct external_filehdr, f_flags)); - if ((flags & coff_magic[i].non_object_flags) != 0) - { - *errmsg = "not relocatable object file"; - *err = 0; - return NULL; - } - - ocr = XNEW (struct simple_object_coff_read); - ocr->magic = magic; - ocr->is_big_endian = is_big_endian; - ocr->nscns = fetch_16 (hdrbuf + offsetof (struct external_filehdr, f_nscns)); - ocr->symptr = fetch_32 (hdrbuf - + offsetof (struct external_filehdr, f_symptr)); - ocr->nsyms = fetch_32 (hdrbuf + offsetof (struct external_filehdr, f_nsyms)); - ocr->flags = flags; - ocr->scnhdr_offset = (sizeof (struct external_filehdr) - + fetch_16 (hdrbuf + offsetof (struct external_filehdr, - f_opthdr))); - - return (void *) ocr; -} - -/* Read the string table in a COFF file. */ - -static char * -simple_object_coff_read_strtab (simple_object_read *sobj, size_t *strtab_size, - const char **errmsg, int *err) -{ - struct simple_object_coff_read *ocr = - (struct simple_object_coff_read *) sobj->data; - off_t strtab_offset; - unsigned char strsizebuf[4]; - size_t strsize; - char *strtab; - - strtab_offset = sobj->offset + ocr->symptr - + ocr->nsyms * sizeof (struct external_syment); - if (!simple_object_internal_read (sobj->descriptor, strtab_offset, - strsizebuf, 4, errmsg, err)) - return NULL; - strsize = (ocr->is_big_endian - ? simple_object_fetch_big_32 (strsizebuf) - : simple_object_fetch_little_32 (strsizebuf)); - strtab = XNEWVEC (char, strsize); - if (!simple_object_internal_read (sobj->descriptor, strtab_offset, - (unsigned char *) strtab, strsize, errmsg, - err)) - { - XDELETEVEC (strtab); - return NULL; - } - *strtab_size = strsize; - return strtab; -} - -/* Find all sections in a COFF file. */ - -static const char * -simple_object_coff_find_sections (simple_object_read *sobj, - int (*pfn) (void *, const char *, - off_t offset, off_t length), - void *data, - int *err) -{ - struct simple_object_coff_read *ocr = - (struct simple_object_coff_read *) sobj->data; - size_t scnhdr_size; - unsigned char *scnbuf; - const char *errmsg; - unsigned int (*fetch_32) (const unsigned char *); - unsigned int nscns; - char *strtab; - size_t strtab_size; - unsigned int i; - - scnhdr_size = sizeof (struct external_scnhdr); - scnbuf = XNEWVEC (unsigned char, scnhdr_size * ocr->nscns); - if (!simple_object_internal_read (sobj->descriptor, - sobj->offset + ocr->scnhdr_offset, - scnbuf, scnhdr_size * ocr->nscns, &errmsg, - err)) - { - XDELETEVEC (scnbuf); - return errmsg; - } - - fetch_32 = (ocr->is_big_endian - ? simple_object_fetch_big_32 - : simple_object_fetch_little_32); - - nscns = ocr->nscns; - strtab = NULL; - strtab_size = 0; - for (i = 0; i < nscns; ++i) - { - unsigned char *scnhdr; - unsigned char *scnname; - char namebuf[SCNNMLEN + 1]; - char *name; - off_t scnptr; - unsigned int size; - - scnhdr = scnbuf + i * scnhdr_size; - scnname = scnhdr + offsetof (struct external_scnhdr, s_name); - memcpy (namebuf, scnname, SCNNMLEN); - namebuf[SCNNMLEN] = '\0'; - name = &namebuf[0]; - if (namebuf[0] == '/') - { - size_t strindex; - char *end; - - strindex = strtol (namebuf + 1, &end, 10); - if (*end == '\0') - { - /* The real section name is found in the string - table. */ - if (strtab == NULL) - { - strtab = simple_object_coff_read_strtab (sobj, - &strtab_size, - &errmsg, err); - if (strtab == NULL) - { - XDELETEVEC (scnbuf); - return errmsg; - } - } - - if (strindex < 4 || strindex >= strtab_size) - { - XDELETEVEC (strtab); - XDELETEVEC (scnbuf); - *err = 0; - return "section string index out of range"; - } - - name = strtab + strindex; - } - } - - scnptr = fetch_32 (scnhdr + offsetof (struct external_scnhdr, s_scnptr)); - size = fetch_32 (scnhdr + offsetof (struct external_scnhdr, s_size)); - - if (!(*pfn) (data, name, scnptr, size)) - break; - } - - if (strtab != NULL) - XDELETEVEC (strtab); - XDELETEVEC (scnbuf); - - return NULL; -} - -/* Fetch the attributes for an simple_object_read. */ - -static void * -simple_object_coff_fetch_attributes (simple_object_read *sobj, - const char **errmsg ATTRIBUTE_UNUSED, - int *err ATTRIBUTE_UNUSED) -{ - struct simple_object_coff_read *ocr = - (struct simple_object_coff_read *) sobj->data; - struct simple_object_coff_attributes *ret; - - ret = XNEW (struct simple_object_coff_attributes); - ret->magic = ocr->magic; - ret->is_big_endian = ocr->is_big_endian; - ret->flags = ocr->flags; - return ret; -} - -/* Release the private data for an simple_object_read. */ - -static void -simple_object_coff_release_read (void *data) -{ - XDELETE (data); -} - -/* Compare two attributes structures. */ - -static const char * -simple_object_coff_attributes_merge (void *todata, void *fromdata, int *err) -{ - struct simple_object_coff_attributes *to = - (struct simple_object_coff_attributes *) todata; - struct simple_object_coff_attributes *from = - (struct simple_object_coff_attributes *) fromdata; - - if (to->magic != from->magic || to->is_big_endian != from->is_big_endian) - { - *err = 0; - return "COFF object format mismatch"; - } - return NULL; -} - -/* Release the private data for an attributes structure. */ - -static void -simple_object_coff_release_attributes (void *data) -{ - XDELETE (data); -} - -/* Prepare to write out a file. */ - -static void * -simple_object_coff_start_write (void *attributes_data, - const char **errmsg ATTRIBUTE_UNUSED, - int *err ATTRIBUTE_UNUSED) -{ - struct simple_object_coff_attributes *attrs = - (struct simple_object_coff_attributes *) attributes_data; - struct simple_object_coff_attributes *ret; - - /* We're just going to record the attributes, but we need to make a - copy because the user may delete them. */ - ret = XNEW (struct simple_object_coff_attributes); - *ret = *attrs; - return ret; -} - -/* Write out a COFF filehdr. */ - -static int -simple_object_coff_write_filehdr (simple_object_write *sobj, int descriptor, - unsigned int nscns, size_t symtab_offset, - unsigned int nsyms, const char **errmsg, - int *err) -{ - struct simple_object_coff_attributes *attrs = - (struct simple_object_coff_attributes *) sobj->data; - unsigned char hdrbuf[sizeof (struct external_filehdr)]; - unsigned char *hdr; - void (*set_16) (unsigned char *, unsigned short); - void (*set_32) (unsigned char *, unsigned int); - - hdr = &hdrbuf[0]; - - set_16 = (attrs->is_big_endian - ? simple_object_set_big_16 - : simple_object_set_little_16); - set_32 = (attrs->is_big_endian - ? simple_object_set_big_32 - : simple_object_set_little_32); - - memset (hdr, 0, sizeof (struct external_filehdr)); - - set_16 (hdr + offsetof (struct external_filehdr, f_magic), attrs->magic); - set_16 (hdr + offsetof (struct external_filehdr, f_nscns), nscns); - /* f_timdat left as zero. */ - set_32 (hdr + offsetof (struct external_filehdr, f_symptr), symtab_offset); - set_32 (hdr + offsetof (struct external_filehdr, f_nsyms), nsyms); - /* f_opthdr left as zero. */ - set_16 (hdr + offsetof (struct external_filehdr, f_flags), attrs->flags); - - return simple_object_internal_write (descriptor, 0, hdrbuf, - sizeof (struct external_filehdr), - errmsg, err); -} - -/* Write out a COFF section header. */ - -static int -simple_object_coff_write_scnhdr (simple_object_write *sobj, int descriptor, - const char *name, size_t *name_offset, - off_t scnhdr_offset, size_t scnsize, - off_t offset, unsigned int align, - const char **errmsg, int *err) -{ - struct simple_object_coff_attributes *attrs = - (struct simple_object_coff_attributes *) sobj->data; - void (*set_32) (unsigned char *, unsigned int); - unsigned char hdrbuf[sizeof (struct external_scnhdr)]; - unsigned char *hdr; - size_t namelen; - unsigned int flags; - - set_32 = (attrs->is_big_endian - ? simple_object_set_big_32 - : simple_object_set_little_32); - - memset (hdrbuf, 0, sizeof hdrbuf); - hdr = &hdrbuf[0]; - - namelen = strlen (name); - if (namelen <= SCNNMLEN) - strncpy ((char *) hdr + offsetof (struct external_scnhdr, s_name), name, - SCNNMLEN); - else - { - snprintf ((char *) hdr + offsetof (struct external_scnhdr, s_name), - SCNNMLEN, "/%lu", (unsigned long) *name_offset); - *name_offset += namelen + 1; - } - - /* s_paddr left as zero. */ - /* s_vaddr left as zero. */ - set_32 (hdr + offsetof (struct external_scnhdr, s_size), scnsize); - set_32 (hdr + offsetof (struct external_scnhdr, s_scnptr), offset); - /* s_relptr left as zero. */ - /* s_lnnoptr left as zero. */ - /* s_nreloc left as zero. */ - /* s_nlnno left as zero. */ - flags = (STYP_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_SHARED - | IMAGE_SCN_MEM_READ); - /* PE can represent alignment up to 13. */ - if (align > 13) - align = 13; - flags |= IMAGE_SCN_ALIGN_POWER_CONST(align); - set_32 (hdr + offsetof (struct external_scnhdr, s_flags), flags); - - return simple_object_internal_write (descriptor, scnhdr_offset, hdrbuf, - sizeof (struct external_scnhdr), - errmsg, err); -} - -/* Write out a complete COFF file. */ - -static const char * -simple_object_coff_write_to_file (simple_object_write *sobj, int descriptor, - int *err) -{ - struct simple_object_coff_attributes *attrs = - (struct simple_object_coff_attributes *) sobj->data; - unsigned int nscns, secnum; - simple_object_write_section *section; - off_t scnhdr_offset; - size_t symtab_offset; - off_t secsym_offset; - unsigned int nsyms; - size_t offset; - size_t name_offset; - const char *errmsg; - unsigned char strsizebuf[4]; - /* The interface doesn't give us access to the name of the input file - yet. We want to use its basename for the FILE symbol. This is - what 'gas' uses when told to assemble from stdin. */ - const char *source_filename = "fake"; - size_t sflen; - union - { - struct external_syment sym; - union external_auxent aux; - } syms[2]; - void (*set_16) (unsigned char *, unsigned short); - void (*set_32) (unsigned char *, unsigned int); - - set_16 = (attrs->is_big_endian - ? simple_object_set_big_16 - : simple_object_set_little_16); - set_32 = (attrs->is_big_endian - ? simple_object_set_big_32 - : simple_object_set_little_32); - - nscns = 0; - for (section = sobj->sections; section != NULL; section = section->next) - ++nscns; - - scnhdr_offset = sizeof (struct external_filehdr); - offset = scnhdr_offset + nscns * sizeof (struct external_scnhdr); - name_offset = 4; - for (section = sobj->sections; section != NULL; section = section->next) - { - size_t mask; - size_t new_offset; - size_t scnsize; - struct simple_object_write_section_buffer *buffer; - - mask = (1U << section->align) - 1; - new_offset = offset & mask; - new_offset &= ~ mask; - while (new_offset > offset) - { - unsigned char zeroes[16]; - size_t write; - - memset (zeroes, 0, sizeof zeroes); - write = new_offset - offset; - if (write > sizeof zeroes) - write = sizeof zeroes; - if (!simple_object_internal_write (descriptor, offset, zeroes, write, - &errmsg, err)) - return errmsg; - } - - scnsize = 0; - for (buffer = section->buffers; buffer != NULL; buffer = buffer->next) - { - if (!simple_object_internal_write (descriptor, offset + scnsize, - ((const unsigned char *) - buffer->buffer), - buffer->size, &errmsg, err)) - return errmsg; - scnsize += buffer->size; - } - - if (!simple_object_coff_write_scnhdr (sobj, descriptor, section->name, - &name_offset, scnhdr_offset, - scnsize, offset, section->align, - &errmsg, err)) - return errmsg; - - scnhdr_offset += sizeof (struct external_scnhdr); - offset += scnsize; - } - - /* Symbol table is always half-word aligned. */ - offset += (offset & 1); - /* There is a file symbol and a section symbol per section, - and each of these has a single auxiliary symbol following. */ - nsyms = 2 * (nscns + 1); - symtab_offset = offset; - /* Advance across space reserved for symbol table to locate - start of string table. */ - offset += nsyms * sizeof (struct external_syment); - - /* Write out file symbol. */ - memset (&syms[0], 0, sizeof (syms)); - strcpy ((char *)&syms[0].sym.e.e_name[0], ".file"); - set_16 (&syms[0].sym.e_scnum[0], IMAGE_SYM_DEBUG); - set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE); - syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_FILE; - syms[0].sym.e_numaux[0] = 1; - /* The name need not be nul-terminated if it fits into the x_fname field - directly, but must be if it has to be placed into the string table. */ - sflen = strlen (source_filename); - if (sflen <= E_FILNMLEN) - memcpy (&syms[1].aux.x_file.x_fname[0], source_filename, sflen); - else - { - set_32 (&syms[1].aux.x_file.x_n.x_offset[0], name_offset); - if (!simple_object_internal_write (descriptor, offset + name_offset, - ((const unsigned char *) - source_filename), - sflen + 1, &errmsg, err)) - return errmsg; - name_offset += strlen (source_filename) + 1; - } - if (!simple_object_internal_write (descriptor, symtab_offset, - (const unsigned char *) &syms[0], - sizeof (syms), &errmsg, err)) - return errmsg; - - /* Write the string table length, followed by the strings and section - symbols in step with each other. */ - set_32 (strsizebuf, name_offset); - if (!simple_object_internal_write (descriptor, offset, strsizebuf, 4, - &errmsg, err)) - return errmsg; - - name_offset = 4; - secsym_offset = symtab_offset + sizeof (syms); - memset (&syms[0], 0, sizeof (syms)); - set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE); - syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_STATIC; - syms[0].sym.e_numaux[0] = 1; - secnum = 1; - - for (section = sobj->sections; section != NULL; section = section->next) - { - size_t namelen; - size_t scnsize; - struct simple_object_write_section_buffer *buffer; - - namelen = strlen (section->name); - set_16 (&syms[0].sym.e_scnum[0], secnum++); - scnsize = 0; - for (buffer = section->buffers; buffer != NULL; buffer = buffer->next) - scnsize += buffer->size; - set_32 (&syms[1].aux.x_scn.x_scnlen[0], scnsize); - if (namelen > SCNNMLEN) - { - set_32 (&syms[0].sym.e.e.e_zeroes[0], 0); - set_32 (&syms[0].sym.e.e.e_offset[0], name_offset); - if (!simple_object_internal_write (descriptor, offset + name_offset, - ((const unsigned char *) - section->name), - namelen + 1, &errmsg, err)) - return errmsg; - name_offset += namelen + 1; - } - else - { - memcpy (&syms[0].sym.e.e_name[0], section->name, - strlen (section->name)); - memset (&syms[0].sym.e.e_name[strlen (section->name)], 0, - E_SYMNMLEN - strlen (section->name)); - } - - if (!simple_object_internal_write (descriptor, secsym_offset, - (const unsigned char *) &syms[0], - sizeof (syms), &errmsg, err)) - return errmsg; - secsym_offset += sizeof (syms); - } - - if (!simple_object_coff_write_filehdr (sobj, descriptor, nscns, - symtab_offset, nsyms, &errmsg, err)) - return errmsg; - - return NULL; -} - -/* Release the private data for an simple_object_write structure. */ - -static void -simple_object_coff_release_write (void *data) -{ - XDELETE (data); -} - -/* The COFF functions. */ - -const struct simple_object_functions simple_object_coff_functions = -{ - simple_object_coff_match, - simple_object_coff_find_sections, - simple_object_coff_fetch_attributes, - simple_object_coff_release_read, - simple_object_coff_attributes_merge, - simple_object_coff_release_attributes, - simple_object_coff_start_write, - simple_object_coff_write_to_file, - simple_object_coff_release_write -}; |