From 0260f0790a024794c3b12e860f8a03d273fad9b3 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Mon, 12 Nov 2007 09:12:51 -0800 Subject: [PATCH] mipseb.r3000-linux.elf [broken because no big-endian tool chain] --- src/conf.h | 1 + src/linker.cpp | 31 +++++++++++++ src/linker.h | 9 ++++ src/stub/Makefile | 47 +++++++++++++++++++ src/stub/src/mipseb.r3000-linux.elf-entry.S | 1 + src/stub/src/mipseb.r3000-linux.elf-fold.S | 1 + src/stub/src/mipseb.r3000-linux.elf-fold.lds | 49 ++++++++++++++++++++ src/stub/src/mipseb.r3000-linux.elf-main.c | 1 + 8 files changed, 140 insertions(+) create mode 100644 src/stub/src/mipseb.r3000-linux.elf-entry.S create mode 100644 src/stub/src/mipseb.r3000-linux.elf-fold.S create mode 100644 src/stub/src/mipseb.r3000-linux.elf-fold.lds create mode 100644 src/stub/src/mipseb.r3000-linux.elf-main.c diff --git a/src/conf.h b/src/conf.h index 91bec926..40912815 100644 --- a/src/conf.h +++ b/src/conf.h @@ -470,6 +470,7 @@ private: #define UPX_F_MACH_FAT 134 #define UPX_F_VMLINUX_ARMEB 135 #define UPX_F_VMLINUX_PPC32 136 +#define UPX_F_LINUX_ELF32_MIPSEB 137 // compression methods diff --git a/src/linker.cpp b/src/linker.cpp index 529118ba..5a4db6f1 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -765,6 +765,37 @@ void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location, } +void ElfLinkerMipsBE::relocate1(const Relocation *rel, upx_byte *location, + unsigned value, const char *type) +{ +#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15)) +#define MIPS_LO(a) ((a) & 0xffff) +#define MIPS_PC16(a) ((a) >> 2) +#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2) + + if (strcmp(type, "R_MIPS_HI16") == 0) + set_le16(location, get_le16(location) + MIPS_HI(value)); + else if (strcmp(type, "R_MIPS_LO16") == 0) + set_le16(location, get_le16(location) + MIPS_LO(value)); + else if (strcmp(type, "R_MIPS_PC16") == 0) + { + value -= rel->section->offset + rel->offset; + set_le16(location, get_le16(location) + MIPS_PC16(value)); + } + else if (strcmp(type, "R_MIPS_26") == 0) + set_le32(location, get_le32(location) + MIPS_PC26(value)); + else if (strcmp(type, "R_MIPS_32") == 0) + set_le32(location, get_le32(location) + value); + else + super::relocate1(rel, location, value, type); + +#undef MIPS_HI +#undef MIPS_LO +#undef MIPS_PC16 +#undef MIPS_PC26 +} + + void ElfLinkerMipsLE::relocate1(const Relocation *rel, upx_byte *location, unsigned value, const char *type) { diff --git a/src/linker.h b/src/linker.h index dbeda4d5..41d03011 100644 --- a/src/linker.h +++ b/src/linker.h @@ -195,6 +195,15 @@ protected: }; +class ElfLinkerMipsBE : public ElfLinker +{ + typedef ElfLinker super; +protected: + virtual void relocate1(const Relocation *, upx_byte *location, + unsigned value, const char *type); +}; + + class ElfLinkerMipsLE : public ElfLinker { typedef ElfLinker super; diff --git a/src/stub/Makefile b/src/stub/Makefile index 25640430..a4b5b024 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -88,6 +88,8 @@ STUBS += i386-linux.kernel.vmlinux-head.h STUBS += i386-linux.kernel.vmlinuz.h STUBS += i386-win32.pe.h STUBS += m68k-atari.tos.h +STUBS += mipseb.r3000-linux.elf-entry.h +STUBS += mipseb.r3000-linux.elf-fold.h STUBS += mipsel.r3000-ps1.h STUBS += mipsel.r3000-linux.elf-entry.h STUBS += mipsel.r3000-linux.elf-fold.h @@ -806,6 +808,51 @@ m68k-atari.tos.h : $(srcdir)/src/$$T.S $(call tc,bin2h-c) tmp/$T.bin $@ +# /*********************************************************************** +# // mipseb.r3000-linux.elf +# ************************************************************************/ + +# BUG: generate bad data [byte-swapped] using 'mipsel', but at least 'make' completes. +mipseb.r3000-linux.elf%.h : tc_list = mipseb.r3000-linux.elf default +mipseb.r3000-linux.elf%.h : tc_bfdname = elf32-littlemips + +tc.mipseb.r3000-linux.elf.as = mipsel-elf-as-20060406 -O -mno-pdr +tc.mipseb.r3000-linux.elf.gcc = mipsel-linux-gcc-4.1.1 -meb -march=r3000 -mno-abicalls -mabi=eabi -G0 -nostdinc -MMD -MT $@ +tc.mipseb.r3000-linux.elf.gcc += -fno-exceptions -fno-asynchronous-unwind-tables +tc.mipseb.r3000-linux.elf.gcc += -Wall -W -Wcast-align -Wcast-qual -Wstrict-prototypes -Wwrite-strings -Werror + +mipseb.r3000-linux.elf-entry.h : $(srcdir)/src/$$T.S +ifeq (1,1) + # info: we really need as-2.17 here + $(call tc,pp-as) -D_TARGET_LINUX_ $< -o - | $(RTRIM) > tmp/$T.i + $(call tc,as) tmp/$T.i -o tmp/$T.bin + $(call tc,gpp_mkdep) --mode=c --MMD=$@ $< --MF=tmp/$T.d +else + # info: as-2.16.1 as used by gcc-4.1.1 does _not_ work + $(call tc,gcc) -c -D_TARGET_LINUX_ -Wa,-O,-mno-pdr $< -o tmp/$T.bin +endif + $(call tc,f-embed_objinfo,tmp/$T.bin) + $(call tc,bin2h-c) tmp/$T.bin $@ + +mipseb.r3000-linux.elf-fold.h : tmp/$$T.o tmp/mipseb.r3000-linux.elf-main.o $(srcdir)/src/$$T.lds + $(call tc,ld) --strip-all -T $(srcdir)/src/$T.lds -Map tmp/$T.map $(filter %.o,$^) -o tmp/$T.bin + $(call tc,f-objstrip,tmp/$T.bin) + $(call tc,sstrip) tmp/$T.bin + $(call tc,bin2h) tmp/$T.bin $@ + +tmp/mipseb.r3000-linux.elf-fold.o : $(srcdir)/src/$$T.S + $(call tc,gcc) -c -D_TARGET_LINUX_ $< -o $@ + $(call tc,f-objstrip,$@) + +tmp/mipseb.r3000-linux.elf-main.o : $(srcdir)/src/$$T.c + $(call tc,gcc) -S -Os -MF tmp/$T.d $< -o - | $(RTRIM) > tmp/$T.i + sed -e 's/ j[ ][ ]*$$L/ b $$L/' \ + -e 's/ jal[ ][ ]*\([^\$$]\)/ bal \1/' < tmp/$T.i > tmp/$T.s + $(call tc,gcc) -c -Wa,-O,-mno-pdr tmp/$T.s -o $@ + $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm + + # /*********************************************************************** # // mipsel.r3000-ps1 # ************************************************************************/ diff --git a/src/stub/src/mipseb.r3000-linux.elf-entry.S b/src/stub/src/mipseb.r3000-linux.elf-entry.S new file mode 100644 index 00000000..aa48db4f --- /dev/null +++ b/src/stub/src/mipseb.r3000-linux.elf-entry.S @@ -0,0 +1 @@ +#include "mipsel.r3000-linux.elf-entry.S" diff --git a/src/stub/src/mipseb.r3000-linux.elf-fold.S b/src/stub/src/mipseb.r3000-linux.elf-fold.S new file mode 100644 index 00000000..80e9ca86 --- /dev/null +++ b/src/stub/src/mipseb.r3000-linux.elf-fold.S @@ -0,0 +1 @@ +#include "mipsel.r3000-linux.elf-fold.S" diff --git a/src/stub/src/mipseb.r3000-linux.elf-fold.lds b/src/stub/src/mipseb.r3000-linux.elf-fold.lds new file mode 100644 index 00000000..b3468eac --- /dev/null +++ b/src/stub/src/mipseb.r3000-linux.elf-fold.lds @@ -0,0 +1,49 @@ +/* mipsel.r3000-linux.elf-fold.lds -- + + This file is part of the UPX executable compressor. + + Copyright (C) 2000-2007 John F. Reiser + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + + John F. Reiser + + */ + + +/* 2007-11-12: BUG: should be elf32-bigmips, but that does not work yet */ +OUTPUT_FORMAT("elf32-littlemips", "elf32-littlemips", "elf32-littlemips") +OUTPUT_ARCH(mips) +/*ENTRY(_start)*/ +PHDRS +{ + text PT_LOAD FILEHDR PHDRS ; + data PT_LOAD ; /* for setting brk(0) */ +} +SECTIONS +{ + . = 0x00100000 + SIZEOF_HEADERS + 12; /* 12==sizeof(l_info) */ + .text : { + *(.text) + *(.data) + } : text + .data : { + } : data +} diff --git a/src/stub/src/mipseb.r3000-linux.elf-main.c b/src/stub/src/mipseb.r3000-linux.elf-main.c new file mode 100644 index 00000000..5f0b0433 --- /dev/null +++ b/src/stub/src/mipseb.r3000-linux.elf-main.c @@ -0,0 +1 @@ +#include "i386-linux.elf-main.c"