1 /* Copyright (C) 1985-1988, 1990, 1992, 1999-2016 Free Software
4 This file is part of GNU Emacs.
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.
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.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
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! */
26 * unexec.c - Convert a running program into an a.out file.
28 * Author: Spencer W. Thomas
29 * Computer Science Dept.
31 * Date: Tue Mar 2 1982
32 * Modified heavily since then.
35 * unexec (const char *new_name, const char *old_name);
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.
44 /* We do not use mmap because that fails with NFS.
45 Instead we read the whole file, modify it, and write it out. */
58 #include <sys/types.h>
61 #if !defined (__NetBSD__) && !defined (__OpenBSD__)
63 #endif /* not __NetBSD__ and not __OpenBSD__ */
65 #if defined (_SYSTYPE_SYSV)
66 #include <sys/elf_mips.h>
68 #endif /* _SYSTYPE_SYSV */
70 #include <syms.h> /* for HDRR declaration */
75 #define MAP_ANON MAP_ANONYMOUS
82 #define MAP_FAILED ((void *) -1)
85 #if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
86 /* Declare COFF debugging symbol table. This used to be in
87 /usr/include/sym.h, but this file is no longer included in Red Hat
88 5.0 and presumably in any other glibc 2.x based distribution. */
116 #define cbHDRR sizeof (HDRR)
117 #define hdrNil ((pHDRR)0)
122 * NetBSD does not have normal-looking user-land ELF support.
124 # if defined __alpha__ || defined __sparc_v9__ || defined _LP64
129 # include <sys/exec_elf.h>
132 # define PT_LOAD Elf_pt_load
133 # if 0 /* was in pkgsrc patches for 20.7 */
134 # define SHT_PROGBITS Elf_sht_progbits
136 # define SHT_SYMTAB Elf_sht_symtab
137 # define SHT_DYNSYM Elf_sht_dynsym
138 # define SHT_NULL Elf_sht_null
139 # define SHT_NOBITS Elf_sht_nobits
140 # define SHT_REL Elf_sht_rel
141 # define SHT_RELA Elf_sht_rela
143 # define SHN_UNDEF Elf_eshn_undefined
144 # define SHN_ABS Elf_eshn_absolute
145 # define SHN_COMMON Elf_eshn_common
146 # endif /* !PT_LOAD */
149 # include <sys/exec_ecoff.h>
150 # define HDRR struct ecoff_symhdr
151 # define pHDRR HDRR *
152 # endif /* __alpha__ */
154 #ifdef __mips__ /* was in pkgsrc patches for 20.7 */
155 # define SHT_MIPS_DEBUG DT_MIPS_FLAGS
156 # define HDRR struct Elf_Shdr
157 #endif /* __mips__ */
158 #endif /* __NetBSD__ */
161 # include <sys/exec_elf.h>
164 #if __GNU_LIBRARY__ - 0 >= 6
165 # include <link.h> /* get ElfW etc */
169 # define ElfBitsW(bits, type) Elf##bits##_##type
177 /* This macro expands `bits' before invoking ElfBitsW. */
178 # define ElfExpandBitsW(bits, type) ElfBitsW (bits, type)
179 # define ElfW(type) ElfExpandBitsW (ELFSIZE, type)
182 /* The code often converts ElfW (Half) values like e_shentsize to ptrdiff_t;
183 check that this doesn't lose information. */
184 #include <intprops.h>
186 verify ((! TYPE_SIGNED (ElfW (Half
))
187 || PTRDIFF_MIN
<= TYPE_MINIMUM (ElfW (Half
)))
188 && TYPE_MAXIMUM (ElfW (Half
)) <= PTRDIFF_MAX
);
191 # define DEBUG_LOG(expr) fprintf (stderr, #expr " 0x%jx\n", (uintmax_t) (expr))
194 /* Get the address of a particular section or program header entry,
195 * accounting for the size of the entries.
199 entry_address (void *section_h
, ptrdiff_t idx
, ptrdiff_t entsize
)
202 return h
+ idx
* entsize
;
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))
212 typedef unsigned char byte
;
214 /* ****************************************************************
219 * In ELF, this works by replacing the old bss SHT_NOBITS section with
220 * a new, larger, SHT_PROGBITS section.
224 unexec (const char *new_name
, const char *old_name
)
226 int new_file
, old_file
;
230 /* Pointers to the base of the image of the two files. */
231 caddr_t old_base
, new_base
;
239 /* Pointers to the file, program and section headers for the old and
241 ElfW (Ehdr
) *old_file_h
, *new_file_h
;
242 ElfW (Phdr
) *old_program_h
, *new_program_h
;
243 ElfW (Shdr
) *old_section_h
, *new_section_h
;
245 /* Point to the section name table. */
246 char *old_section_names
, *new_section_names
;
248 ElfW (Phdr
) *old_bss_seg
, *new_bss_seg
;
249 ElfW (Addr
) old_bss_addr
, new_bss_addr
;
250 ElfW (Word
) old_bss_size
, bss_size_growth
, new_data2_size
;
251 ElfW (Off
) old_bss_offset
, new_data2_offset
;
254 ptrdiff_t old_bss_index
;
255 struct stat stat_buf
;
258 /* Open the old file, allocate a buffer of the right size, and read
259 in the file contents. */
261 old_file
= emacs_open (old_name
, O_RDONLY
, 0);
264 fatal ("Can't open %s for reading: %s", old_name
, strerror (errno
));
266 if (fstat (old_file
, &stat_buf
) != 0)
267 fatal ("Can't fstat (%s): %s", old_name
, strerror (errno
));
270 mmap_fd
= emacs_open ("/dev/zero", O_RDONLY
, 0);
272 fatal ("Can't open /dev/zero for reading: %s", strerror (errno
));
275 /* We cannot use malloc here because that may use sbrk. If it does,
276 we'd dump our temporary buffers with Emacs, and we'd have to be
277 extra careful to use the correct value of sbrk(0) after
278 allocating all buffers in the code below, which we aren't. */
279 old_file_size
= stat_buf
.st_size
;
280 if (! (0 <= old_file_size
&& old_file_size
<= SIZE_MAX
))
281 fatal ("File size out of range");
282 old_base
= mmap (NULL
, old_file_size
, PROT_READ
| PROT_WRITE
,
283 MAP_ANON
| MAP_PRIVATE
, mmap_fd
, 0);
284 if (old_base
== MAP_FAILED
)
285 fatal ("Can't allocate buffer for %s: %s", old_name
, strerror (errno
));
287 if (read (old_file
, old_base
, old_file_size
) != old_file_size
)
288 fatal ("Didn't read all of %s: %s", old_name
, strerror (errno
));
290 /* Get pointers to headers & section names */
292 old_file_h
= (ElfW (Ehdr
) *) old_base
;
293 old_program_h
= (ElfW (Phdr
) *) ((byte
*) old_base
+ old_file_h
->e_phoff
);
294 old_section_h
= (ElfW (Shdr
) *) ((byte
*) old_base
+ old_file_h
->e_shoff
);
295 old_section_names
= (char *) old_base
296 + OLD_SECTION_H (old_file_h
->e_shstrndx
).sh_offset
;
298 /* Find the PT_LOAD header covering the highest address. This
299 segment will be where bss sections are located, past p_filesz. */
301 for (n
= old_file_h
->e_phnum
; --n
>= 0; )
303 ElfW (Phdr
) *seg
= &OLD_PROGRAM_H (n
);
304 if (seg
->p_type
== PT_LOAD
306 || seg
->p_vaddr
> old_bss_seg
->p_vaddr
))
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
;
316 /* Find the last bss style section in the bss segment range. */
318 for (n
= old_file_h
->e_shnum
; --n
> 0; )
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
))
329 if (old_bss_index
== -1)
330 fatal ("no bss section found");
332 new_break
= sbrk (0);
333 new_bss_addr
= (ElfW (Addr
)) new_break
;
334 bss_size_growth
= new_bss_addr
- old_bss_addr
;
335 new_data2_size
= bss_size_growth
;
336 new_data2_size
+= alignof (ElfW (Shdr
)) - 1;
337 new_data2_size
-= new_data2_size
% alignof (ElfW (Shdr
));
339 new_data2_offset
= old_bss_offset
;
342 fprintf (stderr
, "old_bss_index %td\n", old_bss_index
);
343 DEBUG_LOG (old_bss_addr
);
344 DEBUG_LOG (old_bss_size
);
345 DEBUG_LOG (old_bss_offset
);
346 DEBUG_LOG (new_bss_addr
);
347 DEBUG_LOG (new_data2_size
);
348 DEBUG_LOG (new_data2_offset
);
351 if (new_bss_addr
< old_bss_addr
+ old_bss_size
)
352 fatal (".bss shrank when undumping");
354 /* Set the output file to the right size. Allocate a buffer to hold
355 the image of the new file. Set pointers to various interesting
358 new_file
= emacs_open (new_name
, O_RDWR
| O_CREAT
, 0777);
360 fatal ("Can't creat (%s): %s", new_name
, strerror (errno
));
362 new_file_size
= old_file_size
+ new_data2_size
;
364 if (ftruncate (new_file
, new_file_size
))
365 fatal ("Can't ftruncate (%s): %s", new_name
, strerror (errno
));
367 new_base
= mmap (NULL
, new_file_size
, PROT_READ
| PROT_WRITE
,
368 MAP_ANON
| MAP_PRIVATE
, mmap_fd
, 0);
369 if (new_base
== MAP_FAILED
)
370 fatal ("Can't allocate buffer for %s: %s", old_name
, strerror (errno
));
372 /* Make our new file, program and section headers as copies of the
375 new_file_h
= (ElfW (Ehdr
) *) new_base
;
376 memcpy (new_file_h
, old_file_h
, old_file_h
->e_ehsize
);
378 /* Fix up file header. Section header is further away now. */
380 if (new_file_h
->e_shoff
>= old_bss_offset
)
381 new_file_h
->e_shoff
+= new_data2_size
;
383 new_program_h
= (ElfW (Phdr
) *) ((byte
*) new_base
+ new_file_h
->e_phoff
);
384 new_section_h
= (ElfW (Shdr
) *) ((byte
*) new_base
+ new_file_h
->e_shoff
);
386 memcpy (new_program_h
, old_program_h
,
387 old_file_h
->e_phnum
* old_file_h
->e_phentsize
);
388 memcpy (new_section_h
, old_section_h
,
389 old_file_h
->e_shnum
* old_file_h
->e_shentsize
);
392 DEBUG_LOG (old_file_h
->e_shoff
);
393 fprintf (stderr
, "Old section count %td\n", (ptrdiff_t) old_file_h
->e_shnum
);
394 DEBUG_LOG (new_file_h
->e_shoff
);
395 fprintf (stderr
, "New section count %td\n", (ptrdiff_t) new_file_h
->e_shnum
);
398 /* Fix up program header. Extend the writable data segment so
399 that the bss area is covered too. */
401 new_bss_seg
= new_program_h
+ (old_bss_seg
- old_program_h
);
402 new_bss_seg
->p_filesz
= new_bss_addr
- new_bss_seg
->p_vaddr
;
403 new_bss_seg
->p_memsz
= new_bss_seg
->p_filesz
;
405 /* Copy over what we have in memory now for the bss area. */
406 memcpy (new_base
+ new_data2_offset
, (caddr_t
) old_bss_addr
,
409 /* Walk through all section headers, copying data and updating. */
410 for (n
= 1; n
< old_file_h
->e_shnum
; n
++)
413 ElfW (Shdr
) *old_shdr
= &OLD_SECTION_H (n
);
414 ElfW (Shdr
) *new_shdr
= &NEW_SECTION_H (n
);
416 if (new_shdr
->sh_type
== SHT_NOBITS
417 && new_shdr
->sh_addr
>= old_bss_addr
418 && (new_shdr
->sh_addr
+ new_shdr
->sh_size
419 <= old_bss_addr
+ old_bss_size
))
421 /* This section now has file backing. */
422 new_shdr
->sh_type
= SHT_PROGBITS
;
424 /* SHT_NOBITS sections do not need a valid sh_offset, so it
425 might be incorrect. Write the correct value. */
426 new_shdr
->sh_offset
= (new_shdr
->sh_addr
- new_bss_seg
->p_vaddr
427 + new_bss_seg
->p_offset
);
429 /* If this is was a SHT_NOBITS .plt section, then it is
430 probably a PowerPC PLT. If it is PowerPC64 ELFv1 then
431 glibc ld.so doesn't initialize the toc pointer word. A
432 non-zero toc pointer word can defeat Power7 thread safety
433 during lazy update of a PLT entry. This only matters if
434 emacs becomes multi-threaded. */
435 if (strcmp (old_section_names
+ new_shdr
->sh_name
, ".plt") == 0)
436 memset (new_shdr
->sh_offset
+ new_base
, 0, new_shdr
->sh_size
);
438 /* Extend the size of the last bss section to cover dumped
440 if (n
== old_bss_index
)
441 new_shdr
->sh_size
= new_bss_addr
- new_shdr
->sh_addr
;
443 /* We have already copied this section from the current
448 /* Any section that was originally placed after the .bss
449 section should now be offset by NEW_DATA2_SIZE. */
450 if (new_shdr
->sh_offset
>= old_bss_offset
)
451 new_shdr
->sh_offset
+= new_data2_size
;
453 /* Now, start to copy the content of sections. */
454 if (new_shdr
->sh_type
== SHT_NULL
455 || new_shdr
->sh_type
== SHT_NOBITS
)
458 /* Some sections are copied from the current process instead of
460 if (!strcmp (old_section_names
+ new_shdr
->sh_name
, ".data")
461 || !strcmp (old_section_names
+ new_shdr
->sh_name
, ".sdata")
462 || !strcmp (old_section_names
+ new_shdr
->sh_name
, ".lit4")
463 || !strcmp (old_section_names
+ new_shdr
->sh_name
, ".lit8")
464 || !strcmp (old_section_names
+ new_shdr
->sh_name
, ".sdata1")
465 || !strcmp (old_section_names
+ new_shdr
->sh_name
, ".data1"))
466 src
= (caddr_t
) old_shdr
->sh_addr
;
468 src
= old_base
+ old_shdr
->sh_offset
;
470 memcpy (new_shdr
->sh_offset
+ new_base
, src
, new_shdr
->sh_size
);
472 #if (defined __alpha__ && !defined __OpenBSD__) || defined _SYSTYPE_SYSV
473 /* Update Alpha and MIPS COFF debug symbol table. */
474 if (strcmp (old_section_names
+ new_shdr
->sh_name
, ".mdebug") == 0
475 && new_shdr
->sh_offset
- old_shdr
->sh_offset
!= 0
476 #if defined _SYSTYPE_SYSV
477 && new_shdr
->sh_type
== SHT_MIPS_DEBUG
481 ptrdiff_t diff
= new_shdr
->sh_offset
- old_shdr
->sh_offset
;
482 HDRR
*phdr
= (HDRR
*) (new_shdr
->sh_offset
+ new_base
);
484 phdr
->cbLineOffset
+= diff
;
485 phdr
->cbDnOffset
+= diff
;
486 phdr
->cbPdOffset
+= diff
;
487 phdr
->cbSymOffset
+= diff
;
488 phdr
->cbOptOffset
+= diff
;
489 phdr
->cbAuxOffset
+= diff
;
490 phdr
->cbSsOffset
+= diff
;
491 phdr
->cbSsExtOffset
+= diff
;
492 phdr
->cbFdOffset
+= diff
;
493 phdr
->cbRfdOffset
+= diff
;
494 phdr
->cbExtOffset
+= diff
;
496 #endif /* __alpha__ || _SYSTYPE_SYSV */
499 /* Adjust the HDRR offsets in .mdebug and copy the
500 line data if it's in its usual 'hole' in the object.
501 Makes the new file debuggable with dbx.
502 patches up two problems: the absolute file offsets
503 in the HDRR record of .mdebug (see /usr/include/syms.h), and
504 the ld bug that gets the line table in a hole in the
505 elf file rather than in the .mdebug section proper.
506 David Anderson. davea@sgi.com Jan 16,1994. */
507 if (strcmp (old_section_names
+ new_shdr
->sh_name
, ".mdebug") == 0
508 && new_shdr
->sh_offset
- old_shdr
->sh_offset
!= 0)
510 #define MDEBUGADJUST(__ct,__fileaddr) \
511 if (n_phdrr->__ct > 0) \
513 n_phdrr->__fileaddr += movement; \
516 HDRR
*o_phdrr
= (HDRR
*) ((byte
*) old_base
+ old_shdr
->sh_offset
);
517 HDRR
*n_phdrr
= (HDRR
*) ((byte
*) new_base
+ new_shdr
->sh_offset
);
518 ptrdiff_t movement
= new_shdr
->sh_offset
- old_shdr
->sh_offset
;
520 MDEBUGADJUST (idnMax
, cbDnOffset
);
521 MDEBUGADJUST (ipdMax
, cbPdOffset
);
522 MDEBUGADJUST (isymMax
, cbSymOffset
);
523 MDEBUGADJUST (ioptMax
, cbOptOffset
);
524 MDEBUGADJUST (iauxMax
, cbAuxOffset
);
525 MDEBUGADJUST (issMax
, cbSsOffset
);
526 MDEBUGADJUST (issExtMax
, cbSsExtOffset
);
527 MDEBUGADJUST (ifdMax
, cbFdOffset
);
528 MDEBUGADJUST (crfd
, cbRfdOffset
);
529 MDEBUGADJUST (iextMax
, cbExtOffset
);
530 /* The Line Section, being possible off in a hole of the object,
531 requires special handling. */
532 if (n_phdrr
->cbLine
> 0)
534 n_phdrr
->cbLineOffset
+= movement
;
536 if (o_phdrr
->cbLineOffset
> (old_shdr
->sh_offset
537 + old_shdr
->sh_size
))
538 /* If not covered by section, it hasn't yet been copied. */
539 memcpy (n_phdrr
->cbLineOffset
+ new_base
,
540 o_phdrr
->cbLineOffset
+ old_base
, n_phdrr
->cbLine
);
546 /* Update the symbol values of _edata and _end. */
547 for (n
= new_file_h
->e_shnum
; 0 < --n
; )
550 ElfW (Sym
) *symp
, *symendp
;
551 ElfW (Shdr
) *sym_shdr
= &NEW_SECTION_H (n
);
553 if (sym_shdr
->sh_type
!= SHT_DYNSYM
554 && sym_shdr
->sh_type
!= SHT_SYMTAB
)
557 symnames
= ((byte
*) new_base
558 + NEW_SECTION_H (sym_shdr
->sh_link
).sh_offset
);
559 symp
= (ElfW (Sym
) *) (sym_shdr
->sh_offset
+ new_base
);
560 symendp
= (ElfW (Sym
) *) ((byte
*) symp
+ sym_shdr
->sh_size
);
562 for (; symp
< symendp
; symp
++)
564 if (strcmp ((char *) (symnames
+ symp
->st_name
), "_end") == 0
565 || strcmp ((char *) (symnames
+ symp
->st_name
), "end") == 0
566 || strcmp ((char *) (symnames
+ symp
->st_name
), "_edata") == 0
567 || strcmp ((char *) (symnames
+ symp
->st_name
), "edata") == 0)
568 memcpy (&symp
->st_value
, &new_bss_addr
, sizeof (new_bss_addr
));
570 /* Strictly speaking, #ifdef below is not necessary. But we
571 keep it to indicate that this kind of change may also be
572 necessary for other unexecs to support GNUstep. */
573 #ifdef NS_IMPL_GNUSTEP
574 /* ObjC runtime modifies the values of some data structures
575 such as classes and selectors in the .data section after
576 loading. As the dump process copies the .data section
577 from the current process, that causes problems when the
578 modified classes are reinitialized in the dumped
579 executable. We copy such data from the old file, not
580 from the current process. */
581 if (strncmp ((char *) (symnames
+ symp
->st_name
),
582 "_OBJC_", sizeof ("_OBJC_") - 1) == 0)
584 ElfW (Shdr
) *new_shdr
= &NEW_SECTION_H (symp
->st_shndx
);
585 if (new_shdr
->sh_type
!= SHT_NOBITS
)
587 ElfW (Shdr
) *old_shdr
= &OLD_SECTION_H (symp
->st_shndx
);
588 ptrdiff_t reladdr
= symp
->st_value
- new_shdr
->sh_addr
;
589 ptrdiff_t newoff
= reladdr
+ new_shdr
->sh_offset
;
591 if (old_shdr
->sh_type
== SHT_NOBITS
)
592 memset (new_base
+ newoff
, 0, symp
->st_size
);
595 ptrdiff_t oldoff
= reladdr
+ old_shdr
->sh_offset
;
596 memcpy (new_base
+ newoff
, old_base
+ oldoff
,
605 /* Modify the names of sections we changed from SHT_NOBITS to
606 SHT_PROGBITS. This is really just cosmetic, but some tools that
607 (wrongly) operate on section names rather than types might be
608 confused by a SHT_PROGBITS .bss section. */
609 new_section_names
= ((char *) new_base
610 + NEW_SECTION_H (new_file_h
->e_shstrndx
).sh_offset
);
611 for (n
= new_file_h
->e_shnum
; 0 < --n
; )
613 ElfW (Shdr
) *old_shdr
= &OLD_SECTION_H (n
);
614 ElfW (Shdr
) *new_shdr
= &NEW_SECTION_H (n
);
616 /* Replace the leading '.' with ','. When .shstrtab is string
617 merged this will rename both .bss and .rela.bss to ,bss and
619 if (old_shdr
->sh_type
== SHT_NOBITS
620 && new_shdr
->sh_type
== SHT_PROGBITS
)
621 *(new_section_names
+ new_shdr
->sh_name
) = ',';
624 /* This loop seeks out relocation sections for the data section, so
625 that it can undo relocations performed by the runtime loader. */
626 for (n
= new_file_h
->e_shnum
; 0 < --n
; )
628 ElfW (Shdr
) *rel_shdr
= &NEW_SECTION_H (n
);
631 switch (rel_shdr
->sh_type
)
637 /* This code handles two different size structs, but there should
638 be no harm in that provided that r_offset is always the first
640 shdr
= &NEW_SECTION_H (rel_shdr
->sh_info
);
641 if (!strcmp (old_section_names
+ shdr
->sh_name
, ".data")
642 || !strcmp (old_section_names
+ shdr
->sh_name
, ".sdata")
643 || !strcmp (old_section_names
+ shdr
->sh_name
, ".lit4")
644 || !strcmp (old_section_names
+ shdr
->sh_name
, ".lit8")
645 || !strcmp (old_section_names
+ shdr
->sh_name
, ".sdata1")
646 || !strcmp (old_section_names
+ shdr
->sh_name
, ".data1"))
648 ElfW (Addr
) offset
= shdr
->sh_addr
- shdr
->sh_offset
;
649 caddr_t reloc
= old_base
+ rel_shdr
->sh_offset
, end
;
650 for (end
= reloc
+ rel_shdr
->sh_size
;
652 reloc
+= rel_shdr
->sh_entsize
)
654 ElfW (Addr
) addr
= ((ElfW (Rel
) *) reloc
)->r_offset
- offset
;
655 /* Ignore R_*_NONE relocs. */
656 if (((ElfW (Rel
) *) reloc
)->r_offset
== 0)
658 /* Assume reloc applies to a word.
659 ??? This is not always true, eg. TLS module/index
660 pair in .got which occupies two words. */
661 memcpy (new_base
+ addr
, old_base
+ addr
,
662 sizeof (ElfW (Addr
)));
669 /* Write out new_file, and free the buffers. */
671 if (write (new_file
, new_base
, new_file_size
) != new_file_size
)
672 fatal ("Didn't write %lu bytes to %s: %s",
673 (unsigned long) new_file_size
, new_name
, strerror (errno
));
674 munmap (old_base
, old_file_size
);
675 munmap (new_base
, new_file_size
);
677 /* Close the files and make the new file executable. */
680 emacs_close (mmap_fd
);
683 if (emacs_close (old_file
) != 0)
684 fatal ("Can't close (%s): %s", old_name
, strerror (errno
));
686 if (emacs_close (new_file
) != 0)
687 fatal ("Can't close (%s): %s", new_name
, strerror (errno
));