Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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,
  54.   &simple_object_coff_functions,
  55.   &simple_object_xcoff_functions
  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.   ssize_t got;
  67.  
  68.   if (lseek (descriptor, offset, SEEK_SET) < 0)
  69.     {
  70.       *errmsg = "lseek";
  71.       *err = errno;
  72.       return 0;
  73.     }
  74.  
  75.   got = read (descriptor, buffer, size);
  76.   if (got < 0)
  77.     {
  78.       *errmsg = "read";
  79.       *err = errno;
  80.       return 0;
  81.     }
  82.  
  83.   if ((size_t) got < size)
  84.     {
  85.       *errmsg = "file too short";
  86.       *err = 0;
  87.       return 0;
  88.     }
  89.  
  90.   return 1;
  91. }
  92.  
  93. /* Write data to a file using the simple_object error reporting
  94.    conventions.  */
  95.  
  96. int
  97. simple_object_internal_write (int descriptor, off_t offset,
  98.                               const unsigned char *buffer, size_t size,
  99.                               const char **errmsg, int *err)
  100. {
  101.   ssize_t wrote;
  102.  
  103.   if (lseek (descriptor, offset, SEEK_SET) < 0)
  104.     {
  105.       *errmsg = "lseek";
  106.       *err = errno;
  107.       return 0;
  108.     }
  109.  
  110.   wrote = write (descriptor, buffer, size);
  111.   if (wrote < 0)
  112.     {
  113.       *errmsg = "write";
  114.       *err = errno;
  115.       return 0;
  116.     }
  117.  
  118.   if ((size_t) wrote < size)
  119.     {
  120.       *errmsg = "short write";
  121.       *err = 0;
  122.       return 0;
  123.     }
  124.  
  125.   return 1;
  126. }
  127.  
  128. /* Open for read.  */
  129.  
  130. simple_object_read *
  131. simple_object_start_read (int descriptor, off_t offset,
  132.                           const char *segment_name, const char **errmsg,
  133.                           int *err)
  134. {
  135.   unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN];
  136.   size_t len, i;
  137.  
  138.   if (!simple_object_internal_read (descriptor, offset, header,
  139.                                     SIMPLE_OBJECT_MATCH_HEADER_LEN,
  140.                                     errmsg, err))
  141.     return NULL;
  142.  
  143.   len = sizeof (format_functions) / sizeof (format_functions[0]);
  144.   for (i = 0; i < len; ++i)
  145.     {
  146.       void *data;
  147.  
  148.       data = format_functions[i]->match (header, descriptor, offset,
  149.                                          segment_name, errmsg, err);
  150.       if (data != NULL)
  151.         {
  152.           simple_object_read *ret;
  153.  
  154.           ret = XNEW (simple_object_read);
  155.           ret->descriptor = descriptor;
  156.           ret->offset = offset;
  157.           ret->functions = format_functions[i];
  158.           ret->data = data;
  159.           return ret;
  160.         }
  161.     }
  162.  
  163.   *errmsg = "file not recognized";
  164.   *err = 0;
  165.   return NULL;
  166. }
  167.  
  168. /* Find all sections.  */
  169.  
  170. const char *
  171. simple_object_find_sections (simple_object_read *sobj,
  172.                              int (*pfn) (void *, const char *, off_t, off_t),
  173.                              void *data,
  174.                              int *err)
  175. {
  176.   return sobj->functions->find_sections (sobj, pfn, data, err);
  177. }
  178.  
  179. /* Internal data passed to find_one_section.  */
  180.  
  181. struct find_one_section_data
  182. {
  183.   /* The section we are looking for.  */
  184.   const char *name;
  185.   /* Where to store the section offset.  */
  186.   off_t *offset;
  187.   /* Where to store the section length.  */
  188.   off_t *length;
  189.   /* Set if the name is found.  */
  190.   int found;
  191. };
  192.  
  193. /* Internal function passed to find_sections.  */
  194.  
  195. static int
  196. find_one_section (void *data, const char *name, off_t offset, off_t length)
  197. {
  198.   struct find_one_section_data *fosd = (struct find_one_section_data *) data;
  199.  
  200.   if (strcmp (name, fosd->name) != 0)
  201.     return 1;
  202.  
  203.   *fosd->offset = offset;
  204.   *fosd->length = length;
  205.   fosd->found = 1;
  206.  
  207.   /* Stop iteration.  */
  208.   return 0;
  209. }
  210.  
  211. /* Find a section.  */
  212.  
  213. int
  214. simple_object_find_section (simple_object_read *sobj, const char *name,
  215.                             off_t *offset, off_t *length,
  216.                             const char **errmsg, int *err)
  217. {
  218.   struct find_one_section_data fosd;
  219.  
  220.   fosd.name = name;
  221.   fosd.offset = offset;
  222.   fosd.length = length;
  223.   fosd.found = 0;
  224.  
  225.   *errmsg = simple_object_find_sections (sobj, find_one_section,
  226.                                          (void *) &fosd, err);
  227.   if (*errmsg != NULL)
  228.     return 0;
  229.   if (!fosd.found)
  230.     return 0;
  231.   return 1;
  232. }
  233.  
  234. /* Fetch attributes.  */
  235.  
  236. simple_object_attributes *
  237. simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
  238.                                 int *err)
  239. {
  240.   void *data;
  241.   simple_object_attributes *ret;
  242.  
  243.   data = sobj->functions->fetch_attributes (sobj, errmsg, err);
  244.   if (data == NULL)
  245.     return NULL;
  246.   ret = XNEW (simple_object_attributes);
  247.   ret->functions = sobj->functions;
  248.   ret->data = data;
  249.   return ret;
  250. }
  251.  
  252. /* Release an simple_object_read.  */
  253.  
  254. void
  255. simple_object_release_read (simple_object_read *sobj)
  256. {
  257.   sobj->functions->release_read (sobj->data);
  258.   XDELETE (sobj);
  259. }
  260.  
  261. /* Merge attributes.  */
  262.  
  263. const char *
  264. simple_object_attributes_merge (simple_object_attributes *to,
  265.                                 simple_object_attributes *from,
  266.                                 int *err)
  267. {
  268.   if (to->functions != from->functions)
  269.     {
  270.       *err = 0;
  271.       return "different object file format";
  272.     }
  273.   return to->functions->attributes_merge (to->data, from->data, err);
  274. }
  275.  
  276. /* Release an attributes structure.  */
  277.  
  278. void
  279. simple_object_release_attributes (simple_object_attributes *attrs)
  280. {
  281.   attrs->functions->release_attributes (attrs->data);
  282.   XDELETE (attrs);
  283. }
  284.  
  285. /* Start creating an object file.  */
  286.  
  287. simple_object_write *
  288. simple_object_start_write (simple_object_attributes *attrs,
  289.                            const char *segment_name, const char **errmsg,
  290.                            int *err)
  291. {
  292.   void *data;
  293.   simple_object_write *ret;
  294.  
  295.   data = attrs->functions->start_write (attrs->data, errmsg, err);
  296.   if (data == NULL)
  297.     return NULL;
  298.   ret = XNEW (simple_object_write);
  299.   ret->functions = attrs->functions;
  300.   ret->segment_name = xstrdup (segment_name);
  301.   ret->sections = NULL;
  302.   ret->last_section = NULL;
  303.   ret->data = data;
  304.   return ret;
  305. }
  306.  
  307. /* Start creating a section.  */
  308.  
  309. simple_object_write_section *
  310. simple_object_write_create_section (simple_object_write *sobj, const char *name,
  311.                                     unsigned int align,
  312.                                     const char **errmsg ATTRIBUTE_UNUSED,
  313.                                     int *err ATTRIBUTE_UNUSED)
  314. {
  315.   simple_object_write_section *ret;
  316.  
  317.   ret = XNEW (simple_object_write_section);
  318.   ret->next = NULL;
  319.   ret->name = xstrdup (name);
  320.   ret->align = align;
  321.   ret->buffers = NULL;
  322.   ret->last_buffer = NULL;
  323.  
  324.   if (sobj->last_section == NULL)
  325.     {
  326.       sobj->sections = ret;
  327.       sobj->last_section = ret;
  328.     }
  329.   else
  330.     {
  331.       sobj->last_section->next = ret;
  332.       sobj->last_section = ret;
  333.     }
  334.  
  335.   return ret;
  336. }
  337.  
  338. /* Add data to a section.  */
  339.  
  340. const char *
  341. simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
  342.                               simple_object_write_section *section,
  343.                               const void *buffer,
  344.                               size_t size, int copy,
  345.                               int *err ATTRIBUTE_UNUSED)
  346. {
  347.   struct simple_object_write_section_buffer *wsb;
  348.  
  349.   wsb = XNEW (struct simple_object_write_section_buffer);
  350.   wsb->next = NULL;
  351.   wsb->size = size;
  352.  
  353.   if (!copy)
  354.     {
  355.       wsb->buffer = buffer;
  356.       wsb->free_buffer = NULL;
  357.     }
  358.   else
  359.     {
  360.       wsb->free_buffer = (void *) XNEWVEC (char, size);
  361.       memcpy (wsb->free_buffer, buffer, size);
  362.       wsb->buffer = wsb->free_buffer;
  363.     }
  364.  
  365.   if (section->last_buffer == NULL)
  366.     {
  367.       section->buffers = wsb;
  368.       section->last_buffer = wsb;
  369.     }
  370.   else
  371.     {
  372.       section->last_buffer->next = wsb;
  373.       section->last_buffer = wsb;
  374.     }
  375.  
  376.   return NULL;
  377. }
  378.  
  379. /* Write the complete object file.  */
  380.  
  381. const char *
  382. simple_object_write_to_file (simple_object_write *sobj, int descriptor,
  383.                              int *err)
  384. {
  385.   return sobj->functions->write_to_file (sobj, descriptor, err);
  386. }
  387.  
  388. /* Release an simple_object_write.  */
  389.  
  390. void
  391. simple_object_release_write (simple_object_write *sobj)
  392. {
  393.   simple_object_write_section *section;
  394.  
  395.   free (sobj->segment_name);
  396.  
  397.   section = sobj->sections;
  398.   while (section != NULL)
  399.     {
  400.       struct simple_object_write_section_buffer *buffer;
  401.       simple_object_write_section *next_section;
  402.  
  403.       buffer = section->buffers;
  404.       while (buffer != NULL)
  405.         {
  406.           struct simple_object_write_section_buffer *next_buffer;
  407.  
  408.           if (buffer->free_buffer != NULL)
  409.             XDELETEVEC (buffer->free_buffer);
  410.           next_buffer = buffer->next;
  411.           XDELETE (buffer);
  412.           buffer = next_buffer;
  413.         }
  414.  
  415.       next_section = section->next;
  416.       free (section->name);
  417.       XDELETE (section);
  418.       section = next_section;
  419.     }
  420.  
  421.   sobj->functions->release_write (sobj->data);
  422.   XDELETE (sobj);
  423. }
  424.