MIPSEB implementation [still broken because no big-endian tools]
This commit is contained in:
@@ -297,6 +297,11 @@ void PackLinuxElf32mipsel::updateLoader(OutputFile *fo)
|
|||||||
ARM_updateLoader(fo); // not ARM specific; (no 32-bit immediates)
|
ARM_updateLoader(fo); // not ARM specific; (no 32-bit immediates)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackLinuxElf32mipseb::updateLoader(OutputFile *fo)
|
||||||
|
{
|
||||||
|
ARM_updateLoader(fo); // not ARM specific; (no 32-bit immediates)
|
||||||
|
}
|
||||||
|
|
||||||
void PackLinuxElf32::updateLoader(OutputFile *fo)
|
void PackLinuxElf32::updateLoader(OutputFile *fo)
|
||||||
{
|
{
|
||||||
set_native32(&elfout.ehdr.e_entry, fo->getBytesWritten() +
|
set_native32(&elfout.ehdr.e_entry, fo->getBytesWritten() +
|
||||||
@@ -754,6 +759,19 @@ PackLinuxElf32mipsel::buildLoader(Filter const *ft)
|
|||||||
stub_mipsel_r3000_linux_elf_fold, sizeof(stub_mipsel_r3000_linux_elf_fold), ft);
|
stub_mipsel_r3000_linux_elf_fold, sizeof(stub_mipsel_r3000_linux_elf_fold), ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const
|
||||||
|
#include "stub/mipseb.r3000-linux.elf-entry.h"
|
||||||
|
static const
|
||||||
|
#include "stub/mipseb.r3000-linux.elf-fold.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
PackLinuxElf32mipseb::buildLoader(Filter const *ft)
|
||||||
|
{
|
||||||
|
buildLinuxLoader(
|
||||||
|
stub_mipseb_r3000_linux_elf_entry, sizeof(stub_mipseb_r3000_linux_elf_entry),
|
||||||
|
stub_mipseb_r3000_linux_elf_fold, sizeof(stub_mipseb_r3000_linux_elf_fold), ft);
|
||||||
|
}
|
||||||
|
|
||||||
static const
|
static const
|
||||||
#include "stub/powerpc-linux.elf-entry.h"
|
#include "stub/powerpc-linux.elf-entry.h"
|
||||||
static const
|
static const
|
||||||
@@ -1294,6 +1312,14 @@ void PackLinuxElf32mipsel::pack1(OutputFile *fo, Filter &ft)
|
|||||||
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackLinuxElf32mipseb::pack1(OutputFile *fo, Filter &ft)
|
||||||
|
{
|
||||||
|
super::pack1(fo, ft);
|
||||||
|
cprElfHdr3 h3;
|
||||||
|
memcpy(&h3, stub_mipseb_r3000_linux_elf_fold, sizeof(Elf32_Ehdr) + 2*sizeof(Elf32_Phdr));
|
||||||
|
generateElfHdr(fo, &h3, getbrk(phdri, get_native16(&ehdri.e_phnum)) );
|
||||||
|
}
|
||||||
|
|
||||||
void PackLinuxElf32ppc::pack1(OutputFile *fo, Filter &ft)
|
void PackLinuxElf32ppc::pack1(OutputFile *fo, Filter &ft)
|
||||||
{
|
{
|
||||||
super::pack1(fo, ft);
|
super::pack1(fo, ft);
|
||||||
@@ -1550,6 +1576,13 @@ PackLinuxElf32armLe::getFilters() const
|
|||||||
return ARM_getFilters(false);
|
return ARM_getFilters(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *
|
||||||
|
PackLinuxElf32mipseb::getFilters() const
|
||||||
|
{
|
||||||
|
static const int f_none[] = { FT_END };
|
||||||
|
return f_none;
|
||||||
|
}
|
||||||
|
|
||||||
const int *
|
const int *
|
||||||
PackLinuxElf32mipsel::getFilters() const
|
PackLinuxElf32mipsel::getFilters() const
|
||||||
{
|
{
|
||||||
@@ -1598,6 +1631,78 @@ void PackLinuxElf32armBe::defineSymbols(Filter const *ft)
|
|||||||
ARM_defineSymbols(ft);
|
ARM_defineSymbols(ft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackLinuxElf32mipseb::defineSymbols(Filter const * /*ft*/)
|
||||||
|
{
|
||||||
|
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
||||||
|
|
||||||
|
// We want to know if compressed data, plus stub, plus a couple pages,
|
||||||
|
// will fit below the uncompressed program in memory. But we don't
|
||||||
|
// know the final total compressed size yet, so use the uncompressed
|
||||||
|
// size (total over all PT_LOAD32) as an upper bound.
|
||||||
|
unsigned len = 0;
|
||||||
|
unsigned lo_va_user = ~0u; // infinity
|
||||||
|
for (int j= get_native16(&ehdri.e_phnum); --j>=0; ) {
|
||||||
|
if (PT_LOAD32 == get_native32(&phdri[j].p_type)) {
|
||||||
|
len += (unsigned)get_native32(&phdri[j].p_filesz);
|
||||||
|
unsigned const va = get_native32(&phdri[j].p_vaddr);
|
||||||
|
if (va < lo_va_user) {
|
||||||
|
lo_va_user = va;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lsize = /*getLoaderSize()*/ 64 * 1024; // XXX: upper bound; avoid circularity
|
||||||
|
unsigned lo_va_stub = get_native32(&elfout.phdr[0].p_vaddr);
|
||||||
|
unsigned adrc;
|
||||||
|
unsigned adrm;
|
||||||
|
unsigned adru;
|
||||||
|
unsigned adrx;
|
||||||
|
unsigned cntc;
|
||||||
|
unsigned lenm;
|
||||||
|
unsigned lenu;
|
||||||
|
len += (7&-lsize) + lsize;
|
||||||
|
bool const is_big = (lo_va_user < (lo_va_stub + len + 2*page_size));
|
||||||
|
if (is_big) {
|
||||||
|
set_native32( &elfout.ehdr.e_entry,
|
||||||
|
get_native32(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);
|
||||||
|
set_native32(&elfout.phdr[0].p_vaddr, lo_va_user);
|
||||||
|
set_native32(&elfout.phdr[0].p_paddr, lo_va_user);
|
||||||
|
lo_va_stub = lo_va_user;
|
||||||
|
adrc = lo_va_stub;
|
||||||
|
adrm = getbrk(phdri, get_native16(&ehdri.e_phnum));
|
||||||
|
adru = page_mask & (~page_mask + adrm); // round up to page boundary
|
||||||
|
adrx = adru + hlen;
|
||||||
|
lenm = page_size + len;
|
||||||
|
lenu = page_size + len;
|
||||||
|
cntc = len >> 3; // over-estimate; corrected at runtime
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
adrm = lo_va_stub + len;
|
||||||
|
adrc = adrm;
|
||||||
|
adru = lo_va_stub;
|
||||||
|
adrx = lo_va_stub + hlen;
|
||||||
|
lenm = page_size;
|
||||||
|
lenu = page_size + len;
|
||||||
|
cntc = 0;
|
||||||
|
}
|
||||||
|
adrm = page_mask & (~page_mask + adrm); // round up to page boundary
|
||||||
|
adrc = page_mask & (~page_mask + adrc); // round up to page boundary
|
||||||
|
|
||||||
|
linker->defineSymbol("ADRX", adrx); // compressed input for eXpansion
|
||||||
|
|
||||||
|
// For actual moving, we need the true count, which depends on sz_pack2
|
||||||
|
// and is not yet known. So the runtime stub detects "no move"
|
||||||
|
// if adrm==adrc, and otherwise uses actual sz_pack2 to compute cntc.
|
||||||
|
//linker->defineSymbol("CNTC", cntc); // count for copy
|
||||||
|
|
||||||
|
linker->defineSymbol("ADRC", adrc); // addr for copy
|
||||||
|
linker->defineSymbol("LENU", lenu); // len for unmap
|
||||||
|
linker->defineSymbol("ADRU", adru); // addr for unmap
|
||||||
|
linker->defineSymbol("LENM", lenm); // len for map
|
||||||
|
linker->defineSymbol("ADRM", adrm); // addr for map
|
||||||
|
|
||||||
|
//linker->dumpSymbols(); // debug
|
||||||
|
}
|
||||||
|
|
||||||
void PackLinuxElf32mipsel::defineSymbols(Filter const * /*ft*/)
|
void PackLinuxElf32mipsel::defineSymbols(Filter const * /*ft*/)
|
||||||
{
|
{
|
||||||
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);
|
||||||
@@ -2051,6 +2156,18 @@ PackLinuxElf32armLe::~PackLinuxElf32armLe()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PackLinuxElf32mipseb::PackLinuxElf32mipseb(InputFile *f) : super(f)
|
||||||
|
{
|
||||||
|
e_machine = Elf32_Ehdr::EM_MIPS;
|
||||||
|
ei_class = Elf32_Ehdr::ELFCLASS32;
|
||||||
|
ei_data = Elf32_Ehdr::ELFDATA2MSB;
|
||||||
|
ei_osabi = Elf32_Ehdr::ELFOSABI_LINUX;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackLinuxElf32mipseb::~PackLinuxElf32mipseb()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
PackLinuxElf32mipsel::PackLinuxElf32mipsel(InputFile *f) : super(f)
|
PackLinuxElf32mipsel::PackLinuxElf32mipsel(InputFile *f) : super(f)
|
||||||
{
|
{
|
||||||
e_machine = Elf32_Ehdr::EM_MIPS;
|
e_machine = Elf32_Ehdr::EM_MIPS;
|
||||||
@@ -2068,6 +2185,11 @@ Linker* PackLinuxElf32armLe::newLinker() const
|
|||||||
return new ElfLinkerArmLE();
|
return new ElfLinkerArmLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker* PackLinuxElf32mipseb::newLinker() const
|
||||||
|
{
|
||||||
|
return new ElfLinkerMipsBE();
|
||||||
|
}
|
||||||
|
|
||||||
Linker* PackLinuxElf32mipsel::newLinker() const
|
Linker* PackLinuxElf32mipsel::newLinker() const
|
||||||
{
|
{
|
||||||
return new ElfLinkerMipsLE();
|
return new ElfLinkerMipsLE();
|
||||||
|
|||||||
@@ -465,6 +465,25 @@ protected:
|
|||||||
virtual void defineSymbols(Filter const *);
|
virtual void defineSymbols(Filter const *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PackLinuxElf32mipseb : public PackLinuxElf32Be
|
||||||
|
{
|
||||||
|
typedef PackLinuxElf32Be super;
|
||||||
|
public:
|
||||||
|
PackLinuxElf32mipseb(InputFile *f);
|
||||||
|
virtual ~PackLinuxElf32mipseb();
|
||||||
|
virtual int getFormat() const { return UPX_F_LINUX_ELF32_MIPSEB; }
|
||||||
|
virtual const char *getName() const { return "linux/mipseb"; }
|
||||||
|
virtual const char *getFullName(const options_t *) const { return "mipseb-linux.elf"; }
|
||||||
|
virtual const int *getFilters() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual Linker* newLinker() const;
|
||||||
|
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||||
|
virtual void buildLoader(const Filter *);
|
||||||
|
virtual void updateLoader(OutputFile *);
|
||||||
|
virtual void defineSymbols(Filter const *);
|
||||||
|
};
|
||||||
|
|
||||||
class PackLinuxElf32mipsel : public PackLinuxElf32Le
|
class PackLinuxElf32mipsel : public PackLinuxElf32Le
|
||||||
{
|
{
|
||||||
typedef PackLinuxElf32Le super;
|
typedef PackLinuxElf32Le super;
|
||||||
|
|||||||
Reference in New Issue
Block a user