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 1 if NAME is a LTO debug section, 0 if not. */ 255 256 static int 257 handle_lto_debug_sections (const char **name) 258 { 259 /* ??? So we can't use .gnu.lto_ prefixed sections as the assembler 260 complains about bogus section flags. Which means we need to arrange 261 for that to be fixed or .gnu.debuglto_ marked as SHF_EXCLUDE (to make 262 fat lto object tooling work for the fat part). */ 263 /* ??? For now this handles both .gnu.lto_ and .gnu.debuglto_ prefixed 264 sections. */ 265 /* Copy LTO debug sections and rename them to their non-LTO name. */ 266 if (strncmp (*name, ".gnu.debuglto_", sizeof (".gnu.debuglto_") - 1) == 0) 267 { 268 *name = *name + sizeof (".gnu.debuglto_") - 1; 269 return 1; 270 } 271 else if (strncmp (*name, ".gnu.lto_.debug_", sizeof (".gnu.lto_.debug_") -1) == 0) 272 { 273 *name = *name + sizeof (".gnu.lto_") - 1; 274 return 1; 275 } 276 /* Copy over .note.GNU-stack section under the same name if present. */ 277 else if (strcmp (*name, ".note.GNU-stack") == 0) 278 return 1; 279 return 0; 280 } 281 282 /* Copy LTO debug sections. */ 283 284 const char * 285 simple_object_copy_lto_debug_sections (simple_object_read *sobj, 286 const char *dest, int *err) 287 { 288 const char *errmsg; 289 simple_object_write *dest_sobj; 290 simple_object_attributes *attrs; 291 int outfd; 292 293 if (! sobj->functions->copy_lto_debug_sections) 294 { 295 *err = EINVAL; 296 return "simple_object_copy_lto_debug_sections not implemented"; 297 } 298 299 attrs = simple_object_fetch_attributes (sobj, &errmsg, err); 300 if (! attrs) 301 return errmsg; 302 dest_sobj = simple_object_start_write (attrs, NULL, &errmsg, err); 303 simple_object_release_attributes (attrs); 304 if (! dest_sobj) 305 return errmsg; 306 307 errmsg = sobj->functions->copy_lto_debug_sections (sobj, dest_sobj, 308 handle_lto_debug_sections, 309 err); 310 if (errmsg) 311 { 312 simple_object_release_write (dest_sobj); 313 return errmsg; 314 } 315 316 outfd = creat (dest, 00777); 317 if (outfd == -1) 318 { 319 *err = errno; 320 simple_object_release_write (dest_sobj); 321 return "open failed"; 322 } 323 324 errmsg = simple_object_write_to_file (dest_sobj, outfd, err); 325 close (outfd); 326 if (errmsg) 327 { 328 simple_object_release_write (dest_sobj); 329 return errmsg; 330 } 331 332 simple_object_release_write (dest_sobj); 333 return NULL; 334 } 335 336 /* Fetch attributes. */ 337 338 simple_object_attributes * 339 simple_object_fetch_attributes (simple_object_read *sobj, const char **errmsg, 340 int *err) 341 { 342 void *data; 343 simple_object_attributes *ret; 344 345 data = sobj->functions->fetch_attributes (sobj, errmsg, err); 346 if (data == NULL) 347 return NULL; 348 ret = XNEW (simple_object_attributes); 349 ret->functions = sobj->functions; 350 ret->data = data; 351 return ret; 352 } 353 354 /* Release an simple_object_read. */ 355 356 void 357 simple_object_release_read (simple_object_read *sobj) 358 { 359 sobj->functions->release_read (sobj->data); 360 XDELETE (sobj); 361 } 362 363 /* Merge attributes. */ 364 365 const char * 366 simple_object_attributes_merge (simple_object_attributes *to, 367 simple_object_attributes *from, 368 int *err) 369 { 370 if (to->functions != from->functions) 371 { 372 *err = 0; 373 return "different object file format"; 374 } 375 return to->functions->attributes_merge (to->data, from->data, err); 376 } 377 378 /* Release an attributes structure. */ 379 380 void 381 simple_object_release_attributes (simple_object_attributes *attrs) 382 { 383 attrs->functions->release_attributes (attrs->data); 384 XDELETE (attrs); 385 } 386 387 /* Start creating an object file. */ 388 389 simple_object_write * 390 simple_object_start_write (simple_object_attributes *attrs, 391 const char *segment_name, const char **errmsg, 392 int *err) 393 { 394 void *data; 395 simple_object_write *ret; 396 397 data = attrs->functions->start_write (attrs->data, errmsg, err); 398 if (data == NULL) 399 return NULL; 400 ret = XNEW (simple_object_write); 401 ret->functions = attrs->functions; 402 ret->segment_name = segment_name ? xstrdup (segment_name) : NULL; 403 ret->sections = NULL; 404 ret->last_section = NULL; 405 ret->data = data; 406 return ret; 407 } 408 409 /* Start creating a section. */ 410 411 simple_object_write_section * 412 simple_object_write_create_section (simple_object_write *sobj, const char *name, 413 unsigned int align, 414 const char **errmsg ATTRIBUTE_UNUSED, 415 int *err ATTRIBUTE_UNUSED) 416 { 417 simple_object_write_section *ret; 418 419 ret = XNEW (simple_object_write_section); 420 ret->next = NULL; 421 ret->name = xstrdup (name); 422 ret->align = align; 423 ret->buffers = NULL; 424 ret->last_buffer = NULL; 425 426 if (sobj->last_section == NULL) 427 { 428 sobj->sections = ret; 429 sobj->last_section = ret; 430 } 431 else 432 { 433 sobj->last_section->next = ret; 434 sobj->last_section = ret; 435 } 436 437 return ret; 438 } 439 440 /* Add data to a section. */ 441 442 const char * 443 simple_object_write_add_data (simple_object_write *sobj ATTRIBUTE_UNUSED, 444 simple_object_write_section *section, 445 const void *buffer, 446 size_t size, int copy, 447 int *err ATTRIBUTE_UNUSED) 448 { 449 struct simple_object_write_section_buffer *wsb; 450 451 wsb = XNEW (struct simple_object_write_section_buffer); 452 wsb->next = NULL; 453 wsb->size = size; 454 455 if (!copy) 456 { 457 wsb->buffer = buffer; 458 wsb->free_buffer = NULL; 459 } 460 else 461 { 462 wsb->free_buffer = (void *) XNEWVEC (char, size); 463 memcpy (wsb->free_buffer, buffer, size); 464 wsb->buffer = wsb->free_buffer; 465 } 466 467 if (section->last_buffer == NULL) 468 { 469 section->buffers = wsb; 470 section->last_buffer = wsb; 471 } 472 else 473 { 474 section->last_buffer->next = wsb; 475 section->last_buffer = wsb; 476 } 477 478 return NULL; 479 } 480 481 /* Write the complete object file. */ 482 483 const char * 484 simple_object_write_to_file (simple_object_write *sobj, int descriptor, 485 int *err) 486 { 487 return sobj->functions->write_to_file (sobj, descriptor, err); 488 } 489 490 /* Release an simple_object_write. */ 491 492 void 493 simple_object_release_write (simple_object_write *sobj) 494 { 495 simple_object_write_section *section; 496 497 free (sobj->segment_name); 498 499 section = sobj->sections; 500 while (section != NULL) 501 { 502 struct simple_object_write_section_buffer *buffer; 503 simple_object_write_section *next_section; 504 505 buffer = section->buffers; 506 while (buffer != NULL) 507 { 508 struct simple_object_write_section_buffer *next_buffer; 509 510 if (buffer->free_buffer != NULL) 511 XDELETEVEC (buffer->free_buffer); 512 next_buffer = buffer->next; 513 XDELETE (buffer); 514 buffer = next_buffer; 515 } 516 517 next_section = section->next; 518 free (section->name); 519 XDELETE (section); 520 section = next_section; 521 } 522 523 sobj->functions->release_write (sobj->data); 524 XDELETE (sobj); 525 } 526