src: clang-format various packers

This commit is contained in:
Markus F.X.J. Oberhumer
2022-11-26 17:45:25 +01:00
parent 93c6496ba8
commit 9f5d67e27c
13 changed files with 863 additions and 1275 deletions
+69 -129
View File
@@ -25,7 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com>
*/
#include "conf.h"
#include "file.h"
#include "filter.h"
@@ -33,19 +32,16 @@
#include "p_djgpp2.h"
#include "linker.h"
static const
static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i386-dos32.djgpp2.h"
static const
static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i386-dos32.djgpp2-stubify.h"
/*************************************************************************
//
**************************************************************************/
PackDjgpp2::PackDjgpp2(InputFile *f) :
super(f), coff_offset(0)
{
PackDjgpp2::PackDjgpp2(InputFile *f) : super(f), coff_offset(0) {
bele = &N_BELE_RTP::le_policy;
COMPILE_TIME_ASSERT(sizeof(external_scnhdr_t) == 40)
COMPILE_TIME_ASSERT(sizeof(coff_header_t) == 0xa8)
@@ -53,60 +49,38 @@ PackDjgpp2::PackDjgpp2(InputFile *f) :
COMPILE_TIME_ASSERT_ALIGNED1(coff_header_t)
COMPILE_TIME_ASSERT(sizeof(stub_i386_dos32_djgpp2_stubify) == 2048)
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_ADLER32 == 0xbf689ba8)
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
COMPILE_TIME_ASSERT(STUB_I386_DOS32_DJGPP2_STUBIFY_CRC32 == 0x2ae982b2)
// printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
// assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
}
const int *PackDjgpp2::getCompressionMethods(int method, int level) const
{
const int *PackDjgpp2::getCompressionMethods(int method, int level) const {
return Packer::getDefaultCompressionMethods_le32(method, level);
}
const int *PackDjgpp2::getFilters() const
{
static const int filters[] = {
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
const int *PackDjgpp2::getFilters() const {
static const int filters[] = {0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14,
0x11, FT_ULTRA_BRUTE, 0x25, 0x15, 0x12, FT_END};
return filters;
}
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
unsigned range,
unsigned upper_limit) const
{
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf, unsigned range,
unsigned upper_limit) const {
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
o = (o + 0x3ff) &~ 0x1ff;
o = (o + 0x3ff) & ~0x1ff;
return o;
}
Linker *PackDjgpp2::newLinker() const { return new ElfLinkerX86; }
Linker* PackDjgpp2::newLinker() const
{
return new ElfLinkerX86;
}
void PackDjgpp2::buildLoader(const Filter *ft)
{
void PackDjgpp2::buildLoader(const Filter *ft) {
// prepare loader
initLoader(stub_i386_dos32_djgpp2, sizeof(stub_i386_dos32_djgpp2));
addLoader("IDENTSTR,DJ2MAIN1",
ft->id ? "DJCALLT1" : "",
addLoader("IDENTSTR,DJ2MAIN1", ft->id ? "DJCALLT1" : "",
ph.first_offset_found == 1 ? "DJ2MAIN2" : "",
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
getDecompressorSections(),
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
"DJ2BSS00",
nullptr
);
if (ft->id)
{
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "", getDecompressorSections(),
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "", "DJ2BSS00", nullptr);
if (ft->id) {
assert(ft->calls > 0);
addLoader("DJCALLT2", nullptr);
addFilter32(ft->id);
@@ -114,32 +88,24 @@ void PackDjgpp2::buildLoader(const Filter *ft)
addLoader("DJRETURN,+40C,UPX1HEAD", nullptr);
}
/*************************************************************************
// util
**************************************************************************/
void PackDjgpp2::handleStub(OutputFile *fo)
{
if (fo && !opt->djgpp2_coff.coff)
{
if (coff_offset > 0)
{
void PackDjgpp2::handleStub(OutputFile *fo) {
if (fo && !opt->djgpp2_coff.coff) {
if (coff_offset > 0) {
// copy stub from exe
Packer::handleStub(fi, fo, coff_offset);
}
else
{
} else {
// "stubify" stub
info("Adding stub: %ld bytes", (long)sizeof(stub_i386_dos32_djgpp2_stubify));
info("Adding stub: %ld bytes", (long) sizeof(stub_i386_dos32_djgpp2_stubify));
fo->write(stub_i386_dos32_djgpp2_stubify, sizeof(stub_i386_dos32_djgpp2_stubify));
}
}
}
static bool is_dlm(InputFile *fi, unsigned coff_offset)
{
static bool is_dlm(InputFile *fi, unsigned coff_offset) {
unsigned char buf[4];
unsigned off;
@@ -153,14 +119,12 @@ static bool is_dlm(InputFile *fi, unsigned coff_offset)
fi->readx(buf, 4);
if (memcmp(buf, "DLMF", 4) == 0)
return true;
} catch (const IOException&) {
} catch (const IOException &) {
}
return false;
}
static void handle_allegropak(InputFile *fi, OutputFile *fo)
{
static void handle_allegropak(InputFile *fi, OutputFile *fo) {
unsigned char b[8];
int pfsize = 0;
@@ -169,80 +133,71 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
fi->readx(b, 8);
if (memcmp(b, "slh+", 4) != 0)
return;
pfsize = get_be32_signed(b+4);
pfsize = get_be32_signed(b + 4);
if (pfsize <= 8 || pfsize >= fi->st.st_size)
return;
fi->seek(-pfsize, SEEK_END);
} catch (const IOException&) {
} catch (const IOException &) {
return;
}
MemBuffer buf(0x4000);
while (pfsize > 0)
{
const int len = UPX_MIN(pfsize, (int)buf.getSize());
while (pfsize > 0) {
const int len = UPX_MIN(pfsize, (int) buf.getSize());
fi->readx(buf, len);
fo->write(buf, len);
pfsize -= len;
}
}
int PackDjgpp2::readFileHeader()
{
int PackDjgpp2::readFileHeader() {
unsigned char hdr[0x1c];
unsigned char magic[8];
fi->seek(0, SEEK_SET);
fi->readx(hdr, sizeof(hdr));
if (get_le16(hdr) == 0x5a4d) // MZ exe signature, stubbed?
if (get_le16(hdr) == 0x5a4d) // MZ exe signature, stubbed?
{
coff_offset = 512 * get_le16(hdr+4);
if (get_le16(hdr+2) != 0)
coff_offset += get_le16(hdr+2) - 512;
coff_offset = 512 * get_le16(hdr + 4);
if (get_le16(hdr + 2) != 0)
coff_offset += get_le16(hdr + 2) - 512;
fi->seek(512, SEEK_SET);
fi->readx(magic, 8);
if (memcmp("go32stub", magic, 8) != 0)
return 0; // not V2 image
return 0; // not V2 image
fi->seek(coff_offset, SEEK_SET);
if (fi->read(&coff_hdr, sizeof(coff_hdr)) != sizeof(coff_hdr))
throwCantPack("skipping djgpp symlink");
}
else
{
} else {
fi->seek(coff_offset, SEEK_SET);
fi->readx(&coff_hdr, 0xa8);
}
if (coff_hdr.f_magic != 0x014c) // I386MAGIC
if (coff_hdr.f_magic != 0x014c) // I386MAGIC
return 0;
if ((coff_hdr.f_flags & 2) == 0) // F_EXEC - COFF executable
if ((coff_hdr.f_flags & 2) == 0) // F_EXEC - COFF executable
return 0;
if (coff_hdr.a_magic != 0413) // ZMAGIC - demand load format
if (coff_hdr.a_magic != 0413) // ZMAGIC - demand load format
return 0;
// FIXME: check for Linux etc.
text = coff_hdr.sh;
data = text + 1;
bss = data + 1;
bss = data + 1;
return UPX_F_DJGPP2_COFF;
}
// "strip" debug info
void PackDjgpp2::stripDebug()
{
void PackDjgpp2::stripDebug() {
coff_hdr.f_symptr = 0;
coff_hdr.f_nsyms = 0;
coff_hdr.f_flags = 0x10f; // 0x100: "32 bit machine: LSB first"
coff_hdr.f_flags = 0x10f; // 0x100: "32 bit machine: LSB first"
memset(text->misc, 0, 12);
}
/*************************************************************************
//
**************************************************************************/
bool PackDjgpp2::canPack()
{
bool PackDjgpp2::canPack() {
if (!readFileHeader())
return false;
if (is_dlm(fi, coff_offset))
@@ -253,38 +208,32 @@ bool PackDjgpp2::canPack()
throwAlreadyPacked();
// Check for gap in vaddr between text and data, or between data and bss.
if (text->vaddr + text->size != data->vaddr
|| data->vaddr + data->size != bss->vaddr)
{
if (text->vaddr + text->size != data->vaddr || data->vaddr + data->size != bss->vaddr) {
// "Non-standard" layout of text,data,bss: not contiguous in vaddr.
// But should be OK if no overlap.
// Check for no overlap of text and data:
// neither by vaddr, nor by image data
if (text->vaddr + text->size <= data->vaddr &&
data->scnptr - text->scnptr <= data->vaddr - text->vaddr)
{
data->scnptr - text->scnptr <= data->vaddr - text->vaddr) {
// Examples: Quake1; FreePascal(DOS) install.exe (github-issue45)
// Hack: enlarge text image data to eliminate the gap.
text->size = coff_hdr.a_tsize = data->scnptr - text->scnptr;
// But complain if this causes overlap in vaddr
if (text->vaddr + text->size > data->vaddr)
throwAlreadyPacked();
}
else
} else
throwAlreadyPacked();
}
// FIXME: check for Linux etc.
return true;
}
/*************************************************************************
//
**************************************************************************/
void PackDjgpp2::pack(OutputFile *fo)
{
void PackDjgpp2::pack(OutputFile *fo) {
handleStub(fo);
// patch coff header #1: "strip" debug info
@@ -302,7 +251,7 @@ void PackDjgpp2::pack(OutputFile *fo)
obuf.allocForCompression(usize);
fi->seek(coff_offset, SEEK_SET);
fi->readx(ibuf, hdrsize); // orig. coff header
fi->readx(ibuf, hdrsize); // orig. coff header
fi->seek(coff_offset + tpos, SEEK_SET);
fi->readx(ibuf + hdrsize, size);
@@ -313,7 +262,8 @@ void PackDjgpp2::pack(OutputFile *fo)
ft.buf_len = usize - data->size;
ft.addvalue = text->vaddr - hdrsize;
// compress
upx_compress_config_t cconf; cconf.reset();
upx_compress_config_t cconf;
cconf.reset();
// limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
compressWithFilters(&ft, 512, &cconf);
@@ -321,24 +271,25 @@ void PackDjgpp2::pack(OutputFile *fo)
// patch coff header #2
const unsigned lsize = getLoaderSize();
assert(lsize % 4 == 0);
text->size = lsize; // new size of .text
data->size = ph.c_len; // new size of .data
text->size = lsize; // new size of .text
data->size = ph.c_len; // new size of .data
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
stack = ALIGN_UP(stack, 16u);
if (bss->size < stack) // give it a .bss
if (bss->size < stack) // give it a .bss
bss->size = stack;
text->scnptr = sizeof(coff_hdr);
data->scnptr = text->scnptr + text->size;
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size +
ph.overlap_overhead - 0x200;
coff_hdr.f_nscns = 3;
linker->defineSymbol("original_entry", coff_hdr.a_entry);
linker->defineSymbol("length_of_bss", ph.overlap_overhead / 4);
defineDecompressorSymbols();
// Just need no overlap; non-contiguous (gap length > 0)) is OK
assert(bss->vaddr >= ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
assert(bss->vaddr >= ((size + 0x1ff) & ~0x1ff) + (text->vaddr & ~0x1ff));
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
linker->defineSymbol("start_of_compressed", data->vaddr);
@@ -356,7 +307,7 @@ void PackDjgpp2::pack(OutputFile *fo)
bss->size -= ph.overlap_overhead;
// because of a feature (bug?) in stub.asm we need some padding
memcpy(obuf+data->size, "UPX", 3);
memcpy(obuf + data->size, "UPX", 3);
data->size = ALIGN_UP(data->size, 4u);
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
@@ -391,13 +342,11 @@ void PackDjgpp2::pack(OutputFile *fo)
throwNotCompressible();
}
/*************************************************************************
//
**************************************************************************/
int PackDjgpp2::canUnpack()
{
int PackDjgpp2::canUnpack() {
if (!readFileHeader())
return false;
if (is_dlm(fi, coff_offset))
@@ -406,13 +355,11 @@ int PackDjgpp2::canUnpack()
return readPackHeader(4096) ? 1 : -1;
}
/*************************************************************************
//
**************************************************************************/
void PackDjgpp2::unpack(OutputFile *fo)
{
void PackDjgpp2::unpack(OutputFile *fo) {
handleStub(fo);
ibuf.alloc(ph.c_len);
@@ -424,27 +371,24 @@ void PackDjgpp2::unpack(OutputFile *fo)
// decompress
decompress(ibuf, obuf);
coff_header_t *chdr = (coff_header_t*) obuf.getVoidPtr();
coff_header_t *chdr = (coff_header_t *) obuf.getVoidPtr();
text = chdr->sh;
data = text + 1;
const unsigned hdrsize = 20 + 28
+ sizeof(external_scnhdr_t) * chdr->f_nscns;
const unsigned hdrsize = 20 + 28 + sizeof(external_scnhdr_t) * chdr->f_nscns;
unsigned addvalue;
if (ph.version >= 14)
addvalue = text->vaddr - hdrsize;
else
addvalue = text->vaddr &~ 0x1ff; // for old versions
addvalue = text->vaddr & ~0x1ff; // for old versions
// unfilter
if (ph.filter)
{
if (ph.filter) {
Filter ft(ph.level);
ft.init(ph.filter, addvalue);
ft.cto = (unsigned char) ph.filter_cto;
if (ph.version < 11)
{
if (ph.version < 11) {
unsigned char ctobuf[4];
fi->readx(ctobuf, 4);
ft.cto = (unsigned char) (get_le32(ctobuf) >> 24);
@@ -452,17 +396,14 @@ void PackDjgpp2::unpack(OutputFile *fo)
ft.unfilter(obuf, ph.u_len - data->size);
}
if (ph.version < 14)
{
if (ph.version < 14) {
// fixup for the aligning bug in strip 2.8+
text->scnptr &= 0x1ff;
data->scnptr = text->scnptr + text->size;
// write decompressed file
if (fo)
fo->write(obuf, ph.u_len);
}
else
{
} else {
// write the header
// some padding might be required between the end
// of the header and the start of the .text section
@@ -470,8 +411,7 @@ void PackDjgpp2::unpack(OutputFile *fo)
const unsigned padding = text->scnptr - hdrsize;
ibuf.clear(0, padding);
if (fo)
{
if (fo) {
fo->write(obuf, hdrsize);
fo->write(ibuf, padding);
fo->write(obuf + hdrsize, ph.u_len - hdrsize);