Home | History | Annotate | Line # | Download | only in libiberty
simple-object.c revision 1.1.1.3.14.2
      1 /* simple-object.c -- simple routines to read and write object files.
      2    Copyright (C) 2010-2018 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 #include <fcntl.h>
     26 
     27 #ifdef HAVE_STDLIB_H
     28 #include <stdlib.h>
     29 #endif
     30 
     31 #ifdef HAVE_STDINT_H
     32 #include <stdint.h>
     33 #endif
     34 
     35 #ifdef HAVE_STRING_H
     36 #include <string.h>
     37 #endif
     38 
     39 #ifdef HAVE_INTTYPES_H
     40 #include <inttypes.h>
     41 #endif
     42 
     43 #ifndef SEEK_SET
     44 #define SEEK_SET 0
     45 #endif
     46 
     47 #include "simple-object-common.h"
     48 
     49 /* The known object file formats.  */
     50 
     51 static const struct simple_object_functions * const format_functions[] =
     52 {
     53   &simple_object_elf_functions,
     54   &simple_object_mach_o_functions,
     55   &simple_object_coff_functions,
     56   &simple_object_xcoff_functions
     57 };
     58 
     59 /* Read data from a file using the simple_object error reporting
     60    conventions.  */
     61 
     62 int
     63 simple_object_internal_read (int descriptor, off_t offset,
     64 			     unsigned char *buffer, size_t size,
     65 			     const char **errmsg, int *err)
     66 {
     67   if (lseek (descriptor, offset, SEEK_SET) < 0)
     68     {
     69       *errmsg = "lseek";
     70       *err = errno;
     71       return 0;
     72     }
     73 
     74   do
     75     {
     76       ssize_t got = read (descriptor, buffer, size);
     77       if (got == 0)
     78 	break;
     79       else if (got > 0)
     80 	{
     81 	  buffer += got;
     82 	  size -= got;
     83 	}
     84       else if (errno != EINTR)
     85 	{
     86 	  *errmsg = "read";
     87 	  *err = errno;
     88 	  return 0;
     89 	}
     90     }
     91   while (size > 0);
     92 
     93   if (size > 0)
     94     {
     95       *errmsg = "file too short";
     96       *err = 0;
     97       return 0;
     98     }
     99 
    100   return 1;
    101 }
    102 
    103 /* Write data to a file using the simple_object error reporting
    104    conventions.  */
    105 
    106 int
    107 simple_object_internal_write (int descriptor, off_t offset,
    108 			      const unsigned char *buffer, size_t size,
    109 			      const char **errmsg, int *err)
    110 {
    111   if (lseek (descriptor, offset, SEEK_SET) < 0)
    112     {
    113       *errmsg = "lseek";
    114       *err = errno;
    115       return 0;
    116     }
    117 
    118   do
    119     {
    120       ssize_t wrote = write (descriptor, buffer, size);
    121       if (wrote == 0)
    122 	break;
    123       else if (wrote > 0)
    124 	{
    125 	  buffer += wrote;
    126 	  size -= wrote;
    127 	}
    128       else if (errno != EINTR)
    129 	{
    130 	  *errmsg = "write";
    131 	  *err = errno;
    132 	  return 0;
    133 	}
    134     }
    135   while (size > 0);
    136 
    137   if (size > 0)
    138     {
    139       *errmsg = "short write";
    140       *err = 0;
    141       return 0;
    142     }
    143 
    144   return 1;
    145 }
    146 
    147 /* Open for read.  */
    148 
    149 simple_object_read *
    150 simple_object_start_read (int descriptor, off_t offset,
    151 			  const char *segment_name, const char **errmsg,
    152 			  int *err)
    153 {
    154   unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN];
    155   size_t len, i;
    156 
    157   if (!simple_object_internal_read (descriptor, offset, header,
    158 				    SIMPLE_OBJECT_MATCH_HEADER_LEN,
    159 				    errmsg, err))
    160     return NULL;
    161 
    162   len = sizeof (format_functions) / sizeof (format_functions[0]);
    163   for (i = 0; i < len; ++i)
    164     {
    165       void *data;
    166 
    167       data = format_functions[i]->match (header, descriptor, offset,
    168 					 segment_name, errmsg, err);
    169       if (data != NULL)
    170 	{
    171 	  simple_object_read *ret;
    172 
    173 	  ret = XNEW (simple_object_read);
    174 	  ret->descriptor = descriptor;
    175 	  ret->offset = offset;
    176 	  ret->functions = format_functions[i];
    177 	  ret->data = data;
    178 	  return ret;
    179 	}
    180     }
    181 
    182   *errmsg = "file not recognized";
    183   *err = 0;
    184   return NULL;
    185 }
    186 
    187 /* Find all sections.  */
    188 
    189 const char *
    190 simple_object_find_sections (simple_object_read *sobj,
    191 			     int (*pfn) (void *, const char *, off_t, off_t),
    192 			     void *data,
    193 			     int *err)
    194 {
    195   return sobj->functions->find_sections (sobj, pfn, data, err);
    196 }
    197 
    198 /* Internal data passed to find_one_section.  */
    199 
    200 struct find_one_section_data
    201 {
    202   /* The section we are looking for.  */
    203   const char *name;
    204   /* Where to store the section offset.  */
    205   off_t *offset;
    206   /* Where to store the section length.  */
    207   off_t *length;
    208   /* Set if the name is found.  */
    209   int found;
    210 };
    211 
    212 /* Internal function passed to find_sections.  */
    213 
    214 static int
    215 find_one_section (void *data, const char *name, off_t offset, off_t length)
    216 {
    217   struct find_one_section_data *fosd = (struct find_one_section_data *) data;
    218 
    219   if (strcmp (name, fosd->name) != 0)
    220     return 1;
    221 
    222   *fosd->offset = offset;
    223   *fosd->length = length;
    224   fosd->found = 1;
    225 
    226   /* Stop iteration.  */
    227   return 0;
    228 }
    229 
    230 /* Find a section.  */
    231 
    232 int
    233 simple_object_find_section (simple_object_read *sobj, const char *name,
    234 			    off_t *offset, off_t *length,
    235 			    const char **errmsg, int *err)
    236 {
    237   struct find_one_section_data fosd;
    238 
    239   fosd.name = name;
    240   fosd.offset = offset;
    241   fosd.length = length;
    242   fosd.found = 0;
    243 
    244   *errmsg = simple_object_find_sections (sobj, find_one_section,
    245 					 (void *) &fosd, err);
    246   if (*errmsg != NULL)
    247     return 0;
    248   if (!fosd.found)
    249     return 0;
    250   return 1;
    251 }
    252 
    253 /* Callback to identify and rename LTO debug sections by name.
    254    Returns non-NULL if NAME is a LTO debug section, NULL if not.
    255    If RENAME is true it will rename LTO debug sections to non-LTO
    256    ones.  */
    257 
    258 static char *
    259 handle_lto_debug_sections (const char *name, int rename)
    260 {
    261   char *newname = rename ? XCNEWVEC (char, strlen (name) + 1)
    262 	  	         : xstrdup (name);
    263 
    264   /* ???  So we can't use .gnu.lto_ prefixed sections as the assembler
    265      complains about bogus section flags.  Which means we need to arrange
    266      for that to be fixed or .gnu.debuglto_ marked as SHF_EXCLUDE (to make
    267      fat lto object tooling work for the fat part).  */
    268   /* Also include corresponding reloc sections.  */
    269   if (strncmp (name, ".rela", sizeof (".rela") - 1) == 0)
    270     {
    271       if (rename)
    272         strncpy (newname, name, sizeof (".rela") - 1);
    273       name += sizeof (".rela") - 1;
    274     }
    275   else if (strncmp (name, ".rel", sizeof (".rel") - 1) == 0)
    276     {
    277       if (rename)
    278         strncpy (newname, name, sizeof (".rel") - 1);
    279       name += sizeof (".rel") - 1;
    280     }
    281   /* ???  For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed
    282      sections.  */
    283   /* Copy LTO debug sections and rename them to their non-LTO name.  */
    284   if (strncmp (name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0)
    285     return rename ? strcat (newname, name + sizeof (".gnu.debuglto_") - 1) : newname;
    286   else if (strncmp (name, ".gnu.lto_.debug_",
    287 		    sizeof (".gnu.lto_.debug_") -1) == 0)
    288     return rename ? strcat (newname, name + sizeof (".gnu.lto_") - 1) : newname;
    289   /* Copy over .note.GNU-stack section under the same name if present.  */
    290   else if (strcmp (name, ".note.GNU-stack") == 0)
    291     return strcpy (newname, name);
    292   /* Copy over .comment section under the same name if present.  Solaris
    293      ld uses them to relax its checking of ELF gABI access rules for
    294      COMDAT sections in objects produced by GCC.  */
    295   else if (strcmp (name, ".comment") == 0)
    296     return strcpy (newname, name);
    297   free (newname);
    298   return NULL;
    299 }
    300 
    301 /* Wrapper for handle_lto_debug_sections.  */
    302 
    303 static char *
    304 handle_lto_debug_sections_rename (const char *name)
    305 {
    306   return handle_lto_debug_sections (name, 1);
    307 }
    308 
    309 /* Wrapper for handle_lto_debug_sections.  */
    310 
    311 static char *
    312 handle_lto_debug_sections_norename (const char *name)
    313 {
    314   return handle_lto_debug_sections (name, 0);
    315 }
    316 
    317 /* Copy LTO debug sections.  */
    318 
    319 const char *
    320 simple_object_copy_lto_debug_sections (simple_object_read *sobj,
    321 				       const char *dest, int *err, int rename)
    322 {
    323   const char *errmsg;
    324   simple_object_write *dest_sobj;
    325   simple_object_attributes *attrs;
    326   int outfd;
    327 
    328   if (! sobj->functions->copy_lto_debug_sections)
    329     {
    330       *err = EINVAL;
    331       return "simple_object_copy_lto_debug_sections not implemented";
    332     }
    333 
    334   attrs = simple_object_fetch_attributes (sobj, &errmsg, err);
    335   if (! attrs)
    336     return errmsg;
    337   dest_sobj = simple_object_start_write (attrs, NULL, &errmsg, err);
    338   simple_object_release_attributes (attrs);
    339   if (! dest_sobj)
    340     return errmsg;
    341 
    342   errmsg = sobj->functions->copy_lto_debug_sections
    343 	 	 (sobj, dest_sobj,
    344 		  rename ? handle_lto_debug_sections_rename
    345 			 : handle_lto_debug_sections_norename,  err);
    346   if (errmsg)
    347     {
    348       simple_object_release_write (dest_sobj);
    349       return errmsg;
    350     }
    351 
    352   outfd = creat (dest, 00777);
    353   if (outfd == -1)
    354     {
    355       *err = errno;
    356       simple_object_release_write (dest_sobj);
    357       return "open failed";
    358     }
    359 
    360   errmsg = simple_object_write_to_file (dest_sobj, outfd, err);
    361   close (outfd);
    362   if (errmsg)
    363     {
    364       simple_object_release_write (dest_sobj);
    365       return errmsg;
    366     }
    367 
    368   simple_object_release_write (dest_sobj);
    369   return NULL;
    370 }
    371 
    372 /* Fetch attributes.  */
    373 
    374 simple_object_attributes *
    375 simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg,
    376 				int *err)
    377 {
    378   void *data;
    379   simple_object_attributes *ret;
    380 
    381   data = sobj->functions->fetch_attributes (sobj, errmsg, err);
    382   if (data == NULL)
    383     return NULL;
    384   ret = XNEW (simple_object_attributes);
    385   ret->functions = sobj->functions;
    386   ret->data = data;
    387   return ret;
    388 }
    389 
    390 /* Release an simple_object_read.  */
    391 
    392 void
    393 simple_object_release_read (simple_object_read *sobj)
    394 {
    395   sobj->functions->release_read (sobj->data);
    396   XDELETE (sobj);
    397 }
    398 
    399 /* Merge attributes.  */
    400 
    401 const char *
    402 simple_object_attributes_merge (simple_object_attributes *to,
    403 				simple_object_attributes *from,
    404 				int *err)
    405 {
    406   if (to->functions != from->functions)
    407     {
    408       *err = 0;
    409       return "different object file format";
    410     }
    411   return to->functions->attributes_merge (to->data, from->data, err);
    412 }
    413 
    414 /* Release an attributes structure.  */
    415 
    416 void
    417 simple_object_release_attributes (simple_object_attributes *attrs)
    418 {
    419   attrs->functions->release_attributes (attrs->data);
    420   XDELETE (attrs);
    421 }
    422 
    423 /* Start creating an object file.  */
    424 
    425 simple_object_write *
    426 simple_object_start_write (simple_object_attributes *attrs,
    427 			   const char *segment_name, const char **errmsg,
    428 			   int *err)
    429 {
    430   void *data;
    431   simple_object_write *ret;
    432 
    433   data = attrs->functions->start_write (attrs->data, errmsg, err);
    434   if (data == NULL)
    435     return NULL;
    436   ret = XNEW (simple_object_write);
    437   ret->functions = attrs->functions;
    438   ret->segment_name = segment_name ? xstrdup (segment_name) : NULL;
    439   ret->sections = NULL;
    440   ret->last_section = NULL;
    441   ret->data = data;
    442   return ret;
    443 }
    444 
    445 /* Start creating a section.  */
    446 
    447 simple_object_write_section *
    448 simple_object_write_create_section (simple_object_write *sobj, const char *name,
    449 				    unsigned int align,
    450 				    const char **errmsg ATTRIBUTE_UNUSED,
    451 				    int *err ATTRIBUTE_UNUSED)
    452 {
    453   simple_object_write_section *ret;
    454 
    455   ret = XNEW (simple_object_write_section);
    456   ret->next = NULL;
    457   ret->name = xstrdup (name);
    458   ret->align = align;
    459   ret->buffers = NULL;
    460   ret->last_buffer = NULL;
    461 
    462   if (sobj->last_section == NULL)
    463     {
    464       sobj->sections = ret;
    465       sobj->last_section = ret;
    466     }
    467   else
    468     {
    469       sobj->last_section->next = ret;
    470       sobj->last_section = ret;
    471     }
    472 
    473   return ret;
    474 }
    475 
    476 /* Add data to a section.  */
    477 
    478 const char *
    479 simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED,
    480 			      simple_object_write_section *section,
    481 			      const void *buffer,
    482 			      size_t size, int copy,
    483 			      int *err ATTRIBUTE_UNUSED)
    484 {
    485   struct simple_object_write_section_buffer *wsb;
    486 
    487   wsb = XNEW (struct simple_object_write_section_buffer);
    488   wsb->next = NULL;
    489   wsb->size = size;
    490 
    491   if (!copy)
    492     {
    493       wsb->buffer = buffer;
    494       wsb->free_buffer = NULL;
    495     }
    496   else
    497     {
    498       wsb->free_buffer = (void *) XNEWVEC (char, size);
    499       memcpy (wsb->free_buffer, buffer, size);
    500       wsb->buffer = wsb->free_buffer;
    501     }
    502 
    503   if (section->last_buffer == NULL)
    504     {
    505       section->buffers = wsb;
    506       section->last_buffer = wsb;
    507     }
    508   else
    509     {
    510       section->last_buffer->next = wsb;
    511       section->last_buffer = wsb;
    512     }
    513 
    514   return NULL;
    515 }
    516 
    517 /* Write the complete object file.  */
    518 
    519 const char *
    520 simple_object_write_to_file (simple_object_write *sobj, int descriptor,
    521 			     int *err)
    522 {
    523   return sobj->functions->write_to_file (sobj, descriptor, err);
    524 }
    525 
    526 /* Release an simple_object_write.  */
    527 
    528 void
    529 simple_object_release_write (simple_object_write *sobj)
    530 {
    531   simple_object_write_section *section;
    532 
    533   free (sobj->segment_name);
    534 
    535   section = sobj->sections;
    536   while (section != NULL)
    537     {
    538       struct simple_object_write_section_buffer *buffer;
    539       simple_object_write_section *next_section;
    540 
    541       buffer = section->buffers;
    542       while (buffer != NULL)
    543 	{
    544 	  struct simple_object_write_section_buffer *next_buffer;
    545 
    546 	  if (buffer->free_buffer != NULL)
    547 	    XDELETEVEC (buffer->free_buffer);
    548 	  next_buffer = buffer->next;
    549 	  XDELETE (buffer);
    550 	  buffer = next_buffer;
    551 	}
    552 
    553       next_section = section->next;
    554       free (section->name);
    555       XDELETE (section);
    556       section = next_section;
    557     }
    558 
    559   sobj->functions->release_write (sobj->data);
    560   XDELETE (sobj);
    561 }
    562