1 /* Copyright (C) 1985-1988, 1990, 1992, 1999-2021 Free Software
2    Foundation, Inc.
3 
4 This file is part of GNU Emacs.
5 
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or (at
9 your option) any later version.
10 
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
18 
19 /*
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them.   Help stamp out software-hoarding!  */
23 
24 
25 /*
26  * unexec.c - Convert a running program into an a.out file.
27  *
28  * Author:	Spencer W. Thomas
29  *		Computer Science Dept.
30  *		University of Utah
31  * Date:	Tue Mar  2 1982
32  * Modified heavily since then.
33  *
34  * Synopsis:
35  *	unexec (const char *new_name, const char *old_name);
36  *
37  * Takes a snapshot of the program and makes an a.out format file in the
38  * file named by the string argument new_name.
39  * If old_name is non-NULL, the symbol table will be taken from the given file.
40  * On some machines, an existing old_name file is required.
41  *
42  */
43 
44 /* We do not use mmap because that fails with NFS.
45    Instead we read the whole file, modify it, and write it out.  */
46 
47 #include <config.h>
48 #include "unexec.h"
49 #include "lisp.h"
50 
51 #include <errno.h>
52 #include <fcntl.h>
53 #include <limits.h>
54 #include <memory.h>
55 #include <stdint.h>
56 #include <stdio.h>
57 #include <sys/stat.h>
58 #include <sys/types.h>
59 #include <unistd.h>
60 
61 #ifdef __QNX__
62 # include <sys/elf.h>
63 #elif !defined __NetBSD__ && !defined __OpenBSD__
64 # include <elf.h>
65 #endif
66 #include <sys/mman.h>
67 #if defined (_SYSTYPE_SYSV)
68 #include <sys/elf_mips.h>
69 #include <sym.h>
70 #endif /* _SYSTYPE_SYSV */
71 
72 #ifndef MAP_ANON
73 #ifdef MAP_ANONYMOUS
74 #define MAP_ANON MAP_ANONYMOUS
75 #else
76 #define MAP_ANON 0
77 #endif
78 #endif
79 
80 #ifndef MAP_FAILED
81 #define MAP_FAILED ((void *) -1)
82 #endif
83 
84 #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
85 /* Declare COFF debugging symbol table.  This used to be in
86    /usr/include/sym.h, but this file is no longer included in Red Hat
87    5.0 and presumably in any other glibc 2.x based distribution.  */
88 typedef struct {
89 	short magic;
90 	short vstamp;
91 	int ilineMax;
92 	int idnMax;
93 	int ipdMax;
94 	int isymMax;
95 	int ioptMax;
96 	int iauxMax;
97 	int issMax;
98 	int issExtMax;
99 	int ifdMax;
100 	int crfd;
101 	int iextMax;
102 	long cbLine;
103 	long cbLineOffset;
104 	long cbDnOffset;
105 	long cbPdOffset;
106 	long cbSymOffset;
107 	long cbOptOffset;
108 	long cbAuxOffset;
109 	long cbSsOffset;
110 	long cbSsExtOffset;
111 	long cbFdOffset;
112 	long cbRfdOffset;
113 	long cbExtOffset;
114 } HDRR, *pHDRR;
115 #define cbHDRR sizeof (HDRR)
116 #define hdrNil ((pHDRR)0)
117 #endif
118 
119 #ifdef __NetBSD__
120 /*
121  * NetBSD does not have normal-looking user-land ELF support.
122  */
123 # if defined __alpha__ || defined __sparc_v9__ || defined _LP64
124 #  define ELFSIZE	64
125 # else
126 #  define ELFSIZE	32
127 # endif
128 # include <sys/exec_elf.h>
129 
130 # ifndef PT_LOAD
131 #  define PT_LOAD	Elf_pt_load
132 #  if 0						/* was in pkgsrc patches for 20.7 */
133 #   define SHT_PROGBITS Elf_sht_progbits
134 #  endif
135 #  define SHT_SYMTAB	Elf_sht_symtab
136 #  define SHT_DYNSYM	Elf_sht_dynsym
137 #  define SHT_NULL	Elf_sht_null
138 #  define SHT_NOBITS	Elf_sht_nobits
139 #  define SHT_REL	Elf_sht_rel
140 #  define SHT_RELA	Elf_sht_rela
141 
142 #  define SHN_UNDEF	Elf_eshn_undefined
143 #  define SHN_ABS	Elf_eshn_absolute
144 #  define SHN_COMMON	Elf_eshn_common
145 # endif /* !PT_LOAD */
146 
147 # ifdef __alpha__
148 #  include <sys/exec_ecoff.h>
149 #  define HDRR		struct ecoff_symhdr
150 #  define pHDRR		HDRR *
151 # endif /* __alpha__ */
152 
153 #ifdef __mips__			/* was in pkgsrc patches for 20.7 */
154 # define SHT_MIPS_DEBUG	DT_MIPS_FLAGS
155 # define HDRR		struct Elf_Shdr
156 #endif /* __mips__ */
157 #endif /* __NetBSD__ */
158 
159 #ifdef __OpenBSD__
160 # include <sys/exec_elf.h>
161 #endif
162 
163 #if __GNU_LIBRARY__ - 0 >= 6
164 # include <link.h>	/* get ElfW etc */
165 #endif
166 
167 #ifndef ElfW
168 # define ElfBitsW(bits, type) Elf##bits##_##type
169 # ifndef ELFSIZE
170 #  ifdef _LP64
171 #   define ELFSIZE 64
172 #  else
173 #   define ELFSIZE 32
174 #  endif
175 # endif
176   /* This macro expands `bits' before invoking ElfBitsW.  */
177 # define ElfExpandBitsW(bits, type) ElfBitsW (bits, type)
178 # define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
179 #endif
180 
181 /* The code often converts ElfW (Half) values like e_shentsize to ptrdiff_t;
182    check that this doesn't lose information.  */
183 #include <intprops.h>
184 #include <verify.h>
185 verify ((! TYPE_SIGNED (ElfW (Half))
186 	 || PTRDIFF_MIN <= TYPE_MINIMUM (ElfW (Half)))
187 	&& TYPE_MAXIMUM (ElfW (Half)) <= PTRDIFF_MAX);
188 
189 #ifdef UNEXELF_DEBUG
190 # define DEBUG_LOG(expr) fprintf (stderr, #expr " 0x%"PRIxMAX"\n", \
191 				  (uintmax_t) (expr))
192 #endif
193 
194 /* Get the address of a particular section or program header entry,
195  * accounting for the size of the entries.
196  */
197 
198 static void *
entry_address(void * section_h,ptrdiff_t idx,ptrdiff_t entsize)199 entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize)
200 {
201   char *h = section_h;
202   return h + idx * entsize;
203 }
204 
205 #define OLD_SECTION_H(n) \
206   (*(ElfW (Shdr) *) entry_address (old_section_h, n, old_file_h->e_shentsize))
207 #define NEW_SECTION_H(n) \
208   (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shentsize))
209 #define OLD_PROGRAM_H(n) \
210   (*(ElfW (Phdr) *) entry_address (old_program_h, n, old_file_h->e_phentsize))
211 
212 typedef unsigned char byte;
213 
214 /* ****************************************************************
215  * unexec
216  *
217  * driving logic.
218  *
219  * In ELF, this works by replacing the old bss SHT_NOBITS section with
220  * a new, larger, SHT_PROGBITS section.
221  *
222  */
223 void
unexec(const char * new_name,const char * old_name)224 unexec (const char *new_name, const char *old_name)
225 {
226   int new_file, old_file;
227   off_t new_file_size;
228 
229   /* Pointers to the base of the image of the two files.  */
230   caddr_t old_base, new_base;
231 
232 #if MAP_ANON == 0
233   int mmap_fd;
234 #else
235 # define mmap_fd -1
236 #endif
237 
238   /* Pointers to the file, program and section headers for the old and
239      new files.  */
240   ElfW (Ehdr) *old_file_h, *new_file_h;
241   ElfW (Phdr) *old_program_h, *new_program_h;
242   ElfW (Shdr) *old_section_h, *new_section_h;
243 
244   /* Point to the section name table.  */
245   char *old_section_names, *new_section_names;
246 
247   ElfW (Phdr) *old_bss_seg, *new_bss_seg;
248   ElfW (Addr) old_bss_addr, new_bss_addr;
249   ElfW (Word) old_bss_size, bss_size_growth, new_data2_size;
250   ElfW (Off) old_bss_offset, new_data2_offset;
251 
252   ptrdiff_t n;
253   ptrdiff_t old_bss_index;
254   struct stat stat_buf;
255   off_t old_file_size;
256 
257   /* Open the old file, allocate a buffer of the right size, and read
258      in the file contents.  */
259 
260   old_file = emacs_open (old_name, O_RDONLY, 0);
261 
262   if (old_file < 0)
263     fatal ("Can't open %s for reading: %s", old_name, strerror (errno));
264 
265   if (fstat (old_file, &stat_buf) != 0)
266     fatal ("Can't fstat (%s): %s", old_name, strerror (errno));
267 
268 #if MAP_ANON == 0
269   mmap_fd = emacs_open ("/dev/zero", O_RDONLY, 0);
270   if (mmap_fd < 0)
271     fatal ("Can't open /dev/zero for reading: %s", strerror (errno));
272 #endif
273 
274   /* We cannot use malloc here because that may use sbrk.  If it does,
275      we'd dump our temporary buffers with Emacs, and we'd have to be
276      extra careful to use the correct value of sbrk(0) after
277      allocating all buffers in the code below, which we aren't.  */
278   old_file_size = stat_buf.st_size;
279   if (! (0 <= old_file_size && old_file_size <= SIZE_MAX))
280     fatal ("File size out of range");
281   old_base = mmap (NULL, old_file_size, PROT_READ | PROT_WRITE,
282 		   MAP_ANON | MAP_PRIVATE, mmap_fd, 0);
283   if (old_base == MAP_FAILED)
284     fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
285 
286   if (read (old_file, old_base, old_file_size) != old_file_size)
287     fatal ("Didn't read all of %s: %s", old_name, strerror (errno));
288 
289   /* Get pointers to headers & section names */
290 
291   old_file_h = (ElfW (Ehdr) *) old_base;
292   old_program_h = (ElfW (Phdr) *) ((byte *) old_base + old_file_h->e_phoff);
293   old_section_h = (ElfW (Shdr) *) ((byte *) old_base + old_file_h->e_shoff);
294   old_section_names = (char *) old_base
295     + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
296 
297   /* Find the PT_LOAD header covering the highest address.  This
298      segment will be where bss sections are located, past p_filesz.  */
299   old_bss_seg = 0;
300   for (n = old_file_h->e_phnum; --n >= 0; )
301     {
302       ElfW (Phdr) *seg = &OLD_PROGRAM_H (n);
303       if (seg->p_type == PT_LOAD
304 	  && (old_bss_seg == 0
305 	      || seg->p_vaddr > old_bss_seg->p_vaddr))
306 	old_bss_seg = seg;
307     }
308   eassume (old_bss_seg);
309 
310   /* Note that old_bss_addr may be lower than the first bss section
311      address, since the section may need aligning.  */
312   old_bss_addr = old_bss_seg->p_vaddr + old_bss_seg->p_filesz;
313   old_bss_offset = old_bss_seg->p_offset + old_bss_seg->p_filesz;
314   old_bss_size = old_bss_seg->p_memsz - old_bss_seg->p_filesz;
315 
316   /* Find the last bss style section in the bss segment range.  */
317   old_bss_index = -1;
318   for (n = old_file_h->e_shnum; --n > 0; )
319     {
320       ElfW (Shdr) *shdr = &OLD_SECTION_H (n);
321       if (shdr->sh_type == SHT_NOBITS
322 	  && shdr->sh_addr >= old_bss_addr
323 	  && shdr->sh_addr + shdr->sh_size <= old_bss_addr + old_bss_size
324 	  && (old_bss_index == -1
325 	      || OLD_SECTION_H (old_bss_index).sh_addr < shdr->sh_addr))
326 	old_bss_index = n;
327     }
328 
329   if (old_bss_index == -1)
330     fatal ("no bss section found");
331 
332   void *no_break = (void *) (intptr_t) -1;
333   void *new_break = no_break;
334 #ifdef HAVE_SBRK
335   new_break = sbrk (0);
336 #endif
337   if (new_break == no_break)
338     new_break = (byte *) old_bss_addr + old_bss_size;
339   new_bss_addr = (ElfW (Addr)) new_break;
340   bss_size_growth = new_bss_addr - old_bss_addr;
341   new_data2_size = bss_size_growth;
342   new_data2_size += alignof (ElfW (Shdr)) - 1;
343   new_data2_size -= new_data2_size % alignof (ElfW (Shdr));
344 
345   new_data2_offset = old_bss_offset;
346 
347 #ifdef UNEXELF_DEBUG
348   fprintf (stderr, "old_bss_index %td\n", old_bss_index);
349   DEBUG_LOG (old_bss_addr);
350   DEBUG_LOG (old_bss_size);
351   DEBUG_LOG (old_bss_offset);
352   DEBUG_LOG (new_bss_addr);
353   DEBUG_LOG (new_data2_size);
354   DEBUG_LOG (new_data2_offset);
355 #endif
356 
357   if (new_bss_addr < old_bss_addr + old_bss_size)
358     fatal (".bss shrank when undumping");
359 
360   /* Set the output file to the right size.  Allocate a buffer to hold
361      the image of the new file.  Set pointers to various interesting
362      objects.  */
363 
364   new_file = emacs_open (new_name, O_RDWR | O_CREAT, 0777);
365   if (new_file < 0)
366     fatal ("Can't creat (%s): %s", new_name, strerror (errno));
367 
368   new_file_size = old_file_size + new_data2_size;
369 
370   if (ftruncate (new_file, new_file_size))
371     fatal ("Can't ftruncate (%s): %s", new_name, strerror (errno));
372 
373   new_base = mmap (NULL, new_file_size, PROT_READ | PROT_WRITE,
374 		   MAP_ANON | MAP_PRIVATE, mmap_fd, 0);
375   if (new_base == MAP_FAILED)
376     fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
377 
378   /* Make our new file, program and section headers as copies of the
379      originals.  */
380 
381   new_file_h = (ElfW (Ehdr) *) new_base;
382   memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
383 
384   /* Fix up file header.  Section header is further away now.  */
385 
386   if (new_file_h->e_shoff >= old_bss_offset)
387     new_file_h->e_shoff += new_data2_size;
388 
389   new_program_h = (ElfW (Phdr) *) ((byte *) new_base + new_file_h->e_phoff);
390   new_section_h = (ElfW (Shdr) *) ((byte *) new_base + new_file_h->e_shoff);
391 
392   memcpy (new_program_h, old_program_h,
393 	  old_file_h->e_phnum * old_file_h->e_phentsize);
394   memcpy (new_section_h, old_section_h,
395 	  old_file_h->e_shnum * old_file_h->e_shentsize);
396 
397 #ifdef UNEXELF_DEBUG
398   DEBUG_LOG (old_file_h->e_shoff);
399   fprintf (stderr, "Old section count %td\n", (ptrdiff_t) old_file_h->e_shnum);
400   DEBUG_LOG (new_file_h->e_shoff);
401   fprintf (stderr, "New section count %td\n", (ptrdiff_t) new_file_h->e_shnum);
402 #endif
403 
404   /* Fix up program header.  Extend the writable data segment so
405      that the bss area is covered too.  */
406 
407   new_bss_seg = new_program_h + (old_bss_seg - old_program_h);
408   new_bss_seg->p_filesz = new_bss_addr - new_bss_seg->p_vaddr;
409   new_bss_seg->p_memsz = new_bss_seg->p_filesz;
410 
411   /* Copy over what we have in memory now for the bss area. */
412   memcpy (new_base + new_data2_offset, (caddr_t) old_bss_addr,
413 	  bss_size_growth);
414 
415   /* Walk through all section headers, copying data and updating.  */
416   for (n = 1; n < old_file_h->e_shnum; n++)
417     {
418       caddr_t src;
419       ElfW (Shdr) *old_shdr = &OLD_SECTION_H (n);
420       ElfW (Shdr) *new_shdr = &NEW_SECTION_H (n);
421 
422       if (new_shdr->sh_type == SHT_NOBITS
423 	  && new_shdr->sh_addr >= old_bss_addr
424 	  && (new_shdr->sh_addr + new_shdr->sh_size
425 	      <= old_bss_addr + old_bss_size))
426 	{
427 	  /* This section now has file backing.  */
428 	  new_shdr->sh_type = SHT_PROGBITS;
429 
430 	  /* SHT_NOBITS sections do not need a valid sh_offset, so it
431 	     might be incorrect.  Write the correct value.  */
432 	  new_shdr->sh_offset = (new_shdr->sh_addr - new_bss_seg->p_vaddr
433 				 + new_bss_seg->p_offset);
434 
435 	  /* If this is was a SHT_NOBITS .plt section, then it is
436 	     probably a PowerPC PLT.  If it is PowerPC64 ELFv1 then
437 	     glibc ld.so doesn't initialize the toc pointer word.  A
438 	     non-zero toc pointer word can defeat Power7 thread safety
439 	     during lazy update of a PLT entry.  This only matters if
440 	     emacs becomes multi-threaded.  */
441 	  if (strcmp (old_section_names + new_shdr->sh_name, ".plt") == 0)
442 	    memset (new_shdr->sh_offset + new_base, 0, new_shdr->sh_size);
443 
444 	  /* Extend the size of the last bss section to cover dumped
445 	     data.  */
446 	  if (n == old_bss_index)
447 	    new_shdr->sh_size = new_bss_addr - new_shdr->sh_addr;
448 
449 	  /* We have already copied this section from the current
450 	     process.  */
451 	  continue;
452 	}
453 
454       /* Any section that was originally placed after the .bss
455 	 section should now be offset by NEW_DATA2_SIZE.  */
456       if (new_shdr->sh_offset >= old_bss_offset)
457 	new_shdr->sh_offset += new_data2_size;
458 
459       /* Now, start to copy the content of sections.  */
460       if (new_shdr->sh_type == SHT_NULL
461 	  || new_shdr->sh_type == SHT_NOBITS)
462 	continue;
463 
464       /* Some sections are copied from the current process instead of
465 	 the old file.  */
466       if (!strcmp (old_section_names + new_shdr->sh_name, ".data")
467 	  || !strcmp (old_section_names + new_shdr->sh_name, ".sdata")
468 	  || !strcmp (old_section_names + new_shdr->sh_name, ".lit4")
469 	  || !strcmp (old_section_names + new_shdr->sh_name, ".lit8")
470 	  || !strcmp (old_section_names + new_shdr->sh_name, ".sdata1")
471 	  || !strcmp (old_section_names + new_shdr->sh_name, ".data1"))
472 	src = (caddr_t) old_shdr->sh_addr;
473       else
474 	src = old_base + old_shdr->sh_offset;
475 
476       memcpy (new_shdr->sh_offset + new_base, src, new_shdr->sh_size);
477 
478 #if (defined __alpha__ && !defined __OpenBSD__) || defined _SYSTYPE_SYSV
479       /* Update Alpha and MIPS COFF debug symbol table.  */
480       if (strcmp (old_section_names + new_shdr->sh_name, ".mdebug") == 0
481 	  && new_shdr->sh_offset - old_shdr->sh_offset != 0
482 #if defined _SYSTYPE_SYSV
483 	  && new_shdr->sh_type == SHT_MIPS_DEBUG
484 #endif
485 	  )
486 	{
487 	  ptrdiff_t diff = new_shdr->sh_offset - old_shdr->sh_offset;
488 	  HDRR *phdr = (HDRR *) (new_shdr->sh_offset + new_base);
489 
490 	  phdr->cbLineOffset += diff;
491 	  phdr->cbDnOffset += diff;
492 	  phdr->cbPdOffset += diff;
493 	  phdr->cbSymOffset += diff;
494 	  phdr->cbOptOffset += diff;
495 	  phdr->cbAuxOffset += diff;
496 	  phdr->cbSsOffset += diff;
497 	  phdr->cbSsExtOffset += diff;
498 	  phdr->cbFdOffset += diff;
499 	  phdr->cbRfdOffset += diff;
500 	  phdr->cbExtOffset += diff;
501 	}
502 #endif /* __alpha__ || _SYSTYPE_SYSV */
503     }
504 
505   /* Update the symbol values of _edata and _end.  */
506   for (n = new_file_h->e_shnum; 0 < --n; )
507     {
508       byte *symnames;
509       ElfW (Sym) *symp, *symendp;
510       ElfW (Shdr) *sym_shdr = &NEW_SECTION_H (n);
511 
512       if (sym_shdr->sh_type != SHT_DYNSYM
513 	  && sym_shdr->sh_type != SHT_SYMTAB)
514 	continue;
515 
516       symnames = ((byte *) new_base
517 		  + NEW_SECTION_H (sym_shdr->sh_link).sh_offset);
518       symp = (ElfW (Sym) *) (sym_shdr->sh_offset + new_base);
519       symendp = (ElfW (Sym) *) ((byte *) symp + sym_shdr->sh_size);
520 
521       for (; symp < symendp; symp ++)
522 	{
523 	  if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0
524 	      || strcmp ((char *) (symnames + symp->st_name), "end") == 0
525 	      || strcmp ((char *) (symnames + symp->st_name), "_edata") == 0
526 	      || strcmp ((char *) (symnames + symp->st_name), "edata") == 0)
527 	    memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr));
528 
529 	  /* Strictly speaking, #ifdef below is not necessary.  But we
530 	     keep it to indicate that this kind of change may also be
531 	     necessary for other unexecs to support GNUstep.  */
532 #ifdef NS_IMPL_GNUSTEP
533 	  /* ObjC runtime modifies the values of some data structures
534 	     such as classes and selectors in the .data section after
535 	     loading.  As the dump process copies the .data section
536 	     from the current process, that causes problems when the
537 	     modified classes are reinitialized in the dumped
538 	     executable.  We copy such data from the old file, not
539 	     from the current process.  */
540 	  if (strncmp ((char *) (symnames + symp->st_name),
541 		       "_OBJC_", sizeof ("_OBJC_") - 1) == 0)
542 	    {
543 	      ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx);
544 	      if (new_shdr->sh_type != SHT_NOBITS)
545 		{
546 		  ElfW (Shdr) *old_shdr = &OLD_SECTION_H (symp->st_shndx);
547 		  ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr;
548 		  ptrdiff_t newoff = reladdr + new_shdr->sh_offset;
549 
550 		  if (old_shdr->sh_type == SHT_NOBITS)
551 		    memset (new_base + newoff, 0, symp->st_size);
552 		  else
553 		    {
554 		      ptrdiff_t oldoff = reladdr + old_shdr->sh_offset;
555 		      memcpy (new_base + newoff, old_base + oldoff,
556 			      symp->st_size);
557 		    }
558 		}
559 	    }
560 #endif
561 	}
562     }
563 
564   /* Modify the names of sections we changed from SHT_NOBITS to
565      SHT_PROGBITS.  This is really just cosmetic, but some tools that
566      (wrongly) operate on section names rather than types might be
567      confused by a SHT_PROGBITS .bss section.  */
568   new_section_names = ((char *) new_base
569 		       + NEW_SECTION_H (new_file_h->e_shstrndx).sh_offset);
570   for (n = new_file_h->e_shnum; 0 < --n; )
571     {
572       ElfW (Shdr) *old_shdr = &OLD_SECTION_H (n);
573       ElfW (Shdr) *new_shdr = &NEW_SECTION_H (n);
574 
575       /* Replace the leading '.' with ','.  When .shstrtab is string
576 	 merged this will rename both .bss and .rela.bss to ,bss and
577 	 .rela,bss.  */
578       if (old_shdr->sh_type == SHT_NOBITS
579 	  && new_shdr->sh_type == SHT_PROGBITS)
580 	*(new_section_names + new_shdr->sh_name) = ',';
581     }
582 
583   /* This loop seeks out relocation sections for the data section, so
584      that it can undo relocations performed by the runtime loader.
585 
586      The following approach does not work on x86 platforms that use
587      the GNU Gold linker, which can generate .rel.dyn relocation
588      sections containing R_386_32 entries that the following code does
589      not grok.  Emacs works around this problem by avoiding C
590      constructs that generate such entries, which is horrible hack.
591 
592      FIXME: Presumably more problems like this will crop up as linkers
593      get fancier.  We really need to stop assuming that Emacs can grok
594      arbitrary linker output.  See Bug#27248.  */
595   for (n = new_file_h->e_shnum; 0 < --n; )
596     {
597       ElfW (Shdr) *rel_shdr = &NEW_SECTION_H (n);
598       ElfW (Shdr) *shdr;
599 
600       switch (rel_shdr->sh_type)
601 	{
602 	default:
603 	  break;
604 	case SHT_REL:
605 	case SHT_RELA:
606 	  /* This code handles two different size structs, but there should
607 	     be no harm in that provided that r_offset is always the first
608 	     member.  */
609 	  shdr = &NEW_SECTION_H (rel_shdr->sh_info);
610 	  if (!strcmp (old_section_names + shdr->sh_name, ".data")
611 	      || !strcmp (old_section_names + shdr->sh_name, ".sdata")
612 	      || !strcmp (old_section_names + shdr->sh_name, ".lit4")
613 	      || !strcmp (old_section_names + shdr->sh_name, ".lit8")
614 	      || !strcmp (old_section_names + shdr->sh_name, ".sdata1")
615 	      || !strcmp (old_section_names + shdr->sh_name, ".data1"))
616 	    {
617 	      ElfW (Addr) offset = shdr->sh_addr - shdr->sh_offset;
618 	      caddr_t reloc = old_base + rel_shdr->sh_offset, end;
619 	      for (end = reloc + rel_shdr->sh_size;
620 		   reloc < end;
621 		   reloc += rel_shdr->sh_entsize)
622 		{
623 		  ElfW (Addr) addr = ((ElfW (Rel) *) reloc)->r_offset - offset;
624 		  /* Ignore R_*_NONE relocs.  */
625 		  if (((ElfW (Rel) *) reloc)->r_offset == 0)
626 		    continue;
627 		  /* Assume reloc applies to a word.
628 		     ??? This is not always true, eg. TLS module/index
629 		     pair in .got which occupies two words.  */
630 		  memcpy (new_base + addr, old_base + addr,
631 			  sizeof (ElfW (Addr)));
632 		}
633 	    }
634 	  break;
635 	}
636     }
637 
638   /* Write out new_file, and free the buffers.  */
639 
640   if (write (new_file, new_base, new_file_size) != new_file_size)
641     fatal ("Didn't write %lu bytes to %s: %s",
642 	   (unsigned long) new_file_size, new_name, strerror (errno));
643   munmap (old_base, old_file_size);
644   munmap (new_base, new_file_size);
645 
646   /* Close the files and make the new file executable.  */
647 
648 #if MAP_ANON == 0
649   emacs_close (mmap_fd);
650 #endif
651 
652   if (emacs_close (old_file) != 0)
653     fatal ("Can't close (%s): %s", old_name, strerror (errno));
654 
655   if (emacs_close (new_file) != 0)
656     fatal ("Can't close (%s): %s", new_name, strerror (errno));
657 }
658