Home | History | Annotate | Line # | Download | only in libiberty
simple-object.c revision 1.1.1.1.8.1
      1          1.1  christos /* simple-object.c -- simple routines to read and write object files.
      2          1.1  christos    Copyright 2010 Free Software Foundation, Inc.
      3          1.1  christos    Written by Ian Lance Taylor, Google.
      4          1.1  christos 
      5          1.1  christos This program is free software; you can redistribute it and/or modify it
      6          1.1  christos under the terms of the GNU General Public License as published by the
      7          1.1  christos Free Software Foundation; either version 2, or (at your option) any
      8          1.1  christos later version.
      9          1.1  christos 
     10          1.1  christos This program is distributed in the hope that it will be useful,
     11          1.1  christos but WITHOUT ANY WARRANTY; without even the implied warranty of
     12          1.1  christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13          1.1  christos GNU General Public License for more details.
     14          1.1  christos 
     15          1.1  christos You should have received a copy of the GNU General Public License
     16          1.1  christos along with this program; if not, write to the Free Software
     17          1.1  christos Foundation, 51 Franklin Street - Fifth Floor,
     18          1.1  christos Boston, MA 02110-1301, USA.  */
     19          1.1  christos 
     20          1.1  christos #include "config.h"
     21          1.1  christos #include "libiberty.h"
     22          1.1  christos #include "simple-object.h"
     23          1.1  christos 
     24          1.1  christos #include <errno.h>
     25          1.1  christos 
     26          1.1  christos #ifdef HAVE_STDLIB_H
     27          1.1  christos #include <stdlib.h>
     28          1.1  christos #endif
     29          1.1  christos 
     30          1.1  christos #ifdef HAVE_STDINT_H
     31          1.1  christos #include <stdint.h>
     32          1.1  christos #endif
     33          1.1  christos 
     34          1.1  christos #ifdef HAVE_STRING_H
     35          1.1  christos #include <string.h>
     36          1.1  christos #endif
     37          1.1  christos 
     38          1.1  christos #ifdef HAVE_INTTYPES_H
     39          1.1  christos #include <inttypes.h>
     40          1.1  christos #endif
     41          1.1  christos 
     42          1.1  christos #ifndef SEEK_SET
     43          1.1  christos #define SEEK_SET 0
     44          1.1  christos #endif
     45          1.1  christos 
     46          1.1  christos #include "simple-object-common.h"
     47          1.1  christos 
     48          1.1  christos /* The known object file formats.  */
     49          1.1  christos 
     50          1.1  christos static const struct simple_object_functions * const format_functions[] =
     51          1.1  christos {
     52          1.1  christos   &simple_object_elf_functions,
     53          1.1  christos   &simple_object_mach_o_functions,
     54          1.1  christos   &simple_object_coff_functions
     55          1.1  christos };
     56          1.1  christos 
     57          1.1  christos /* Read data from a file using the simple_object error reporting
     58          1.1  christos    conventions.  */
     59          1.1  christos 
     60          1.1  christos int
     61          1.1  christos simple_object_internal_read (int descriptor, off_t offset,
     62          1.1  christos 			     unsigned char *buffer, size_t size,
     63          1.1  christos 			     const char **errmsg, int *err)
     64          1.1  christos {
     65          1.1  christos   ssize_t got;
     66          1.1  christos 
     67          1.1  christos   if (lseek (descriptor, offset, SEEK_SET) < 0)
     68          1.1  christos     {
     69          1.1  christos       *errmsg = "lseek";
     70          1.1  christos       *err = errno;
     71          1.1  christos       return 0;
     72          1.1  christos     }
     73          1.1  christos 
     74          1.1  christos   got = read (descriptor, buffer, size);
     75          1.1  christos   if (got < 0)
     76          1.1  christos     {
     77          1.1  christos       *errmsg = "read";
     78          1.1  christos       *err = errno;
     79          1.1  christos       return 0;
     80          1.1  christos     }
     81          1.1  christos 
     82          1.1  christos   if ((size_t) got < size)
     83          1.1  christos     {
     84          1.1  christos       *errmsg = "file too short";
     85          1.1  christos       *err = 0;
     86          1.1  christos       return 0;
     87          1.1  christos     }
     88          1.1  christos 
     89          1.1  christos   return 1;
     90          1.1  christos }
     91          1.1  christos 
     92          1.1  christos /* Write data to a file using the simple_object error reporting
     93          1.1  christos    conventions.  */
     94          1.1  christos 
     95          1.1  christos int
     96          1.1  christos simple_object_internal_write (int descriptor, off_t offset,
     97          1.1  christos 			      const unsigned char *buffer, size_t size,
     98          1.1  christos 			      const char **errmsg, int *err)
     99          1.1  christos {
    100          1.1  christos   ssize_t wrote;
    101          1.1  christos 
    102          1.1  christos   if (lseek (descriptor, offset, SEEK_SET) < 0)
    103          1.1  christos     {
    104          1.1  christos       *errmsg = "lseek";
    105          1.1  christos       *err = errno;
    106          1.1  christos       return 0;
    107          1.1  christos     }
    108          1.1  christos 
    109          1.1  christos   wrote = write (descriptor, buffer, size);
    110          1.1  christos   if (wrote < 0)
    111          1.1  christos     {
    112          1.1  christos       *errmsg = "write";
    113          1.1  christos       *err = errno;
    114          1.1  christos       return 0;
    115          1.1  christos     }
    116          1.1  christos 
    117          1.1  christos   if ((size_t) wrote < size)
    118          1.1  christos     {
    119          1.1  christos       *errmsg = "short write";
    120          1.1  christos       *err = 0;
    121          1.1  christos       return 0;
    122          1.1  christos     }
    123          1.1  christos 
    124          1.1  christos   return 1;
    125          1.1  christos }
    126          1.1  christos 
    127          1.1  christos /* Open for read.  */
    128          1.1  christos 
    129          1.1  christos simple_object_read *
    130          1.1  christos simple_object_start_read (int descriptor, off_t offset,
    131          1.1  christos 			  const char *segment_name, const char **errmsg,
    132          1.1  christos 			  int *err)
    133          1.1  christos {
    134          1.1  christos   unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN];
    135          1.1  christos   size_t len, i;
    136          1.1  christos 
    137          1.1  christos   if (!simple_object_internal_read (descriptor, offset, header,
    138          1.1  christos 				    SIMPLE_OBJECT_MATCH_HEADER_LEN,
    139          1.1  christos 				    errmsg, err))
    140          1.1  christos     return NULL;
    141          1.1  christos 
    142          1.1  christos   len = sizeof (format_functions) / sizeof (format_functions[0]);
    143          1.1  christos   for (i = 0; i < len; ++i)
    144          1.1  christos     {
    145          1.1  christos       void *data;
    146          1.1  christos 
    147          1.1  christos       data = format_functions[i]->match (header, descriptor, offset,
    148          1.1  christos 					 segment_name, errmsg, err);
    149          1.1  christos       if (data != NULL)
    150          1.1  christos 	{
    151          1.1  christos 	  simple_object_read *ret;
    152          1.1  christos 
    153          1.1  christos 	  ret = XNEW (simple_object_read);
    154          1.1  christos 	  ret->descriptor = descriptor;
    155          1.1  christos 	  ret->offset = offset;
    156          1.1  christos 	  ret->functions = format_functions[i];
    157          1.1  christos 	  ret->data = data;
    158          1.1  christos 	  return ret;
    159          1.1  christos 	}
    160          1.1  christos     }
    161          1.1  christos 
    162          1.1  christos   *errmsg = "file not recognized";
    163          1.1  christos   *err = 0;
    164          1.1  christos   return NULL;
    165          1.1  christos }
    166          1.1  christos 
    167          1.1  christos /* Find all sections.  */
    168          1.1  christos 
    169          1.1  christos const char *
    170          1.1  christos simple_object_find_sections (simple_object_read *sobj,
    171          1.1  christos 			     int (*pfn) (void *, const char *, off_t, off_t),
    172          1.1  christos 			     void *data,
    173          1.1  christos 			     int *err)
    174          1.1  christos {
    175          1.1  christos   return sobj->functions->find_sections (sobj, pfn, data, err);
    176          1.1  christos }
    177          1.1  christos 
    178          1.1  christos /* Internal data passed to find_one_section.  */
    179          1.1  christos 
    180          1.1  christos struct find_one_section_data
    181          1.1  christos {
    182          1.1  christos   /* The section we are looking for.  */
    183          1.1  christos   const char *name;
    184          1.1  christos   /* Where to store the section offset.  */
    185          1.1  christos   off_t *offset;
    186          1.1  christos   /* Where to store the section length.  */
    187          1.1  christos   off_t *length;
    188          1.1  christos   /* Set if the name is found.  */
    189          1.1  christos   int found;
    190          1.1  christos };
    191          1.1  christos 
    192          1.1  christos /* Internal function passed to find_sections.  */
    193          1.1  christos 
    194          1.1  christos static int
    195          1.1  christos find_one_section (void *data, const char *name, off_t offset, off_t length)
    196          1.1  christos {
    197          1.1  christos   struct find_one_section_data *fosd = (struct find_one_section_data *) data;
    198          1.1  christos 
    199          1.1  christos   if (strcmp (name, fosd->name) != 0)
    200          1.1  christos     return 1;
    201          1.1  christos 
    202          1.1  christos   *fosd->offset = offset;
    203          1.1  christos   *fosd->length = length;
    204          1.1  christos   fosd->found = 1;
    205          1.1  christos 
    206          1.1  christos   /* Stop iteration.  */
    207          1.1  christos   return 0;
    208          1.1  christos }
    209          1.1  christos 
    210          1.1  christos /* Find a section.  */
    211          1.1  christos 
    212          1.1  christos int
    213          1.1  christos simple_object_find_section (simple_object_read *sobj, const char *name,
    214          1.1  christos 			    off_t *offset, off_t *length,
    215          1.1  christos 			    const char **errmsg, int *err)
    216          1.1  christos {
    217          1.1  christos   struct find_one_section_data fosd;
    218          1.1  christos 
    219          1.1  christos   fosd.name = name;
    220          1.1  christos   fosd.offset = offset;
    221          1.1  christos   fosd.length = length;
    222          1.1  christos   fosd.found = 0;
    223          1.1  christos 
    224          1.1  christos   *errmsg = simple_object_find_sections (sobj, find_one_section,
    225          1.1  christos 					 (void *) &fosd, err);
    226          1.1  christos   if (*errmsg != NULL)
    227          1.1  christos     return 0;
    228          1.1  christos   if (!fosd.found)
    229          1.1  christos     return 0;
    230          1.1  christos   return 1;
    231          1.1  christos }
    232          1.1  christos 
    233          1.1  christos /* Fetch attributes.  */
    234          1.1  christos 
    235          1.1  christos simple_object_attributes *
    236          1.1  christos simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
    237          1.1  christos 				int *err)
    238          1.1  christos {
    239          1.1  christos   void *data;
    240          1.1  christos   simple_object_attributes *ret;
    241          1.1  christos 
    242          1.1  christos   data = sobj->functions->fetch_attributes (sobj, errmsg, err);
    243          1.1  christos   if (data == NULL)
    244          1.1  christos     return NULL;
    245          1.1  christos   ret = XNEW (simple_object_attributes);
    246          1.1  christos   ret->functions = sobj->functions;
    247          1.1  christos   ret->data = data;
    248          1.1  christos   return ret;
    249          1.1  christos }
    250          1.1  christos 
    251          1.1  christos /* Release an simple_object_read.  */
    252          1.1  christos 
    253          1.1  christos void
    254          1.1  christos simple_object_release_read (simple_object_read *sobj)
    255          1.1  christos {
    256          1.1  christos   sobj->functions->release_read (sobj->data);
    257          1.1  christos   XDELETE (sobj);
    258          1.1  christos }
    259          1.1  christos 
    260  1.1.1.1.8.1       tls /* Merge attributes.  */
    261          1.1  christos 
    262          1.1  christos const char *
    263  1.1.1.1.8.1       tls simple_object_attributes_merge (simple_object_attributes *to,
    264  1.1.1.1.8.1       tls 				simple_object_attributes *from,
    265  1.1.1.1.8.1       tls 				int *err)
    266          1.1  christos {
    267  1.1.1.1.8.1       tls   if (to->functions != from->functions)
    268          1.1  christos     {
    269          1.1  christos       *err = 0;
    270          1.1  christos       return "different object file format";
    271          1.1  christos     }
    272  1.1.1.1.8.1       tls   return to->functions->attributes_merge (to->data, from->data, err);
    273          1.1  christos }
    274          1.1  christos 
    275          1.1  christos /* Release an attributes structure.  */
    276          1.1  christos 
    277          1.1  christos void
    278          1.1  christos simple_object_release_attributes (simple_object_attributes *attrs)
    279          1.1  christos {
    280          1.1  christos   attrs->functions->release_attributes (attrs->data);
    281          1.1  christos   XDELETE (attrs);
    282          1.1  christos }
    283          1.1  christos 
    284          1.1  christos /* Start creating an object file.  */
    285          1.1  christos 
    286          1.1  christos simple_object_write *
    287          1.1  christos simple_object_start_write (simple_object_attributes *attrs,
    288          1.1  christos 			   const char *segment_name, const char **errmsg,
    289          1.1  christos 			   int *err)
    290          1.1  christos {
    291          1.1  christos   void *data;
    292          1.1  christos   simple_object_write *ret;
    293          1.1  christos 
    294          1.1  christos   data = attrs->functions->start_write (attrs->data, errmsg, err);
    295          1.1  christos   if (data == NULL)
    296          1.1  christos     return NULL;
    297          1.1  christos   ret = XNEW (simple_object_write);
    298          1.1  christos   ret->functions = attrs->functions;
    299          1.1  christos   ret->segment_name = xstrdup (segment_name);
    300          1.1  christos   ret->sections = NULL;
    301          1.1  christos   ret->last_section = NULL;
    302          1.1  christos   ret->data = data;
    303          1.1  christos   return ret;
    304          1.1  christos }
    305          1.1  christos 
    306          1.1  christos /* Start creating a section.  */
    307          1.1  christos 
    308          1.1  christos simple_object_write_section *
    309          1.1  christos simple_object_write_create_section (simple_object_write *sobj, const char *name,
    310          1.1  christos 				    unsigned int align,
    311          1.1  christos 				    const char **errmsg ATTRIBUTE_UNUSED,
    312          1.1  christos 				    int *err ATTRIBUTE_UNUSED)
    313          1.1  christos {
    314          1.1  christos   simple_object_write_section *ret;
    315          1.1  christos 
    316          1.1  christos   ret = XNEW (simple_object_write_section);
    317          1.1  christos   ret->next = NULL;
    318          1.1  christos   ret->name = xstrdup (name);
    319          1.1  christos   ret->align = align;
    320          1.1  christos   ret->buffers = NULL;
    321          1.1  christos   ret->last_buffer = NULL;
    322          1.1  christos 
    323          1.1  christos   if (sobj->last_section == NULL)
    324          1.1  christos     {
    325          1.1  christos       sobj->sections = ret;
    326          1.1  christos       sobj->last_section = ret;
    327          1.1  christos     }
    328          1.1  christos   else
    329          1.1  christos     {
    330          1.1  christos       sobj->last_section->next = ret;
    331          1.1  christos       sobj->last_section = ret;
    332          1.1  christos     }
    333          1.1  christos 
    334          1.1  christos   return ret;
    335          1.1  christos }
    336          1.1  christos 
    337          1.1  christos /* Add data to a section.  */
    338          1.1  christos 
    339          1.1  christos const char *
    340          1.1  christos simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
    341          1.1  christos 			      simple_object_write_section *section,
    342          1.1  christos 			      const void *buffer,
    343          1.1  christos 			      size_t size, int copy,
    344          1.1  christos 			      int *err ATTRIBUTE_UNUSED)
    345          1.1  christos {
    346          1.1  christos   struct simple_object_write_section_buffer *wsb;
    347          1.1  christos 
    348          1.1  christos   wsb = XNEW (struct simple_object_write_section_buffer);
    349          1.1  christos   wsb->next = NULL;
    350          1.1  christos   wsb->size = size;
    351          1.1  christos 
    352          1.1  christos   if (!copy)
    353          1.1  christos     {
    354          1.1  christos       wsb->buffer = buffer;
    355          1.1  christos       wsb->free_buffer = NULL;
    356          1.1  christos     }
    357          1.1  christos   else
    358          1.1  christos     {
    359          1.1  christos       wsb->free_buffer = (void *) XNEWVEC (char, size);
    360          1.1  christos       memcpy (wsb->free_buffer, buffer, size);
    361          1.1  christos       wsb->buffer = wsb->free_buffer;
    362          1.1  christos     }
    363          1.1  christos 
    364          1.1  christos   if (section->last_buffer == NULL)
    365          1.1  christos     {
    366          1.1  christos       section->buffers = wsb;
    367          1.1  christos       section->last_buffer = wsb;
    368          1.1  christos     }
    369          1.1  christos   else
    370          1.1  christos     {
    371          1.1  christos       section->last_buffer->next = wsb;
    372          1.1  christos       section->last_buffer = wsb;
    373          1.1  christos     }
    374          1.1  christos 
    375          1.1  christos   return NULL;
    376          1.1  christos }
    377          1.1  christos 
    378          1.1  christos /* Write the complete object file.  */
    379          1.1  christos 
    380          1.1  christos const char *
    381          1.1  christos simple_object_write_to_file (simple_object_write *sobj, int descriptor,
    382          1.1  christos 			     int *err)
    383          1.1  christos {
    384          1.1  christos   return sobj->functions->write_to_file (sobj, descriptor, err);
    385          1.1  christos }
    386          1.1  christos 
    387          1.1  christos /* Release an simple_object_write.  */
    388          1.1  christos 
    389          1.1  christos void
    390          1.1  christos simple_object_release_write (simple_object_write *sobj)
    391          1.1  christos {
    392          1.1  christos   simple_object_write_section *section;
    393          1.1  christos 
    394          1.1  christos   free (sobj->segment_name);
    395          1.1  christos 
    396          1.1  christos   section = sobj->sections;
    397          1.1  christos   while (section != NULL)
    398          1.1  christos     {
    399          1.1  christos       struct simple_object_write_section_buffer *buffer;
    400          1.1  christos       simple_object_write_section *next_section;
    401          1.1  christos 
    402          1.1  christos       buffer = section->buffers;
    403          1.1  christos       while (buffer != NULL)
    404          1.1  christos 	{
    405          1.1  christos 	  struct simple_object_write_section_buffer *next_buffer;
    406          1.1  christos 
    407          1.1  christos 	  if (buffer->free_buffer != NULL)
    408          1.1  christos 	    XDELETEVEC (buffer->free_buffer);
    409          1.1  christos 	  next_buffer = buffer->next;
    410          1.1  christos 	  XDELETE (buffer);
    411          1.1  christos 	  buffer = next_buffer;
    412          1.1  christos 	}
    413          1.1  christos 
    414          1.1  christos       next_section = section->next;
    415          1.1  christos       free (section->name);
    416          1.1  christos       XDELETE (section);
    417          1.1  christos       section = next_section;
    418          1.1  christos     }
    419          1.1  christos 
    420          1.1  christos   sobj->functions->release_write (sobj->data);
    421          1.1  christos   XDELETE (sobj);
    422          1.1  christos }
    423