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