|
|
bb3be4 |
From c7ffdf36d7eb5ed8044818902d4c69516d09dbb2 Mon Sep 17 00:00:00 2001
|
|
|
bb3be4 |
From: Alan Modra <amodra@gmail.com>
|
|
|
bb3be4 |
Date: Sun, 8 Nov 2015 09:28:59 -0800
|
|
|
bb3be4 |
Subject: [PATCH 03/11] ELF unexec: Tidy code
|
|
|
bb3be4 |
|
|
|
bb3be4 |
Separate out some of the more mechanical changes so following patches
|
|
|
bb3be4 |
are smaller.
|
|
|
bb3be4 |
|
|
|
bb3be4 |
* unexelf.c (unexec): Rearrange initialisation of program
|
|
|
bb3be4 |
header vars. Use pointer vars in loops rather than indexing
|
|
|
bb3be4 |
section header array via macros. Simplify _OBJC_ sym code
|
|
|
bb3be4 |
and reloc handling code.
|
|
|
bb3be4 |
---
|
|
|
bb3be4 |
src/unexelf.c | 210 +++++++++++++++++++++++++++-------------------------------
|
|
|
bb3be4 |
1 file changed, 96 insertions(+), 114 deletions(-)
|
|
|
bb3be4 |
|
|
|
bb3be4 |
diff --git a/src/unexelf.c b/src/unexelf.c
|
|
|
bb3be4 |
index 1699f31..d6c6648 100644
|
|
|
bb3be4 |
--- a/src/unexelf.c
|
|
|
bb3be4 |
+++ b/src/unexelf.c
|
|
|
bb3be4 |
@@ -812,20 +812,11 @@ unexec (const char *new_name, const char *old_name)
|
|
|
bb3be4 |
if (new_base == MAP_FAILED)
|
|
|
bb3be4 |
fatal ("Can't allocate buffer for %s: %s", old_name, strerror (errno));
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- new_file_h = (ElfW (Ehdr) *) new_base;
|
|
|
bb3be4 |
- new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
|
|
|
bb3be4 |
- new_section_h = (ElfW (Shdr) *)
|
|
|
bb3be4 |
- ((byte *) new_base + old_file_h->e_shoff + new_data2_incr);
|
|
|
bb3be4 |
-
|
|
|
bb3be4 |
/* Make our new file, program and section headers as copies of the
|
|
|
bb3be4 |
originals. */
|
|
|
bb3be4 |
|
|
|
bb3be4 |
+ new_file_h = (ElfW (Ehdr) *) new_base;
|
|
|
bb3be4 |
memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
|
|
|
bb3be4 |
- memcpy (new_program_h, old_program_h,
|
|
|
bb3be4 |
- old_file_h->e_phnum * old_file_h->e_phentsize);
|
|
|
bb3be4 |
-
|
|
|
bb3be4 |
- /* Modify the e_shstrndx if necessary. */
|
|
|
bb3be4 |
- PATCH_INDEX (new_file_h->e_shstrndx);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
/* Fix up file header. We'll add one section. Section header is
|
|
|
bb3be4 |
further away now. */
|
|
|
bb3be4 |
@@ -833,6 +824,16 @@ unexec (const char *new_name, const char *old_name)
|
|
|
bb3be4 |
new_file_h->e_shoff += new_data2_incr;
|
|
|
bb3be4 |
new_file_h->e_shnum += 1;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
+ /* Modify the e_shstrndx if necessary. */
|
|
|
bb3be4 |
+ PATCH_INDEX (new_file_h->e_shstrndx);
|
|
|
bb3be4 |
+
|
|
|
bb3be4 |
+ new_program_h = (ElfW (Phdr) *) ((byte *) new_base + old_file_h->e_phoff);
|
|
|
bb3be4 |
+ new_section_h = (ElfW (Shdr) *)
|
|
|
bb3be4 |
+ ((byte *) new_base + old_file_h->e_shoff + new_data2_incr);
|
|
|
bb3be4 |
+
|
|
|
bb3be4 |
+ memcpy (new_program_h, old_program_h,
|
|
|
bb3be4 |
+ old_file_h->e_phnum * old_file_h->e_phentsize);
|
|
|
bb3be4 |
+
|
|
|
bb3be4 |
#ifdef UNEXELF_DEBUG
|
|
|
bb3be4 |
DEBUG_LOG (old_file_h->e_shoff);
|
|
|
bb3be4 |
fprintf (stderr, "Old section count %td\n", (ptrdiff_t) old_file_h->e_shnum);
|
|
|
bb3be4 |
@@ -905,32 +906,35 @@ unexec (const char *new_name, const char *old_name)
|
|
|
bb3be4 |
for (n = 1, nn = 1; n < old_file_h->e_shnum; n++, nn++)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
caddr_t src;
|
|
|
bb3be4 |
+ ElfW (Shdr) *old_shdr = &OLD_SECTION_H (n);
|
|
|
bb3be4 |
+ ElfW (Shdr) *new_shdr = &NEW_SECTION_H (nn);
|
|
|
bb3be4 |
+
|
|
|
bb3be4 |
/* If it is (s)bss section, insert the new data2 section before it. */
|
|
|
bb3be4 |
/* new_data2_index is the index of either old_sbss or old_bss, that was
|
|
|
bb3be4 |
chosen as a section for new_data2. */
|
|
|
bb3be4 |
if (n == new_data2_index)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
/* Steal the data section header for this data2 section. */
|
|
|
bb3be4 |
- memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
|
|
|
bb3be4 |
+ memcpy (new_shdr, &OLD_SECTION_H (old_data_index),
|
|
|
bb3be4 |
new_file_h->e_shentsize);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_addr = new_data2_addr;
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_offset = new_data2_offset;
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_size = new_data2_size;
|
|
|
bb3be4 |
+ new_shdr->sh_addr = new_data2_addr;
|
|
|
bb3be4 |
+ new_shdr->sh_offset = new_data2_offset;
|
|
|
bb3be4 |
+ new_shdr->sh_size = new_data2_size;
|
|
|
bb3be4 |
/* Use the bss section's alignment. This will assure that the
|
|
|
bb3be4 |
new data2 section always be placed in the same spot as the old
|
|
|
bb3be4 |
bss section by any other application. */
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (n).sh_addralign;
|
|
|
bb3be4 |
+ new_shdr->sh_addralign = old_shdr->sh_addralign;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
/* Now copy over what we have in the memory now. */
|
|
|
bb3be4 |
- memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
|
|
|
bb3be4 |
- (caddr_t) OLD_SECTION_H (n).sh_addr,
|
|
|
bb3be4 |
+ memcpy (new_shdr->sh_offset + new_base,
|
|
|
bb3be4 |
+ (caddr_t) old_shdr->sh_addr,
|
|
|
bb3be4 |
new_data2_size);
|
|
|
bb3be4 |
nn++;
|
|
|
bb3be4 |
+ new_shdr++;
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
|
|
|
bb3be4 |
- old_file_h->e_shentsize);
|
|
|
bb3be4 |
+ memcpy (new_shdr, old_shdr, old_file_h->e_shentsize);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
if (n == old_bss_index
|
|
|
bb3be4 |
/* The new bss and sbss section's size is zero, and its file offset
|
|
|
bb3be4 |
@@ -939,13 +943,13 @@ unexec (const char *new_name, const char *old_name)
|
|
|
bb3be4 |
)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
/* NN should be `old_s?bss_index + 1' at this point. */
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_offset = new_data2_offset + new_data2_size;
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_addr = new_data2_addr + new_data2_size;
|
|
|
bb3be4 |
+ new_shdr->sh_offset = new_data2_offset + new_data2_size;
|
|
|
bb3be4 |
+ new_shdr->sh_addr = new_data2_addr + new_data2_size;
|
|
|
bb3be4 |
/* Let the new bss section address alignment be the same as the
|
|
|
bb3be4 |
section address alignment followed the old bss section, so
|
|
|
bb3be4 |
this section will be placed in exactly the same place. */
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_addralign = OLD_SECTION_H (nn).sh_addralign;
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_size = 0;
|
|
|
bb3be4 |
+ new_shdr->sh_addralign = OLD_SECTION_H (nn).sh_addralign;
|
|
|
bb3be4 |
+ new_shdr->sh_size = 0;
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
else
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
@@ -975,53 +979,50 @@ temacs:
|
|
|
bb3be4 |
25 1709 0x4 0x10
|
|
|
bb3be4 |
*/
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- if (NEW_SECTION_H (nn).sh_offset >= old_bss_offset
|
|
|
bb3be4 |
- || (NEW_SECTION_H (nn).sh_offset + NEW_SECTION_H (nn).sh_size
|
|
|
bb3be4 |
+ if (new_shdr->sh_offset >= old_bss_offset
|
|
|
bb3be4 |
+ || (new_shdr->sh_offset + new_shdr->sh_size
|
|
|
bb3be4 |
> new_data2_offset))
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_offset += new_data2_incr;
|
|
|
bb3be4 |
+ new_shdr->sh_offset += new_data2_incr;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
/* Any section that was originally placed after the section
|
|
|
bb3be4 |
header table should now be off by the size of one section
|
|
|
bb3be4 |
header table entry. */
|
|
|
bb3be4 |
- if (NEW_SECTION_H (nn).sh_offset > new_file_h->e_shoff)
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_offset += new_file_h->e_shentsize;
|
|
|
bb3be4 |
+ if (new_shdr->sh_offset > new_file_h->e_shoff)
|
|
|
bb3be4 |
+ new_shdr->sh_offset += new_file_h->e_shentsize;
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
|
|
|
bb3be4 |
/* If any section hdr refers to the section after the new .data
|
|
|
bb3be4 |
section, make it refer to next one because we have inserted
|
|
|
bb3be4 |
a new section in between. */
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- PATCH_INDEX (NEW_SECTION_H (nn).sh_link);
|
|
|
bb3be4 |
+ PATCH_INDEX (new_shdr->sh_link);
|
|
|
bb3be4 |
/* For symbol tables, info is a symbol table index,
|
|
|
bb3be4 |
so don't change it. */
|
|
|
bb3be4 |
- if (NEW_SECTION_H (nn).sh_type != SHT_SYMTAB
|
|
|
bb3be4 |
- && NEW_SECTION_H (nn).sh_type != SHT_DYNSYM)
|
|
|
bb3be4 |
- PATCH_INDEX (NEW_SECTION_H (nn).sh_info);
|
|
|
bb3be4 |
+ if (new_shdr->sh_type != SHT_SYMTAB
|
|
|
bb3be4 |
+ && new_shdr->sh_type != SHT_DYNSYM)
|
|
|
bb3be4 |
+ PATCH_INDEX (new_shdr->sh_info);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
if (old_sbss_index != -1)
|
|
|
bb3be4 |
- if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".sbss"))
|
|
|
bb3be4 |
+ if (!strcmp (old_section_names + new_shdr->sh_name, ".sbss"))
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_offset =
|
|
|
bb3be4 |
- round_up (NEW_SECTION_H (nn).sh_offset,
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_addralign);
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_type = SHT_PROGBITS;
|
|
|
bb3be4 |
+ new_shdr->sh_offset =
|
|
|
bb3be4 |
+ round_up (new_shdr->sh_offset,
|
|
|
bb3be4 |
+ new_shdr->sh_addralign);
|
|
|
bb3be4 |
+ new_shdr->sh_type = SHT_PROGBITS;
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
|
|
|
bb3be4 |
/* Now, start to copy the content of sections. */
|
|
|
bb3be4 |
- if (NEW_SECTION_H (nn).sh_type == SHT_NULL
|
|
|
bb3be4 |
- || NEW_SECTION_H (nn).sh_type == SHT_NOBITS)
|
|
|
bb3be4 |
+ if (new_shdr->sh_type == SHT_NULL
|
|
|
bb3be4 |
+ || new_shdr->sh_type == SHT_NOBITS)
|
|
|
bb3be4 |
continue;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
/* Write out the sections. .data and .data1 (and data2, called
|
|
|
bb3be4 |
".data" in the strings table) get copied from the current process
|
|
|
bb3be4 |
instead of the old file. */
|
|
|
bb3be4 |
- if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".sdata")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".lit4")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".lit8")
|
|
|
bb3be4 |
+ if (!strcmp (old_section_names + new_shdr->sh_name, ".data")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + new_shdr->sh_name, ".sdata")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + new_shdr->sh_name, ".lit4")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + new_shdr->sh_name, ".lit8")
|
|
|
bb3be4 |
/* The conditional bit below was in Oliva's original code
|
|
|
bb3be4 |
(1999-08-25) and seems to have been dropped by mistake
|
|
|
bb3be4 |
subsequently. It prevents a crash at startup under X in
|
|
|
bb3be4 |
@@ -1043,28 +1044,22 @@ temacs:
|
|
|
bb3be4 |
loader, but I never got anywhere with an SGI support call
|
|
|
bb3be4 |
seeking clues. -- fx 2002-11-29. */
|
|
|
bb3be4 |
#ifdef IRIX6_5
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".got")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + new_shdr->sh_name, ".got")
|
|
|
bb3be4 |
#endif
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".sdata1")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".data1")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".sbss"))
|
|
|
bb3be4 |
- src = (caddr_t) OLD_SECTION_H (n).sh_addr;
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + new_shdr->sh_name, ".sdata1")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + new_shdr->sh_name, ".data1")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + new_shdr->sh_name, ".sbss"))
|
|
|
bb3be4 |
+ src = (caddr_t) old_shdr->sh_addr;
|
|
|
bb3be4 |
else
|
|
|
bb3be4 |
- src = old_base + OLD_SECTION_H (n).sh_offset;
|
|
|
bb3be4 |
+ src = old_base + old_shdr->sh_offset;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
|
|
|
bb3be4 |
- NEW_SECTION_H (nn).sh_size);
|
|
|
bb3be4 |
+ memcpy (new_shdr->sh_offset + new_base, src, new_shdr->sh_size);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
#if defined __alpha__ && !defined __OpenBSD__
|
|
|
bb3be4 |
/* Update Alpha COFF symbol table: */
|
|
|
bb3be4 |
- if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
|
|
|
bb3be4 |
- == 0)
|
|
|
bb3be4 |
+ if (strcmp (old_section_names + old_shdr->sh_name, ".mdebug") == 0)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
|
|
|
bb3be4 |
+ pHDRR symhdr = (pHDRR) (new_shdr->sh_offset + new_base);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
symhdr->cbLineOffset += new_data2_size;
|
|
|
bb3be4 |
symhdr->cbDnOffset += new_data2_size;
|
|
|
bb3be4 |
@@ -1081,13 +1076,13 @@ temacs:
|
|
|
bb3be4 |
#endif /* __alpha__ && !__OpenBSD__ */
|
|
|
bb3be4 |
|
|
|
bb3be4 |
#if defined (_SYSTYPE_SYSV)
|
|
|
bb3be4 |
- if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG
|
|
|
bb3be4 |
+ if (new_shdr->sh_type == SHT_MIPS_DEBUG
|
|
|
bb3be4 |
&& old_mdebug_index != -1)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- ptrdiff_t new_offset = NEW_SECTION_H (nn).sh_offset;
|
|
|
bb3be4 |
+ ptrdiff_t new_offset = new_shdr->sh_offset;
|
|
|
bb3be4 |
ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset;
|
|
|
bb3be4 |
ptrdiff_t diff = new_offset - old_offset;
|
|
|
bb3be4 |
- HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
|
|
|
bb3be4 |
+ HDRR *phdr = (HDRR *) (new_shdr->sh_offset + new_base);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
if (diff)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
@@ -1123,8 +1118,8 @@ temacs:
|
|
|
bb3be4 |
n_phdrr->__fileaddr += movement; \
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset);
|
|
|
bb3be4 |
- HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset);
|
|
|
bb3be4 |
+ HDRR *o_phdrr = (HDRR *) ((byte *) old_base + old_shdr->sh_offset);
|
|
|
bb3be4 |
+ HDRR *n_phdrr = (HDRR *) ((byte *) new_base + new_shdr->sh_offset);
|
|
|
bb3be4 |
unsigned movement = new_data2_size;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
MDEBUGADJUST (idnMax, cbDnOffset);
|
|
|
bb3be4 |
@@ -1141,8 +1136,8 @@ temacs:
|
|
|
bb3be4 |
requires special handling. */
|
|
|
bb3be4 |
if (n_phdrr->cbLine > 0)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset
|
|
|
bb3be4 |
- + OLD_SECTION_H (n).sh_size))
|
|
|
bb3be4 |
+ if (o_phdrr->cbLineOffset > (old_shdr->sh_offset
|
|
|
bb3be4 |
+ + old_shdr->sh_size))
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
/* line data is in a hole in elf. do special copy and adjust
|
|
|
bb3be4 |
for this ld mistake.
|
|
|
bb3be4 |
@@ -1162,13 +1157,11 @@ temacs:
|
|
|
bb3be4 |
#endif /* __sgi */
|
|
|
bb3be4 |
|
|
|
bb3be4 |
/* If it is the symbol table, its st_shndx field needs to be patched. */
|
|
|
bb3be4 |
- if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
|
|
|
bb3be4 |
- || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
|
|
|
bb3be4 |
+ if (new_shdr->sh_type == SHT_SYMTAB
|
|
|
bb3be4 |
+ || new_shdr->sh_type == SHT_DYNSYM)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- ElfW (Shdr) *spt = &NEW_SECTION_H (nn);
|
|
|
bb3be4 |
- ptrdiff_t num = spt->sh_size / spt->sh_entsize;
|
|
|
bb3be4 |
- ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset +
|
|
|
bb3be4 |
- new_base);
|
|
|
bb3be4 |
+ ptrdiff_t num = new_shdr->sh_size / new_shdr->sh_entsize;
|
|
|
bb3be4 |
+ ElfW (Sym) *sym = (ElfW (Sym) *) (new_shdr->sh_offset + new_base);
|
|
|
bb3be4 |
for (; num--; sym++)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
if ((sym->st_shndx == SHN_UNDEF)
|
|
|
bb3be4 |
@@ -1186,15 +1179,16 @@ temacs:
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
byte *symnames;
|
|
|
bb3be4 |
ElfW (Sym) *symp, *symendp;
|
|
|
bb3be4 |
+ ElfW (Shdr) *sym_shdr = &NEW_SECTION_H (n);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM
|
|
|
bb3be4 |
- && NEW_SECTION_H (n).sh_type != SHT_SYMTAB)
|
|
|
bb3be4 |
+ if (sym_shdr->sh_type != SHT_DYNSYM
|
|
|
bb3be4 |
+ && sym_shdr->sh_type != SHT_SYMTAB)
|
|
|
bb3be4 |
continue;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
symnames = ((byte *) new_base
|
|
|
bb3be4 |
- + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset);
|
|
|
bb3be4 |
- symp = (ElfW (Sym) *) (NEW_SECTION_H (n).sh_offset + new_base);
|
|
|
bb3be4 |
- symendp = (ElfW (Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size);
|
|
|
bb3be4 |
+ + NEW_SECTION_H (sym_shdr->sh_link).sh_offset);
|
|
|
bb3be4 |
+ symp = (ElfW (Sym) *) (sym_shdr->sh_offset + new_base);
|
|
|
bb3be4 |
+ symendp = (ElfW (Sym) *) ((byte *) symp + sym_shdr->sh_size);
|
|
|
bb3be4 |
|
|
|
bb3be4 |
for (; symp < symendp; symp ++)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
@@ -1218,22 +1212,21 @@ temacs:
|
|
|
bb3be4 |
if (strncmp ((char *) (symnames + symp->st_name),
|
|
|
bb3be4 |
"_OBJC_", sizeof ("_OBJC_") - 1) == 0)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- caddr_t old, new;
|
|
|
bb3be4 |
+ ElfW (Shdr) *new_shdr = &NEW_SECTION_H (symp->st_shndx);
|
|
|
bb3be4 |
+ ptrdiff_t reladdr = symp->st_value - new_shdr->sh_addr;
|
|
|
bb3be4 |
+ ptrdiff_t newoff = reladdr + new_shdr->sh_offset;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- new = ((symp->st_value - NEW_SECTION_H (symp->st_shndx).sh_addr)
|
|
|
bb3be4 |
- + NEW_SECTION_H (symp->st_shndx).sh_offset + new_base);
|
|
|
bb3be4 |
/* "Unpatch" index. */
|
|
|
bb3be4 |
nn = symp->st_shndx;
|
|
|
bb3be4 |
if (nn > old_bss_index)
|
|
|
bb3be4 |
nn--;
|
|
|
bb3be4 |
if (nn == old_bss_index)
|
|
|
bb3be4 |
- memset (new, 0, symp->st_size);
|
|
|
bb3be4 |
+ memset (new_base + newoff, 0, symp->st_size);
|
|
|
bb3be4 |
else
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- old = ((symp->st_value
|
|
|
bb3be4 |
- - NEW_SECTION_H (symp->st_shndx).sh_addr)
|
|
|
bb3be4 |
- + OLD_SECTION_H (nn).sh_offset + old_base);
|
|
|
bb3be4 |
- memcpy (new, old, symp->st_size);
|
|
|
bb3be4 |
+ ElfW (Shdr) *old_shdr = &OLD_SECTION_H (nn);
|
|
|
bb3be4 |
+ ptrdiff_t oldoff = reladdr + old_shdr->sh_offset;
|
|
|
bb3be4 |
+ memcpy (new_base + newoff, old_base + oldoff, symp->st_size);
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
#endif
|
|
|
bb3be4 |
@@ -1244,13 +1237,10 @@ temacs:
|
|
|
bb3be4 |
that it can undo relocations performed by the runtime linker. */
|
|
|
bb3be4 |
for (n = new_file_h->e_shnum; 0 < --n; )
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- ElfW (Shdr) section = NEW_SECTION_H (n);
|
|
|
bb3be4 |
-
|
|
|
bb3be4 |
- /* Cause a compilation error if anyone uses n instead of nn below. */
|
|
|
bb3be4 |
- #define n ((void) 0);
|
|
|
bb3be4 |
- n /* Prevent 'macro "n" is not used' warnings. */
|
|
|
bb3be4 |
+ ElfW (Shdr) *rel_shdr = &NEW_SECTION_H (n);
|
|
|
bb3be4 |
+ ElfW (Shdr) *shdr;
|
|
|
bb3be4 |
|
|
|
bb3be4 |
- switch (section.sh_type)
|
|
|
bb3be4 |
+ switch (rel_shdr->sh_type)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
default:
|
|
|
bb3be4 |
break;
|
|
|
bb3be4 |
@@ -1259,28 +1249,22 @@ temacs:
|
|
|
bb3be4 |
/* This code handles two different size structs, but there should
|
|
|
bb3be4 |
be no harm in that provided that r_offset is always the first
|
|
|
bb3be4 |
member. */
|
|
|
bb3be4 |
- nn = section.sh_info;
|
|
|
bb3be4 |
- if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".sdata")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".lit4")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".lit8")
|
|
|
bb3be4 |
+ shdr = &NEW_SECTION_H (rel_shdr->sh_info);
|
|
|
bb3be4 |
+ if (!strcmp (old_section_names + shdr->sh_name, ".data")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + shdr->sh_name, ".sdata")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + shdr->sh_name, ".lit4")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + shdr->sh_name, ".lit8")
|
|
|
bb3be4 |
#ifdef IRIX6_5 /* see above */
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".got")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + shdr->sh_name, ".got")
|
|
|
bb3be4 |
#endif
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".sdata1")
|
|
|
bb3be4 |
- || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
|
|
|
bb3be4 |
- ".data1"))
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + shdr->sh_name, ".sdata1")
|
|
|
bb3be4 |
+ || !strcmp (old_section_names + shdr->sh_name, ".data1"))
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
- ElfW (Addr) offset = (NEW_SECTION_H (nn).sh_addr
|
|
|
bb3be4 |
- - NEW_SECTION_H (nn).sh_offset);
|
|
|
bb3be4 |
- caddr_t reloc = old_base + section.sh_offset, end;
|
|
|
bb3be4 |
- for (end = reloc + section.sh_size; reloc < end;
|
|
|
bb3be4 |
- reloc += section.sh_entsize)
|
|
|
bb3be4 |
+ ElfW (Addr) offset = shdr->sh_addr - shdr->sh_offset;
|
|
|
bb3be4 |
+ caddr_t reloc = old_base + rel_shdr->sh_offset, end;
|
|
|
bb3be4 |
+ for (end = reloc + rel_shdr->sh_size;
|
|
|
bb3be4 |
+ reloc < end;
|
|
|
bb3be4 |
+ reloc += rel_shdr->sh_entsize)
|
|
|
bb3be4 |
{
|
|
|
bb3be4 |
ElfW (Addr) addr = ((ElfW (Rel) *) reloc)->r_offset - offset;
|
|
|
bb3be4 |
#ifdef __alpha__
|
|
|
bb3be4 |
@@ -1295,8 +1279,6 @@ temacs:
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
break;
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
-
|
|
|
bb3be4 |
- #undef n
|
|
|
bb3be4 |
}
|
|
|
bb3be4 |
|
|
|
bb3be4 |
/* Write out new_file, and free the buffers. */
|
|
|
bb3be4 |
--
|
|
|
bb3be4 |
2.7.4
|
|
|
bb3be4 |
|