/* Copyright (C) 1985, 1986, 1987, 1988, 1990, 1992
Free Software Foundation, Inc.
- This program 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.
+This file is part of GNU Emacs.
- This program 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.
+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.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+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, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
*/
\f
+#include <config.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
return x - rem + y;
}
+/* Return the index of the section named NAME.
+ SECTION_NAMES, FILE_NAME and FILE_H give information
+ about the file we are looking in.
+
+ If we don't find the section NAME, that is a fatal error
+ if NOERROR is 0; we return -1 if NOERROR is nonzero. */
+
+static int
+find_section (name, section_names, file_name, old_file_h, old_section_h, noerror)
+ char *name;
+ char *section_names;
+ char *file_name;
+ Elf32_Ehdr *old_file_h;
+ Elf32_Shdr *old_section_h;
+ int noerror;
+{
+ int idx;
+
+ for (idx = 1; idx < old_file_h->e_shnum; idx++)
+ {
+#ifdef DEBUG
+ fprintf (stderr, "Looking for %s - found %s\n", name,
+ section_names + OLD_SECTION_H (idx).sh_name);
+#endif
+ if (!strcmp (section_names + OLD_SECTION_H (idx).sh_name,
+ name))
+ break;
+ }
+ if (idx == old_file_h->e_shnum)
+ {
+ if (noerror)
+ return -1;
+ else
+ fatal ("Can't find .bss in %s.\n", file_name, 0);
+ }
+
+ return idx;
+}
+
/* ****************************************************************
* unexec
*
= (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset;
/* Find the mdebug section, if any. */
- for (old_mdebug_index = 1; old_mdebug_index < old_file_h->e_shnum; old_mdebug_index++)
- {
-#ifdef DEBUG
- fprintf (stderr, "Looking for .mdebug - found %s\n",
- old_section_names + OLD_SECTION_H(old_mdebug_index).sh_name);
-#endif
- if (!strcmp (old_section_names + OLD_SECTION_H(old_mdebug_index).sh_name,
- ".mdebug"))
- break;
- }
- if (old_mdebug_index == old_file_h->e_shnum)
- old_mdebug_index = -1; /* just means no such section was present */
+
+ old_mdebug_index = find_section (".mdebug", old_section_names,
+ old_name, old_file_h, old_section_h, 1);
/* Find the old .bss section. */
- for (old_bss_index = 1; old_bss_index < old_file_h->e_shnum; old_bss_index++)
- {
-#ifdef DEBUG
- fprintf (stderr, "Looking for .bss - found %s\n",
- old_section_names + OLD_SECTION_H(old_bss_index).sh_name);
-#endif
- if (!strcmp (old_section_names + OLD_SECTION_H(old_bss_index).sh_name,
- ".bss"))
- break;
- }
- if (old_bss_index == old_file_h->e_shnum)
- fatal ("Can't find .bss in %s.\n", old_name, 0);
+ old_bss_index = find_section (".bss", old_section_names,
+ old_name, old_file_h, old_section_h, 0);
/* Find the old .data section. Figure out parameters of
the new data2 and bss sections. */
- for (old_data_index = 1;
- old_data_index < old_file_h->e_shnum;
- old_data_index++)
- {
-#ifdef DEBUG
- fprintf (stderr, "Looking for .data - found %s\n",
- old_section_names + OLD_SECTION_H(old_data_index).sh_name);
-#endif
- if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name,
- ".data"))
- break;
- }
- if (old_data_index == old_file_h->e_shnum)
- fatal ("Can't find .data in %s.\n", old_name, 0);
+ old_data_index = find_section (".data", old_section_names,
+ old_name, old_file_h, old_section_h, 0);
old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
{
caddr_t src;
- if (n < old_bss_index)
+ /* If it is bss section, insert the new data2 section before it. */
+ if (n == old_bss_index)
{
- memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
- old_file_h->e_shentsize);
-
- }
- else if (n == old_bss_index)
- {
-
- /* If it is bss section, insert the new data2 section before it. */
/* Steal the data section header for this data2 section. */
memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
new_file_h->e_shentsize);
NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
NEW_SECTION_H (nn).sh_size = 0;
}
- else /* n > old_bss_index */
+ else
{
-
memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
old_file_h->e_shentsize);
-
- }
- /* Any section that was original placed AFTER the bss
- section must now be adjusted by NEW_OFFSETS_SHIFT. */
+ /* Any section that was original placed AFTER the bss
+ section must now be adjusted by NEW_OFFSETS_SHIFT. */
+
+ if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
+ NEW_SECTION_H (nn).sh_offset += new_offsets_shift;
+ }
- if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
- NEW_SECTION_H (nn).sh_offset += new_offsets_shift;
-
/* If any section hdr refers to the section after the new .data
section, make it refer to next one because we have inserted
a new section in between. */
/* Write out the sections. .data and .data1 (and data2, called
".data" in the strings table) get copied from the current process
instead of the old file. */
- if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
- || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1")
- || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".got"))
+ if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
+ || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data1")
+#ifdef IRIX6_5
+ /* Under IRIX 6.5 gcc places objects with adresses relative to
+ shared symbols in the section .rodata, which are adjusted at
+ startup time. Unfortunately they aren't adjusted after unexec,
+ so with this configuration we must get .rodata also from memory.
+ Do any other configurations need this, too?
+ <Wolfgang.Glas@hfm.tu-graz.ac.at> 1999-06-08. */
+ || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".rodata")
+#endif
+ || !strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".got"))
src = (caddr_t) OLD_SECTION_H (n).sh_addr;
else
src = old_base + OLD_SECTION_H (n).sh_offset;
+ new_base);
for (; num--; sym++)
{
+ /* don't patch special section indices. */
if (sym->st_shndx == SHN_UNDEF
- || sym->st_shndx == SHN_ABS
- || sym->st_shndx == SHN_COMMON)
+ || sym->st_shndx >= SHN_LORESERVE)
continue;
PATCH_INDEX (sym->st_shndx);