diff options
author | Karl Heuer <kwzh@gnu.org> | 1996-01-08 22:29:48 +0000 |
---|---|---|
committer | Karl Heuer <kwzh@gnu.org> | 1996-01-08 22:29:48 +0000 |
commit | 48240339243662c5f0f0191c82c0f8de4361f1e1 (patch) | |
tree | 9d3a6061ec4b7d1a9eaf16f918156ce733533225 /src/unexelf.c | |
parent | 449decf581c0092e3048c9529dbe747b8b1619d3 (diff) | |
download | emacs-48240339243662c5f0f0191c82c0f8de4361f1e1.tar.gz emacs-48240339243662c5f0f0191c82c0f8de4361f1e1.tar.bz2 emacs-48240339243662c5f0f0191c82c0f8de4361f1e1.zip |
(unexec) [SOLARIS2]: Undo relocations performed by the
runtime linker.
Diffstat (limited to 'src/unexelf.c')
-rw-r--r-- | src/unexelf.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/unexelf.c b/src/unexelf.c index c61f4c368f1..c86663f7ace 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -807,6 +807,40 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) memcpy (&symp->st_value, &new_bss_addr, sizeof (new_bss_addr)); } +#ifdef SOLARIS2 + /* This loop seeks out relocation sections for the data section, so + that it can undo relocations performed by the runtime linker. */ + for (n = new_file_h->e_shnum - 1; n; n--) + { + Elf32_Shdr section = NEW_SECTION_H (n); + switch (section.sh_type) { + default: + break; + case SHT_REL: + case SHT_RELA: + /* This code handles two different size structs, but there + should be no harm in that provided that r_offset is always + the first member. */ + nn = section.sh_info; + if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data") + || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), + ".data1")) + { + Elf32_Addr offset = NEW_SECTION_H (nn).sh_addr - + NEW_SECTION_H (nn).sh_offset; + caddr_t reloc = old_base + section.sh_offset, end; + for (end = reloc + section.sh_size; reloc < end; + reloc += section.sh_entsize) + { + Elf32_Addr addr = ((Elf32_Rel *) reloc)->r_offset - offset; + memcpy (new_base + addr, old_base + addr, 4); + } + } + break; + } + } +#endif + #ifdef UNEXEC_USE_MAP_PRIVATE if (lseek (new_file, 0, SEEK_SET) == -1) fatal ("Can't rewind (%s): errno %d\n", new_name, errno); |