1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  *
  26  * dldump(3c) creates a new file image from the specified input file.
  27  */
  28 
  29 #include        <sys/param.h>
  30 #include        <sys/procfs.h>
  31 #include        <fcntl.h>
  32 #include        <stdio.h>
  33 #include        <libelf.h>
  34 #include        <link.h>
  35 #include        <dlfcn.h>
  36 #include        <stdlib.h>
  37 #include        <string.h>
  38 #include        <unistd.h>
  39 #include        <errno.h>
  40 #include        "libld.h"
  41 #include        "msg.h"
  42 #include        "_librtld.h"
  43 
  44 /*
  45  * Generic clean up routine
  46  */
  47 static void
  48 cleanup(Elf *ielf, Elf *oelf, Elf *melf, Cache *icache, Cache *mcache,
  49     int fd, const char *opath)
  50 {
  51         if (icache) {
  52                 Cache * _icache = icache;
  53 
  54                 for (++_icache; _icache->c_flags != FLG_C_END; _icache++) {
  55                         if (_icache->c_info)
  56                                 (void) free(_icache->c_info);
  57                 }
  58                 (void) free((void *)icache);
  59         }
  60         if (mcache)
  61                 (void) free((void *)mcache);
  62 
  63         if (ielf)
  64                 (void) elf_end(ielf);
  65         if (oelf)
  66                 (void) elf_end(oelf);
  67         if (melf)
  68                 (void) elf_end(melf);
  69         if (fd)
  70                 (void) close(fd);
  71         if (opath)
  72                 (void) unlink(opath);
  73 }
  74 
  75 /*
  76  * The dldump(3x) interface directs control to the runtime linker.  The runtime
  77  * linker brings in librtld.so.1 to provide the underlying support for this
  78  * call (this is because librtld.so.1 requires libelf.so.1, and the whole wad
  79  * is rather expensive to drag around with ld.so.1).
  80  *
  81  * rt_dldump(Rt_map * lmp, const char * opath, int flags, Addr addr)
  82  *
  83  * lmp provides the link-map of the ipath (the input file).
  84  *
  85  * opath specifies the output file.
  86  *
  87  * flags provides a variety of options that control how the new image will be
  88  * relocated (if required).
  89  *
  90  * addr indicates the base address at which the associated input image is mapped
  91  * within the process.
  92  *
  93  * The modes of operation and the various flags provide a number of combinations
  94  * of images that can be created, some are useful, some maybe not.  The
  95  * following provide a couple of basic models for dldump(3x) use:
  96  *
  97  *  new executable -    dldump(0, outfile, RTLD_MEMORY)
  98  *
  99  *                      A dynamic executable may undergo some initialization
 100  *                      and the results of this saved in a new file for later
 101  *                      execution.  The executable will presumable update
 102  *                      parts of its data segment and heap (note that the heap
 103  *                      should be acquired using malloc() so that it follows
 104  *                      the end of the data segment for this technique to be
 105  *                      useful).  These updated memory elements are saved to the
 106  *                      new file, including a new .SUNW_heap section if
 107  *                      required.
 108  *
 109  *                      For greatest flexibility, no relocated information
 110  *                      should be saved (by default any relocated information is
 111  *                      returned to the value it had in its original file).
 112  *                      This allows the new image to bind to new dynamic objects
 113  *                      when executed on the same or newer upgrades of the OS.
 114  *
 115  *                      Fixing relocations by applying RTLD_REL_ALL will bind
 116  *                      the image to the dependencies presently mapped as part
 117  *                      of the process.  Thus the new executable will only work
 118  *                      correctly when these same dependencies map to exactly
 119  *                      to the same locations. (note that RTLD_REL_RELATIVE will
 120  *                      have no effect as dynamic executables commonly don't
 121  *                      contain any relative relocations).
 122  *
 123  *  new shared object - dldump(infile, outfile, RTLD_REL_RELATIVE)
 124  *
 125  *                      A shared object can be fixed to a known address so as
 126  *                      to reduce its relocation overhead on startup.  Because
 127  *                      the new file is fixed to a new base address (which is
 128  *                      the address at which the object was found mapped to the
 129  *                      process) it is now a dynamic executable.
 130  *
 131  *                      Data changes that have occurred due to the object
 132  *                      gaining control (at the least this would be .init
 133  *                      processing) will not be carried over to the new image.
 134  *
 135  *                      By only performing relative relocations all global
 136  *                      relocations are available for unique binding to each
 137  *                      process - thus interposition etc. is still available.
 138  *
 139  *                      Using RTLD_REL_ALL will fix all relocations in the new
 140  *                      file, which will certainly provide for faster startup
 141  *                      of the new image, but at the loss of interposition
 142  *                      flexibility.
 143  */
 144 int
 145 rt_dldump(Rt_map *lmp, const char *opath, int flags, Addr addr)
 146 {
 147         Elf *           ielf = 0, *oelf = 0, *melf = 0;
 148         Ehdr            *iehdr, *oehdr, *mehdr;
 149         Phdr            *iphdr, *ophdr, *data_phdr = 0;
 150         Cache           *icache = 0, *_icache, *mcache = 0, *_mcache;
 151         Cache           *data_cache = 0, *dyn_cache = 0;
 152         Xword           rel_null_no = 0, rel_data_no = 0, rel_func_no = 0;
 153         Xword           rel_entsize;
 154         Rel             *rel_base = 0, *rel_null, *rel_data, *rel_func;
 155         Elf_Scn         *scn;
 156         Shdr            *shdr;
 157         Elf_Data        *data;
 158         Half            endx = 1;
 159         int             fd = 0, err, num;
 160         size_t          shstr_size = 1, shndx;
 161         Addr            edata;
 162         char            *shstr, *_shstr, *ipath = NAME(lmp);
 163         prstatus_t      *status = 0, _status;
 164         Lm_list         *lml = LIST(lmp);
 165         Alist           *nodirect = 0;
 166 
 167         if (lmp == lml_main.lm_head) {
 168                 char    proc[16];
 169                 int     pfd;
 170 
 171                 /*
 172                  * Get a /proc descriptor.
 173                  */
 174                 (void) snprintf(proc, 16, MSG_ORIG(MSG_FMT_PROC),
 175                     (int)getpid());
 176                 if ((pfd = open(proc, O_RDONLY)) == -1) {
 177                         err = errno;
 178                         eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), proc,
 179                             strerror(err));
 180                         return (1);
 181                 }
 182 
 183                 /*
 184                  * If we've been asked to process the dynamic executable we
 185                  * might not know its full path (this is prior to realpath()
 186                  * processing becoming default), and thus use /proc to obtain a
 187                  * file descriptor of the input file.
 188                  */
 189                 if ((fd = ioctl(pfd, PIOCOPENM, (void *)0)) == -1) {
 190                         err = errno;
 191                         eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC), ipath,
 192                             strerror(err));
 193                         (void) close(pfd);
 194                         return (1);
 195                 }
 196 
 197                 /*
 198                  * Obtain the process's status structure from which we can
 199                  * determine the size of the process's heap.  Note, if the
 200                  * application is using mapmalloc then the heap size is going
 201                  * to be zero, and if we're dumping a data section that makes
 202                  * reference to the malloc'ed area we're not going to get a
 203                  * useful image.
 204                  */
 205                 if (!(flags & RTLD_NOHEAP)) {
 206                         if (ioctl(pfd, PIOCSTATUS, (void *)&_status) == -1) {
 207                                 err = errno;
 208                                 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_PROC),
 209                                     ipath, strerror(err));
 210                                 (void) close(fd);
 211                                 (void) close(pfd);
 212                                 return (1);
 213                         }
 214                         if ((flags & RTLD_MEMORY) && _status.pr_brksize)
 215                                 status = &_status;
 216                 }
 217                 (void) close(pfd);
 218         } else {
 219                 /*
 220                  * Open the specified file.
 221                  */
 222                 if ((fd = open(ipath, O_RDONLY, 0)) == -1) {
 223                         err = errno;
 224                         eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), ipath,
 225                             strerror(err));
 226                         return (1);
 227                 }
 228         }
 229 
 230         /*
 231          * Initialize with the ELF library and make sure this is a suitable
 232          * ELF file we're dealing with.
 233          */
 234         (void) elf_version(EV_CURRENT);
 235         if ((ielf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
 236                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), ipath);
 237                 cleanup(ielf, oelf, melf, icache, mcache, fd, 0);
 238                 return (1);
 239         }
 240         (void) close(fd);
 241 
 242         if ((elf_kind(ielf) != ELF_K_ELF) ||
 243             ((iehdr = elf_getehdr(ielf)) == NULL) ||
 244             ((iehdr->e_type != ET_EXEC) && (iehdr->e_type != ET_DYN))) {
 245                 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_IMG_ELF), ipath);
 246                 cleanup(ielf, oelf, melf, icache, mcache, 0, 0);
 247                 return (1);
 248         }
 249 
 250         /*
 251          * Make sure we can create the new output file.
 252          */
 253         if ((fd = open(opath, (O_RDWR | O_CREAT | O_TRUNC), 0777)) == -1) {
 254                 err = errno;
 255                 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), opath,
 256                     strerror(err));
 257                 cleanup(ielf, oelf, melf, icache, mcache, 0, 0);
 258                 return (1);
 259         }
 260         if ((oelf = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) {
 261                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), opath);
 262                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 263                 return (1);
 264         }
 265 
 266         /*
 267          * Obtain the input program headers.  Remember the last data segments
 268          * program header entry as this will be updated later to reflect any new
 269          * heap section size.
 270          */
 271         if ((iphdr = elf_getphdr(ielf)) == NULL) {
 272                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETPHDR), ipath);
 273                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 274                 return (1);
 275         }
 276 
 277         for (num = 0, ophdr = iphdr; num != iehdr->e_phnum; num++, ophdr++) {
 278                 /*
 279                  * Save the program header that contains the NOBITS section, or
 280                  * the last loadable program header if no NOBITS exists.  A
 281                  * NOBITS section translates to a memory size requirement that
 282                  * is greater than the file data it is mapped from.  Note that
 283                  * we inspect all headers just incase there only exist text
 284                  * segments.
 285                  */
 286                 if (ophdr->p_type == PT_LOAD) {
 287                         if (ophdr->p_filesz != ophdr->p_memsz)
 288                                 data_phdr = ophdr;
 289                         else if (data_phdr) {
 290                                 if (data_phdr->p_vaddr < ophdr->p_vaddr)
 291                                         data_phdr = ophdr;
 292                         } else
 293                                 data_phdr = ophdr;
 294                 }
 295         }
 296 
 297         /*
 298          * If there is no data segment, and a heap section is required,
 299          * warn the user and disable the heap addition (Note that you can't
 300          * simply append the heap to the last segment, as it might be a text
 301          * segment, and would therefore have the wrong permissions).
 302          */
 303         if (status && !data_phdr) {
 304                 eprintf(lml, ERR_WARNING, MSG_INTL(MSG_IMG_DATASEG), ipath);
 305                 status = 0;
 306         }
 307 
 308         /*
 309          * Obtain the input files section header string table.
 310          */
 311 
 312         if (elf_getshdrstrndx(ielf, &shndx) == -1) {
 313                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRSTRNDX), ipath);
 314                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 315                 return (1);
 316         }
 317         if ((scn = elf_getscn(ielf, shndx)) == NULL) {
 318                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSCN), ipath);
 319                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 320                 return (1);
 321         }
 322         if ((data = elf_getdata(scn, NULL)) == NULL) {
 323                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), ipath);
 324                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 325                 return (1);
 326         }
 327         shstr = (char *)data->d_buf;
 328 
 329         /*
 330          * Construct a cache to maintain the input files section information.
 331          * Obtain an extra cache element if a heap addition is required.  Also
 332          * add an additional entry (marked FLG_C_END) to make the processing of
 333          * this cache easier.
 334          */
 335 
 336         if (elf_getshdrnum(ielf, &shndx) == -1) {
 337                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRNUM), opath);
 338                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 339                 return (1);
 340         }
 341 
 342         num = shndx;
 343 
 344         if (status)
 345                 num++;
 346         if ((icache = malloc((num + 1) * sizeof (Cache))) == 0) {
 347                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 348                 return (1);
 349         }
 350         icache[num].c_flags = FLG_C_END;
 351 
 352         _icache = icache;
 353         _icache++;
 354 
 355         /*
 356          * Traverse each section from the input file collecting the appropriate
 357          * ELF information.  Indicate how the section will be processed to
 358          * generate the output image.
 359          */
 360         for (scn = 0; scn = elf_nextscn(ielf, scn); _icache++) {
 361 
 362                 if ((_icache->c_shdr = shdr = elf_getshdr(scn)) == NULL) {
 363                         eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDR), ipath);
 364                         cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 365                         return (1);
 366                 }
 367 
 368                 if ((_icache->c_data = elf_getdata(scn, NULL)) == NULL) {
 369                         eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), ipath);
 370                         cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 371                         return (1);
 372                 }
 373                 _icache->c_name = shstr + (size_t)(shdr->sh_name);
 374                 _icache->c_scn = scn;
 375                 _icache->c_flags = 0;
 376                 _icache->c_info = 0;
 377 
 378                 /*
 379                  * Process any .SUNW_syminfo section.  Symbols that are tagged
 380                  * as NO_DIRECT are collected, as they should not be bound to.
 381                  */
 382                 if ((flags & ~RTLD_REL_RELATIVE) &&
 383                     (shdr->sh_type == SHT_SUNW_syminfo)) {
 384                         if (syminfo(_icache, &nodirect)) {
 385                                 cleanup(ielf, oelf, melf, icache, mcache,
 386                                     fd, opath);
 387                                 return (1);
 388                         }
 389                 }
 390 
 391                 /*
 392                  * If the section has no address it is not part of the mapped
 393                  * image, and is unlikely to require any further processing.
 394                  * The section header string table will be rewritten (this isn't
 395                  * always necessary, it's only really required when relocation
 396                  * sections are renamed or sections are stripped, but we do
 397                  * things the same way regardless).
 398                  */
 399                 if (shdr->sh_addr == 0) {
 400                         if ((shdr->sh_type == SHT_STRTAB) &&
 401                             ((strcmp(_icache->c_name,
 402                             MSG_ORIG(MSG_SCN_SHSTR))) == 0))
 403                                 _icache->c_flags = FLG_C_SHSTR;
 404                         else if (flags & RTLD_STRIP) {
 405                                 _icache->c_flags = FLG_C_EXCLUDE;
 406                                 continue;
 407                         }
 408                 }
 409 
 410                 /*
 411                  * Skip relocation sections for the time being, they'll be
 412                  * analyzed after all sections have been processed.
 413                  */
 414                 if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr)
 415                         continue;
 416 
 417                 /*
 418                  * Sections at this point will simply be passed through to the
 419                  * output file.  Keep track of the section header string table
 420                  * size.
 421                  */
 422                 shstr_size += strlen(_icache->c_name) + 1;
 423 
 424                 /*
 425                  * If a heap section is to be added to the output image,
 426                  * indicate that it will be added following the last data
 427                  * section.
 428                  */
 429                 if (shdr->sh_addr && ((shdr->sh_addr + shdr->sh_size) ==
 430                     (data_phdr->p_vaddr + data_phdr->p_memsz))) {
 431                         data_cache = _icache;
 432 
 433                         if (status) {
 434                                 _icache++;
 435                                 _icache->c_name =
 436                                     (char *)MSG_ORIG(MSG_SCN_HEAP);
 437                                 _icache->c_flags = FLG_C_HEAP;
 438 
 439                                 _icache->c_scn = 0;
 440                                 _icache->c_shdr = 0;
 441                                 _icache->c_data = 0;
 442                                 _icache->c_info = 0;
 443 
 444                                 shstr_size += strlen(_icache->c_name) + 1;
 445                         }
 446                 }
 447         }
 448 
 449         /*
 450          * Now that we've processed all input sections count the relocation
 451          * entries (relocation sections need to reference their symbol tables).
 452          */
 453         _icache = icache;
 454         for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
 455 
 456                 if ((shdr = _icache->c_shdr) == 0)
 457                         continue;
 458 
 459                 /*
 460                  * If any form of relocations are to be applied to the output
 461                  * image determine what relocation counts exist.  These will be
 462                  * used to reorganize (localize) the relocation records.
 463                  */
 464                 if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr) {
 465                         rel_entsize = shdr->sh_entsize;
 466 
 467                         if (count_reloc(icache, _icache, lmp, flags, addr,
 468                             &rel_null_no, &rel_data_no, &rel_func_no,
 469                             nodirect)) {
 470                                 cleanup(ielf, oelf, melf, icache, mcache,
 471                                     fd, opath);
 472                                 return (1);
 473                         }
 474                 }
 475         }
 476 
 477         /*
 478          * If any form of relocations are to be applied to the output image
 479          * then we will reorganize (localize) the relocation records.  If this
 480          * reorganization occurs, the relocation sections will no longer have a
 481          * one-to-one relationship with the section they relocate, hence we
 482          * rename them to a more generic name.
 483          */
 484         _icache = icache;
 485         for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
 486 
 487                 if ((shdr = _icache->c_shdr) == 0)
 488                         continue;
 489 
 490                 if ((shdr->sh_type == M_REL_SHT_TYPE) && shdr->sh_addr) {
 491                         if (rel_null_no) {
 492                                 _icache->c_flags = FLG_C_RELOC;
 493                                 _icache->c_name =
 494                                     (char *)MSG_ORIG(MSG_SCN_RELOC);
 495                         }
 496                         shstr_size += strlen(_icache->c_name) + 1;
 497                 }
 498         }
 499 
 500 
 501         /*
 502          * If there is no data section, and a heap is required, warn the user
 503          * and disable the heap addition.
 504          */
 505         if (!data_cache) {
 506                 eprintf(lml, ERR_WARNING, MSG_INTL(MSG_IMG_DATASEC), ipath);
 507                 status = 0;
 508                 endx = 0;
 509         }
 510 
 511         /*
 512          * Determine the value of _edata (which will also be _end) and its
 513          * section index for updating the data segments phdr and symbol table
 514          * information later.  If a new heap section is being added, update
 515          * the values appropriately.
 516          */
 517         edata = data_phdr->p_vaddr + data_phdr->p_memsz;
 518         if (status)
 519                 edata += status->pr_brksize;
 520 
 521         if (endx) {
 522                 /* LINTED */
 523                 endx = (Half)elf_ndxscn(data_cache->c_scn);
 524                 if (status)
 525                         endx++;
 526         }
 527 
 528         /*
 529          * We're now ready to construct the new elf image.
 530          *
 531          * Obtain a new elf header and initialize it with any basic information
 532          * that isn't calculated as part of elf_update().
 533          */
 534         if ((oehdr = elf_newehdr(oelf)) == NULL) {
 535                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWEHDR), opath);
 536                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 537                 return (1);
 538         }
 539         oehdr->e_machine = iehdr->e_machine;
 540         oehdr->e_flags = iehdr->e_flags;
 541         oehdr->e_type = ET_EXEC;
 542         oehdr->e_entry = iehdr->e_entry;
 543         if (addr)
 544                 oehdr->e_entry += addr;
 545 
 546         /*
 547          * Obtain a new set of program headers.  Initialize these with the same
 548          * information as the input program headers.  Update the virtual address
 549          * and the data segments size to reflect any new heap section.
 550          */
 551         if ((ophdr = elf_newphdr(oelf, iehdr->e_phnum)) == NULL) {
 552                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWPHDR), opath);
 553                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 554                 return (1);
 555         }
 556         for (num = 0; num != iehdr->e_phnum; num++, iphdr++, ophdr++) {
 557                 *ophdr = *iphdr;
 558                 if ((ophdr->p_type != PT_INTERP) && (ophdr->p_type != PT_NOTE))
 559                         ophdr->p_vaddr += addr;
 560                 if (data_phdr == iphdr) {
 561                         if (status)
 562                                 ophdr->p_memsz = edata - ophdr->p_vaddr;
 563                         ophdr->p_filesz = ophdr->p_memsz;
 564                 }
 565         }
 566 
 567         /*
 568          * Establish a buffer for the new section header string table.  This
 569          * will be filled in as each new section is created.
 570          */
 571         if ((shstr = malloc(shstr_size)) == 0) {
 572                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 573                 return (1);
 574         }
 575         _shstr = shstr;
 576         *_shstr++ = '\0';
 577 
 578         /*
 579          * Use the input files cache information to generate new sections.
 580          */
 581         _icache = icache;
 582         for (_icache++; _icache->c_flags != FLG_C_END; _icache++) {
 583                 /*
 584                  * Skip any excluded sections.
 585                  */
 586                 if (_icache->c_flags == FLG_C_EXCLUDE)
 587                         continue;
 588 
 589                 /*
 590                  * Create a matching section header in the output file.
 591                  */
 592                 if ((scn = elf_newscn(oelf)) == NULL) {
 593                         eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWSCN), opath);
 594                         cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 595                         return (1);
 596                 }
 597                 if ((shdr = elf_getshdr(scn)) == NULL) {
 598                         eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWSHDR), opath);
 599                         cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 600                         return (1);
 601                 }
 602 
 603                 /*
 604                  * If this is the heap section initialize the appropriate
 605                  * entries, otherwise simply use the original section header
 606                  * information.
 607                  */
 608                 if (_icache->c_flags == FLG_C_HEAP) {
 609                         shdr->sh_type = SHT_PROGBITS;
 610                         shdr->sh_flags = SHF_ALLOC | SHF_WRITE;
 611                 } else
 612                         *shdr = *_icache->c_shdr;
 613 
 614                 /*
 615                  * Create a matching data buffer for this section.
 616                  */
 617                 if ((data = elf_newdata(scn)) == NULL) {
 618                         eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_NEWDATA), opath);
 619                         cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 620                         return (1);
 621                 }
 622 
 623                 /*
 624                  * Determine what data will be used for this section.
 625                  */
 626                 if (_icache->c_flags == FLG_C_SHSTR) {
 627                         /*
 628                          * Reassign the shstrtab to the new data buffer we're
 629                          * creating.  Insure that the new elf header references
 630                          * this section header table.
 631                          */
 632                         *data = *_icache->c_data;
 633 
 634                         data->d_buf = (void *)shstr;
 635                         data->d_size = shstr_size;
 636 
 637                         _icache->c_info = shstr;
 638 
 639                         /* LINTED */
 640                         if (elf_ndxscn(scn) >= SHN_LORESERVE) {
 641                                 Elf_Scn *_scn;
 642                                 Shdr    *shdr0;
 643 
 644                                 /*
 645                                  * libelf deals with e_shnum for us, but we
 646                                  * need to deal with e_shstrndx ourselves.
 647                                  */
 648                                 oehdr->e_shstrndx = SHN_XINDEX;
 649                                 if ((_scn = elf_getscn(oelf, 0)) == NULL) {
 650                                         eprintf(lml, ERR_ELF,
 651                                             MSG_ORIG(MSG_ELF_GETSCN), opath);
 652                                         cleanup(ielf, oelf, melf, icache,
 653                                             mcache, fd, opath);
 654                                         return (1);
 655                                 }
 656                                 shdr0 = elf_getshdr(_scn);
 657                                 shdr0->sh_link = elf_ndxscn(scn);
 658                         } else {
 659                                 oehdr->e_shstrndx = (Half)elf_ndxscn(scn);
 660                         }
 661 
 662                 } else if (_icache->c_flags == FLG_C_HEAP) {
 663                         /*
 664                          * Assign the heap to the appropriate memory offset.
 665                          */
 666                         data->d_buf = status->pr_brkbase;
 667                         data->d_type = ELF_T_BYTE;
 668                         data->d_size = (size_t)status->pr_brksize;
 669                         data->d_off = 0;
 670                         data->d_align = 1;
 671                         data->d_version = EV_CURRENT;
 672 
 673                         shdr->sh_addr = data_cache->c_shdr->sh_addr +
 674                             data_cache->c_shdr->sh_size;
 675 
 676                 } else if (_icache->c_flags == FLG_C_RELOC) {
 677                         /*
 678                          * If some relocations are to be saved in the new image
 679                          * then the relocation sections will be reorganized to
 680                          * localize their contents.  These relocation sections
 681                          * will no longer have a one-to-one relationship with
 682                          * the section they relocate, hence we rename them and
 683                          * remove their sh_info info.
 684                          */
 685                         *data = *_icache->c_data;
 686 
 687                         shdr->sh_info = 0;
 688 
 689                 } else {
 690                         /*
 691                          * By default simply pass the section through.  If
 692                          * we've been asked to use the memory image of the
 693                          * input file reestablish the data buffer address.
 694                          */
 695                         *data = *_icache->c_data;
 696 
 697                         if ((shdr->sh_addr) && (flags & RTLD_MEMORY))
 698                                 data->d_buf = (void *)(shdr->sh_addr + addr);
 699 
 700                         /*
 701                          * Update any NOBITS section to indicate that it now
 702                          * contains data.  If this image is being created
 703                          * directly from the input file, zero out the .bss
 704                          * section (this saves ld.so.1 having to zero out memory
 705                          * or do any /dev/zero mappings).
 706                          */
 707                         if (shdr->sh_type == SHT_NOBITS) {
 708                                 shdr->sh_type = SHT_PROGBITS;
 709                                 if (!(flags & RTLD_MEMORY)) {
 710                                         if ((data->d_buf = calloc(1,
 711                                             data->d_size)) == 0) {
 712                                                 cleanup(ielf, oelf, melf,
 713                                                     icache, mcache, fd, opath);
 714                                                 return (1);
 715                                         }
 716                                 }
 717                         }
 718                 }
 719 
 720                 /*
 721                  * Update the section header string table.
 722                  */
 723                 /* LINTED */
 724                 shdr->sh_name = (Word)(_shstr - shstr);
 725                 (void) strcpy(_shstr, _icache->c_name);
 726                 _shstr = _shstr + strlen(_icache->c_name) + 1;
 727 
 728                 /*
 729                  * For each section that has a virtual address update its
 730                  * address to the fixed location of the new image.
 731                  */
 732                 if (shdr->sh_addr)
 733                         shdr->sh_addr += addr;
 734 
 735                 /*
 736                  * If we've inserted a new section any later sections may need
 737                  * their sh_link fields updated (.stabs comes to mind).
 738                  */
 739                 if (status && endx && (shdr->sh_link >= endx))
 740                         shdr->sh_link++;
 741         }
 742 
 743         /*
 744          * Generate the new image, and obtain a new elf descriptor that will
 745          * allow us to write and update the new image.
 746          */
 747         if (elf_update(oelf, ELF_C_WRIMAGE) == -1) {
 748                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_UPDATE), opath);
 749                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 750                 return (1);
 751         }
 752         if ((melf = elf_begin(0, ELF_C_IMAGE, oelf)) == NULL) {
 753                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_BEGIN), opath);
 754                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 755                 return (1);
 756         }
 757         if ((mehdr = elf_getehdr(melf)) == NULL) {
 758                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETEHDR), opath);
 759                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 760                 return (1);
 761         }
 762 
 763         if (elf_getshdrnum(melf, &shndx) == -1) {
 764                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDRNUM), opath);
 765                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 766                 return (1);
 767         }
 768 
 769         /*
 770          * Construct a cache to maintain the memory files section information.
 771          */
 772         if ((mcache = malloc(shndx * sizeof (Cache))) == 0) {
 773                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 774                 return (1);
 775         }
 776         _mcache = mcache;
 777         _mcache++;
 778 
 779         for (scn = 0; scn = elf_nextscn(melf, scn); _mcache++) {
 780 
 781                 if ((_mcache->c_shdr = elf_getshdr(scn)) == NULL) {
 782                         eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETSHDR), opath);
 783                         cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 784                         return (1);
 785                 }
 786 
 787                 if ((_mcache->c_data = elf_getdata(scn, NULL)) == NULL) {
 788                         eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_GETDATA), opath);
 789                         cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 790                         return (1);
 791                 }
 792         }
 793 
 794         /*
 795          * Now that we have a complete description of the new image update any
 796          * sections that are required.
 797          *
 798          *  o   reset any symbol table entries.
 799          *
 800          *  o   reset any relocation entries.
 801          *
 802          *  o   reset dynamic entries.
 803          */
 804         _mcache = &mcache[0];
 805         for (_icache = &icache[1]; _icache->c_flags != FLG_C_END; _icache++) {
 806 
 807                 if (_icache->c_flags == FLG_C_EXCLUDE)
 808                         continue;
 809 
 810                 _mcache++;
 811                 shdr = _mcache->c_shdr;
 812 
 813                 /*
 814                  * Update the symbol table entries.  _end and _edata will be
 815                  * changed to reflect any heap addition.  All global symbols
 816                  * will be updated to their new fixed address.
 817                  */
 818                 if ((shdr->sh_type == SHT_SYMTAB) ||
 819                     (shdr->sh_type == SHT_DYNSYM) ||
 820                     (shdr->sh_type == SHT_SUNW_LDYNSYM)) {
 821                         update_sym(mcache, _mcache, edata, endx, addr);
 822                         continue;
 823                 }
 824 
 825                 /*
 826                  * Update any relocations.  All relocation requirements will
 827                  * have been established in count_reloc().
 828                  */
 829                 if (shdr->sh_type == M_REL_SHT_TYPE) {
 830                         if (rel_base == (Rel *)0) {
 831                                 rel_base = (Rel *)_mcache->c_data->d_buf;
 832                                 rel_null = rel_base;
 833                                 rel_data = (Rel *)((Xword)rel_null +
 834                                     (rel_null_no * rel_entsize));
 835                                 rel_func = (Rel *)((Xword)rel_data +
 836                                     (rel_data_no * rel_entsize));
 837                         }
 838 
 839                         update_reloc(mcache, icache, _icache, opath, lmp,
 840                             &rel_null, &rel_data, &rel_func);
 841                         continue;
 842                 }
 843 
 844                 /*
 845                  * Perform any dynamic entry updates after all relocation
 846                  * processing has been carried out (as its possible the .dynamic
 847                  * section could occur before the .rel sections, delay this
 848                  * processing until last).
 849                  */
 850                 if (shdr->sh_type == SHT_DYNAMIC)
 851                         dyn_cache = _mcache;
 852         }
 853 
 854         if (dyn_cache) {
 855                 Xword   off = (Xword)rel_base - (Xword)mehdr;
 856 
 857                 /*
 858                  * If we're dumping a fixed object (typically the dynamic
 859                  * executable) compensate for its real base address.
 860                  */
 861                 if (!addr)
 862                         off += ADDR(lmp);
 863 
 864                 if (update_dynamic(mcache, dyn_cache, lmp, flags, addr, off,
 865                     opath, rel_null_no, rel_data_no, rel_func_no, rel_entsize,
 866                     elf_checksum(melf))) {
 867                         cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 868                         return (1);
 869                 }
 870         }
 871 
 872         /*
 873          * Having completed all section updates write the memory file out.
 874          */
 875         if (elf_update(oelf, ELF_C_WRITE) == -1) {
 876                 eprintf(lml, ERR_ELF, MSG_ORIG(MSG_ELF_UPDATE), opath);
 877                 cleanup(ielf, oelf, melf, icache, mcache, fd, opath);
 878                 return (1);
 879         }
 880 
 881         cleanup(ielf, oelf, melf, icache, mcache, fd, 0);
 882         return (0);
 883 }