[BACK]Return to simple-object.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils / dist / libiberty

Annotation of src/external/gpl3/binutils/dist/libiberty/simple-object.c, Revision 1.1.1.3

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

CVSweb <webmaster@jp.NetBSD.org>