--- configure.in | 2 ++ src/m/macppc.h | 11 +++++++++++ src/unexelf.c | 27 +++++++++++++++++++++++---- 3 files changed, 36 insertions(+), 4 deletions(-) Index: configure.in =================================================================== --- configure.in.orig +++ configure.in @@ -279,6 +279,8 @@ case "${canonical}" in ;; ppc-*-linux* | \ + ppc64-*-linux | \ + powerpc64-*-linux* | \ powerpc-*-linux* ) machine=macppc opsys=gnu-linux ;; Index: src/m/macppc.h =================================================================== --- src/m/macppc.h.orig +++ src/m/macppc.h @@ -95,7 +95,18 @@ Boston, MA 02111-1307, USA. */ #ifdef LINUX #define LINKER $(CC) -nostdlib +#ifdef __powerpc64__ +#define LD_SWITCH_MACHINE -Xlinker -m -Xlinker elf64ppc +#undef START_FILES +#undef LIB_STANDARD +#define START_FILES pre-crt0.o /usr/lib64/crt1.o /usr/lib64/crti.o +#define LIB_STANDARD -lgcc -lc -lgcc /usr/lib64/crtn.o +#ifndef _LP64 +#define _LP64 +#endif +#else #define LD_SWITCH_MACHINE -Xlinker -m -Xlinker elf32ppc +#endif /* s/gnu-linux.h defines this to `-z nocombreloc' which does not work here because prefix-args is not used. */ #undef LD_SWITCH_SYSTEM_TEMACS Index: src/unexelf.c =================================================================== --- src/unexelf.c.orig +++ src/unexelf.c @@ -697,7 +697,7 @@ unexec (new_name, old_name, data_start, ElfW(Addr) new_data2_addr; int n, nn; - int old_bss_index, old_sbss_index; + int old_bss_index, old_sbss_index, old_plt_index; int old_data_index, new_data2_index; int old_mdebug_index; struct stat stat_buf; @@ -756,15 +756,34 @@ unexec (new_name, old_name, data_start, old_sbss_index = find_section (".sbss", old_section_names, old_name, old_file_h, old_section_h, 1); if (old_sbss_index != -1) - if (OLD_SECTION_H (old_sbss_index).sh_type == SHT_PROGBITS) + if (OLD_SECTION_H (old_sbss_index).sh_type != SHT_NOBITS) old_sbss_index = -1; - if (old_sbss_index == -1) + /* PowerPC64 has .plt in the BSS section. */ + old_plt_index = find_section (".plt", old_section_names, + old_name, old_file_h, old_section_h, 1); + if (old_plt_index != -1) + if (OLD_SECTION_H (old_plt_index).sh_type != SHT_NOBITS) + old_plt_index = -1; + + if (old_sbss_index == -1 && old_plt_index == -1) { old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr; old_bss_size = OLD_SECTION_H (old_bss_index).sh_size; new_data2_index = old_bss_index; } + else if (old_plt_index != -1 + && (old_sbss_index == -1 + || (OLD_SECTION_H (old_sbss_index).sh_addr + > OLD_SECTION_H (old_plt_index).sh_addr))) + { + old_bss_addr = OLD_SECTION_H (old_plt_index).sh_addr; + old_bss_size = OLD_SECTION_H (old_bss_index).sh_size + + OLD_SECTION_H (old_plt_index).sh_size; + if (old_sbss_index != -1) + old_bss_size += OLD_SECTION_H (old_sbss_index).sh_size; + new_data2_index = old_plt_index; + } else { old_bss_addr = OLD_SECTION_H (old_sbss_index).sh_addr; @@ -955,7 +974,7 @@ unexec (new_name, old_name, data_start, if (n == old_bss_index /* The new bss and sbss section's size is zero, and its file offset and virtual address should be off by NEW_DATA2_SIZE. */ - || n == old_sbss_index + || n == old_sbss_index || n == old_plt_index ) { /* NN should be `old_s?bss_index + 1' at this point. */