# HG changeset patch # User Richard M. Stallman # Date 779797341 0 # Node ID 678a41575de077d5f975848c02ed6e35a0cca95e # Parent dff46e860b511dfaf6c42d2ac093454c6ce161e3 [SUNOS4]: Include link.h. (unexec) [SUNOS4]: Cancel relocations that ld.so did. diff -r dff46e860b51 -r 678a41575de0 src/unexsunos4.c --- a/src/unexsunos4.c Sat Sep 17 07:30:42 1994 +0000 +++ b/src/unexsunos4.c Sat Sep 17 10:22:21 1994 +0000 @@ -1,3 +1,22 @@ +/* Unexec for Sunos 4 using shared libraries. + Copyright (C) 1990, 1994 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* Contributed by Viktor Dukhovni. */ /* * Unexec for Berkeley a.out format + SUNOS shared libraries @@ -37,6 +56,10 @@ #include #endif +#ifdef SUNOS4 +#include +#endif + #ifdef HAVE_UNISTD_H #include #endif @@ -183,6 +206,56 @@ lseek (new, N_TRELOFF (nhdr), L_SET); write (new, old + N_TRELOFF (ohdr), stat.st_size - N_TRELOFF (ohdr)); + /* Some other BSD systems use this file. + We don't know whether this change is right for them. */ +#ifdef SUNOS4 + /* Undo the relocations done at startup by ld.so. + It will do these relocations again when we start the dumped Emacs. + Doing them twice gives incorrect results. */ + { + extern struct link_dynamic _DYNAMIC; + unsigned long taddr = N_TXTADDR (ohdr); + unsigned long rel, erel; + unsigned rel_size; + + if (_DYNAMIC.ld_version < 2) + { + rel = _DYNAMIC.ld_un.ld_1->ld_rel; + erel = _DYNAMIC.ld_un.ld_1->ld_hash; + } + else + { + rel = _DYNAMIC.ld_un.ld_2->ld_rel; + erel = _DYNAMIC.ld_un.ld_2->ld_hash; + } + + switch (ohdr.a_machtype) + { + case M_68010: + case M_68020: + rel_size = 8; /* sizeof(struct reloc_info_m68k) */ + break; + case M_SPARC: + rel_size = 12; /* sizeof(struct reloc_info_sparc) */ + break; + case M_OLDSUN2: + default: + fatal ("unknown machine type in unexec!\n"); + } + + for (; rel < erel; rel += rel_size) + { + unsigned long rpos = *(unsigned long *)(taddr + rel) - taddr; + + if (rpos < (unsigned long)&data_start - taddr) + continue; + + lseek (new, N_TXTOFF (nhdr) + rpos, L_SET); + write (new, old + N_TXTOFF (ohdr) + rpos, sizeof (unsigned long)); + } + } +#endif /* SUNOS4 */ + fchmod (new, 0755); }