Commit 8daaf78b authored by Eli Zaretskii's avatar Eli Zaretskii
Browse files

[BROKEN_NOCOMBRELOC]: Include assert.h.

(unexec) [BROKEN_NOCOMBRELOC]: Handle platforms whose nocombreloc option
is broken (e.g., MIPS/NetBSD).
parent 09b7af0a
......@@ -433,6 +433,9 @@ extern void fatal (const char *msgid, ...);
#if __sgi
#include <syms.h> /* for HDRR declaration */
#endif /* __sgi */
#ifdef BROKEN_NOCOMBRELOC
#include <assert.h>
#endif
#ifndef MAP_ANON
#ifdef MAP_ANONYMOUS
......@@ -687,6 +690,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
int old_mdebug_index;
struct stat stat_buf;
int old_file_size;
#ifdef BROKEN_NOCOMBRELOC
int unreloc_sections[10], n_unreloc_sections;
#endif
/* Open the old file, allocate a buffer of the right size, and read
in the file contents. */
......@@ -1218,6 +1224,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
/* This loop seeks out relocation sections for the data section, so
that it can undo relocations performed by the runtime linker. */
#ifndef BROKEN_NOCOMBRELOC
for (n = new_file_h->e_shnum - 1; n; n--)
{
ElfW(Shdr) section = NEW_SECTION_H (n);
......@@ -1272,6 +1279,81 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
break;
}
}
#else /* BROKEN_NOCOMBRELOC */
for (n = 1, n_unreloc_sections = 0; n < new_file_h->e_shnum; n++)
if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
|| !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata")
|| !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".lit4")
|| !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".lit8")
#ifdef IRIX6_5 /* see above */
|| !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".got")
#endif
|| !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata1")
|| !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1"))
{
assert (n_unreloc_sections
< (sizeof (unreloc_sections) / sizeof (unreloc_sections[0])));
unreloc_sections[n_unreloc_sections++] = n;
#ifdef DEBUG
fprintf (stderr, "section %d: %s\n", n,
old_section_names + NEW_SECTION_H (n).sh_name);
#endif
}
for (n = new_file_h->e_shnum - 1; n; n--)
{
ElfW(Shdr) section = NEW_SECTION_H (n);
caddr_t reloc, end;
ElfW(Addr) addr, offset;
int target;
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. */
for (reloc = old_base + section.sh_offset,
end = reloc + section.sh_size;
reloc < end;
reloc += section.sh_entsize)
{
addr = ((ElfW(Rel) *) reloc)->r_offset;
#ifdef __alpha__
/* The Alpha ELF binutils currently have a bug that
sometimes results in relocs that contain all
zeroes. Work around this for now... */
if (addr == 0)
continue;
#endif
for (nn = 0; nn < n_unreloc_sections; nn++)
{
target = unreloc_sections[nn];
if (NEW_SECTION_H (target).sh_addr <= addr
&& addr < (NEW_SECTION_H (target).sh_addr +
NEW_SECTION_H (target).sh_size))
{
offset = (NEW_SECTION_H (target).sh_addr -
NEW_SECTION_H (target).sh_offset);
memcpy (new_base + addr - offset,
old_base + addr - offset,
sizeof (ElfW(Addr)));
#ifdef DEBUG
fprintf (stderr, "unrelocate: [%08lx] <= %08lx\n",
(long) addr,
(long) *((long *) (new_base + addr - offset)));
#endif
break;
}
}
}
break;
}
}
#endif /* BROKEN_NOCOMBRELOC */
/* Write out new_file, and free the buffers. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment