From 265b26952815a893b33da9c34dec6ea5cfbfd7cb Mon Sep 17 00:00:00 2001 From: "Richard M. Stallman" Date: Wed, 4 Sep 1996 15:15:42 +0000 Subject: [PATCH] unexelf1.c merged into this file. --- src/unexelf.c | 98 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/src/unexelf.c b/src/unexelf.c index 60e82cc6a95..a832755167e 100644 --- a/src/unexelf.c +++ b/src/unexelf.c @@ -423,6 +423,22 @@ Filesz Memsz Flags Align #include #include +#ifdef __alpha__ +# include /* get COFF debugging symbol table declaration */ +#endif + +#if __GNU_LIBRARY__ - 0 >= 6 +# include /* get ElfW etc */ +#endif + +#ifndef ElfW +# ifdef __STDC__ +# define ElfW(type) Elf32_##type +# else +# define ElfW(type) Elf32_/**/type +# endif +#endif + #ifndef emacs #define fatal(a, b, c) fprintf (stderr, a, b, c), exit (1) #else @@ -462,13 +478,13 @@ extern void fatal (char *, ...); */ #define OLD_SECTION_H(n) \ - (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) + (*(ElfW(Shdr) *) ((byte *) old_section_h + old_file_h->e_shentsize * (n))) #define NEW_SECTION_H(n) \ - (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) + (*(ElfW(Shdr) *) ((byte *) new_section_h + new_file_h->e_shentsize * (n))) #define OLD_PROGRAM_H(n) \ - (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) + (*(ElfW(Phdr) *) ((byte *) old_program_h + old_file_h->e_phentsize * (n))) #define NEW_PROGRAM_H(n) \ - (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) + (*(ElfW(Phdr) *) ((byte *) new_program_h + new_file_h->e_phentsize * (n))) #define PATCH_INDEX(n) \ do { \ @@ -510,17 +526,17 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) /* Pointers to the file, program and section headers for the old and new * files. */ - Elf32_Ehdr *old_file_h, *new_file_h; - Elf32_Phdr *old_program_h, *new_program_h; - Elf32_Shdr *old_section_h, *new_section_h; + ElfW(Ehdr) *old_file_h, *new_file_h; + ElfW(Phdr) *old_program_h, *new_program_h; + ElfW(Shdr) *old_section_h, *new_section_h; /* Point to the section name table in the old file */ char *old_section_names; - Elf32_Addr old_bss_addr, new_bss_addr; - Elf32_Word old_bss_size, new_data2_size; - Elf32_Off new_data2_offset; - Elf32_Addr new_data2_addr; + ElfW(Addr) old_bss_addr, new_bss_addr; + ElfW(Word) old_bss_size, new_data2_size; + ElfW(Off) new_data2_offset; + ElfW(Addr) new_data2_addr; int n, nn, old_bss_index, old_data_index, new_data2_index; struct stat stat_buf; @@ -547,9 +563,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) /* Get pointers to headers & section names */ - old_file_h = (Elf32_Ehdr *) old_base; - old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff); - old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff); + old_file_h = (ElfW(Ehdr) *) old_base; + old_program_h = (ElfW(Phdr) *) ((byte *) old_base + old_file_h->e_phoff); + old_section_h = (ElfW(Shdr) *) ((byte *) old_base + old_file_h->e_shoff); old_section_names = (char *) old_base + OLD_SECTION_H (old_file_h->e_shstrndx).sh_offset; @@ -574,7 +590,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; #if defined(emacs) || !defined(DEBUG) - new_bss_addr = (Elf32_Addr) sbrk (0); + new_bss_addr = (ElfW(Addr)) sbrk (0); #else new_bss_addr = old_bss_addr + old_bss_size + 0x1234; #endif @@ -620,9 +636,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) if (new_base == (caddr_t) -1) fatal ("Can't mmap (%s): errno %d\n", new_name, errno); - new_file_h = (Elf32_Ehdr *) new_base; - new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff); - new_section_h = (Elf32_Shdr *) + new_file_h = (ElfW(Ehdr) *) new_base; + new_program_h = (ElfW(Phdr) *) ((byte *) new_base + old_file_h->e_phoff); + new_section_h = (ElfW(Shdr) *) ((byte *) new_base + old_file_h->e_shoff + new_data2_size); /* Make our new file, program and section headers as copies of the @@ -808,13 +824,34 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src, NEW_SECTION_H (nn).sh_size); +#ifdef __alpha__ + /* Update Alpha COFF symbol table: */ + if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug") + == 0) + { + pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base); + + symhdr->cbLineOffset += new_data2_size; + symhdr->cbDnOffset += new_data2_size; + symhdr->cbPdOffset += new_data2_size; + symhdr->cbSymOffset += new_data2_size; + symhdr->cbOptOffset += new_data2_size; + symhdr->cbAuxOffset += new_data2_size; + symhdr->cbSsOffset += new_data2_size; + symhdr->cbSsExtOffset += new_data2_size; + symhdr->cbFdOffset += new_data2_size; + symhdr->cbRfdOffset += new_data2_size; + symhdr->cbExtOffset += new_data2_size; + } +#endif /* __alpha__ */ + /* If it is the symbol table, its st_shndx field needs to be patched. */ if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) { - Elf32_Shdr *spt = &NEW_SECTION_H (nn); + ElfW(Shdr) *spt = &NEW_SECTION_H (nn); unsigned int num = spt->sh_size / spt->sh_entsize; - Elf32_Sym * sym = (Elf32_Sym *) (NEW_SECTION_H (nn).sh_offset + + ElfW(Sym) * sym = (ElfW(Sym) *) (NEW_SECTION_H (nn).sh_offset + new_base); for (; num--; sym++) { @@ -832,7 +869,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) for (n = new_file_h->e_shnum - 1; n; n--) { byte *symnames; - Elf32_Sym *symp, *symendp; + ElfW(Sym) *symp, *symendp; if (NEW_SECTION_H (n).sh_type != SHT_DYNSYM && NEW_SECTION_H (n).sh_type != SHT_SYMTAB) @@ -840,8 +877,8 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) symnames = ((byte *) new_base + NEW_SECTION_H (NEW_SECTION_H (n).sh_link).sh_offset); - symp = (Elf32_Sym *) (NEW_SECTION_H (n).sh_offset + new_base); - symendp = (Elf32_Sym *) ((byte *)symp + NEW_SECTION_H (n).sh_size); + symp = (ElfW(Sym) *) (NEW_SECTION_H (n).sh_offset + new_base); + symendp = (ElfW(Sym) *) ((byte *)symp + NEW_SECTION_H (n).sh_size); for (; symp < symendp; symp ++) if (strcmp ((char *) (symnames + symp->st_name), "_end") == 0 @@ -853,7 +890,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) 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); + ElfW(Shdr) section = NEW_SECTION_H (n); switch (section.sh_type) { default: break; @@ -867,14 +904,21 @@ unexec (new_name, old_name, data_start, bss_start, entry_address) || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name), ".data1")) { - Elf32_Addr offset = NEW_SECTION_H (nn).sh_addr - + ElfW(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); + ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - 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 (((ElfW(Rel) *) reloc)->r_offset == 0) + continue; +#endif + memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr))); } } break; -- 2.39.2