/* Dump for the HP-PA. It needs some work; for instance, it currently * assumes that the data space is the last space in the a.out file. * If it weren't the last space, the code would have to adjust pointers * (such as header.space_location) that point into spaces beyond the * data space, as the data space in the new a.out is larger than that * in the original a.out. * * Also, it is unclear how the checksum field in the a.out header has * to be computed. * * An a.out file must not have holes in HP-UX (or exec(2) would complain * about an invalid data segment), therefore we cannot lseek over the * ununsed parts of the heap. * * The code to support dump with a dynamically linked a.out is a hack. * I have no idea why it works and if it will continue to work in * newer OS releases. */ #include AOUT_H #define copy(from,to,size) {\ char buf[4096];\ int len = (size), n;\ \ while (len > 0) {\ if ((n = read (from, buf, 4096)) == -1) {\ Dump_Finalize;\ Primitive_Error ("error reading old a.out: ~E");\ }\ if (write (to, buf, n) == -1) {\ Dump_Finalize;\ Primitive_Error ("error writing new a.out: ~E");\ }\ len -= n;\ }\ } Object P_Dump (Object ofile) { struct header hdr; struct som_exec_auxhdr auxhdr; unsigned int data_size; int delta; struct stat stat; extern void *sbrk(); Dump_Prolog; /* Read a.out header and first aux header */ if (read (afd, (char *)&hdr, sizeof (hdr)) != sizeof (hdr) || lseek (afd, (off_t)hdr.aux_header_location, SEEK_SET) == -1 || read (afd, (char *)&auxhdr, sizeof (auxhdr)) != sizeof (auxhdr)) { Dump_Finalize; Primitive_Error ("can't read a.out headers"); } if (hdr.a_magic != EXEC_MAGIC && hdr.a_magic != SHARE_MAGIC && hdr.a_magic != DEMAND_MAGIC) { Dump_Finalize; Primitive_Error ("bad magic number ~s in a.out", Make_Integer (hdr.a_magic)); } if (auxhdr.som_auxhdr.type != HPUX_AUX_ID) { Dump_Finalize; Primitive_Error ("bad aux header id ~s in a.out", Make_Integer (auxhdr.som_auxhdr.type)); } /* Copy old file up to beginning of data space */ (void)lseek (afd, (off_t)0, SEEK_SET); copy (afd, ofd, auxhdr.exec_dfile); #ifdef HPSHLIB /* Save data segments of shared libraries */ Save_Shared_Data (); #endif /* Write data space (doesn't skip holes in heap yet) */ Was_Dumped = 1; Brk_On_Dump = sbrk (0); data_size = Brk_On_Dump - (char *)auxhdr.exec_dmem; if (write (ofd, (char *)auxhdr.exec_dmem, data_size) != data_size) { Dump_Finalize; Primitive_Error ("error writing data space: ~E"); } /* Check if data space was last space in a.out file. * Should not just quit, but adjust all pointers that point * beyond end of data space */ (void)fstat (afd, &stat); if (lseek (afd, (off_t)auxhdr.exec_dsize, SEEK_CUR) != stat.st_size) Primitive_Error ("$DATA$ not last space in a.out file"); /* Write new headers. * Do we have to recalculate the checksum? The manual doesn't * say how the checksum is calculated. */ delta = data_size - auxhdr.exec_dsize; hdr.som_length += delta; auxhdr.exec_dsize = data_size; auxhdr.exec_bsize = 0; (void)lseek (ofd, (off_t)0, SEEK_SET); if (write (ofd, (char *)&hdr, sizeof (hdr)) == -1 || lseek (ofd, (off_t)hdr.aux_header_location, SEEK_SET) == -1 || write (ofd, (char *)&auxhdr, sizeof (auxhdr)) == -1) { Dump_Finalize; Primitive_Error ("error writing a.out headers: ~E"); } Dump_Epilog; } #ifdef HPSHLIB /* Save and restore data segments of shared libraries. * * When the running program is dumped, we copy the data segment of * each shared library into a malloced area so that it gets saved * into the newly created a.out. * * On startup of the new a.out, we have to restore the data segments. * To do so, we first have to re-load all libraries that were present * in the old a.out when dump was called. * As the libraries may now get mapped to different locations, we * call mmap with an anonymous file to make the memory at the old * locations accessible again. */ #include