From 147acf4b57e74fe3b08adcd11b8267863d9f9a98 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sat, 17 Oct 2009 21:55:03 -0700 Subject: [PATCH] Compress shared library for amd64-linux. --- src/p_lx_elf.cpp | 372 +++++++++-- src/p_lx_elf.h | 22 +- src/stub/Makefile | 14 + src/stub/amd64-linux.shlib-init.h | 636 +++++++++++++++++++ src/stub/src/amd64-linux.shlib-init.S | 411 ++++++++++++ src/stub/tmp/amd64-linux.shlib-init.bin.dump | 57 ++ 6 files changed, 1446 insertions(+), 66 deletions(-) create mode 100644 src/stub/amd64-linux.shlib-init.h create mode 100644 src/stub/src/amd64-linux.shlib-init.S create mode 100644 src/stub/tmp/amd64-linux.shlib-init.bin.dump diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 4c88954b..6e6bb7b0 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -161,28 +161,25 @@ void PackLinuxElf::pack3(OutputFile *fo, Filter &ft) unsigned len = fo->getBytesWritten(); fo->write(&zero, 3& -len); // ALIGN_UP 0 mod 4 len += (3& -len); // 0 mod 4 + unsigned const t = 4 ^ (4 & len) ^ ((!!xct_off)<<2); // 0 or 4 fo->write(&zero, t); len += t; + + set_te32(&disp, len); // distance back to beginning (detect dynamic reloc) + fo->write(&disp, sizeof(disp)); + len += sizeof(disp); + if (xct_off) { - set_te32(&disp, xct_va - xct_off + len); // to detect dynamic reloc + set_te32(&disp, elf_unsigned_dynamic(Elf32_Dyn::DT_INIT) - load_va); fo->write(&disp, sizeof(disp)); len += sizeof(disp); - set_te32(&disp, elf_unsigned_dynamic(Elf32_Dyn::DT_INIT)); + set_te32(&disp, hatch_off); fo->write(&disp, sizeof(disp)); len += sizeof(disp); - set_te32(&disp, hatch_va); - fo->write(&disp, sizeof(disp)); - len += sizeof(disp); - - set_te32(&disp, xct_va); - fo->write(&disp, sizeof(disp)); - len += sizeof(disp); - } - else { - set_te32(&disp, len - xct_off); // distance back to beginning + set_te32(&disp, xct_off); fo->write(&disp, sizeof(disp)); len += sizeof(disp); } @@ -194,7 +191,8 @@ void PackLinuxElf::pack3(OutputFile *fo, Filter &ft) void PackLinuxElf32::pack3(OutputFile *fo, Filter &ft) { super::pack3(fo, ft); - set_te32(&elfout.phdr[0].p_filesz, sz_pack2); + set_te32(&elfout.phdr[0].p_filesz, sz_pack2 + lsize); + set_te32(&elfout.phdr[0].p_memsz, sz_pack2 + lsize); if (0!=xct_off) { // shared library Elf32_Phdr *phdr = phdri; unsigned off = sz_pack2; @@ -229,8 +227,8 @@ void PackLinuxElf32::pack3(OutputFile *fo, Filter &ft) } else { // Change length of first PT_LOAD. va_init += get_te32(&phdr->p_vaddr); - set_te32(&phdr->p_filesz, sz_pack2); - set_te32(&phdr->p_memsz, sz_pack2); // FIXME + set_te32(&phdr->p_filesz, sz_pack2 + lsize); + set_te32(&phdr->p_memsz, sz_pack2 + lsize); // FIXME } continue; // all done with this PT_LOAD } @@ -270,7 +268,80 @@ void PackLinuxElf32::pack3(OutputFile *fo, Filter &ft) void PackLinuxElf64::pack3(OutputFile *fo, Filter &ft) { super::pack3(fo, ft); - set_te64(&elfout.phdr[0].p_filesz, sz_pack2); + set_te64(&elfout.phdr[0].p_filesz, sz_pack2 + lsize); + set_te64(&elfout.phdr[0].p_memsz, sz_pack2 + lsize); + if (0!=xct_off) { // shared library + Elf64_Phdr *phdr = phdri; + unsigned off = sz_pack2; + unsigned off_init = 0; // where in file + uint64_t va_init = sz_pack2; // virtual address + uint64_t rel = 0; + uint64_t old_dtinit = 0; + for (int j = e_phnum; --j>=0; ++phdr) { + uint64_t const len = get_te64(&phdr->p_filesz); + uint64_t const ioff = get_te64(&phdr->p_offset); + uint64_t const align= get_te64(&phdr->p_align); + unsigned const type = get_te32(&phdr->p_type); + if (phdr->PT_INTERP==type) { // FIXME + // Rotate to highest position, so it can be lopped + // by decrementing e_phnum. FIXME: must relocate .p_offset, + // and ::pack4 must rewrite it to the output, too. + memcpy((unsigned char *)ibuf, phdr, sizeof(*phdr)); + memcpy(phdr, 1+phdr, j * sizeof(*phdr)); + memcpy(&phdr[j], (unsigned char *)ibuf, sizeof(*phdr)); + --phdr; + set_te16(&ehdri.e_phnum, --e_phnum); + continue; + } + if (phdr->PT_LOAD==type) { + if (xct_off < ioff) { // Slide up non-first PT_LOAD. + fi->seek(ioff, SEEK_SET); + fi->readx(ibuf, len); + // Unfortunately .p_align typically is 2MB. FIXME + off += (align-1) & (ioff - off); + fo->seek(off, SEEK_SET); + fo->write(ibuf, len); + rel = off - ioff; + set_te64(&phdr->p_offset, rel + ioff); + } + else { // Change length of first PT_LOAD. + va_init += get_te64(&phdr->p_vaddr); + set_te64(&phdr->p_filesz, sz_pack2 + lsize); + set_te64(&phdr->p_memsz, sz_pack2 + lsize); // FIXME + } + continue; // all done with this PT_LOAD + } + // Compute new offset of &DT_INIT.d_val. + if (phdr->PT_DYNAMIC==type) { + off_init = rel + ioff; + fi->seek(ioff, SEEK_SET); + fi->read(ibuf, len); + Elf64_Dyn *dyn = (Elf64_Dyn *)(void *)ibuf; + for (int j2 = len; j2 > 0; ++dyn, j2 -= sizeof(*dyn)) { + if (dyn->DT_INIT==get_te64(&dyn->d_tag)) { + old_dtinit = dyn->d_val; + unsigned const t = (unsigned char *)&dyn->d_val - + (unsigned char *)ibuf; + off_init += t; + break; + } + } + // fall through to relocate .p_offset + } + if (xct_off < ioff) + set_te64(&phdr->p_offset, rel + ioff); + } + if (off_init) { // change DT_INIT.d_val + fo->seek(off_init, SEEK_SET); + uint64_t word; set_te64(&word, va_init); + fo->rewrite(&word, sizeof(word)); + fo->seek(0, SEEK_END); + } + ehdri.e_shnum = 0; + ehdri.e_shoff = old_dtinit; // easy to find for unpacking + //ehdri.e_shentsize = 0; + //ehdri.e_shstrndx = 0; + } } void @@ -297,7 +368,7 @@ void PackLinuxElf::defineSymbols(Filter const *) PackLinuxElf32::PackLinuxElf32(InputFile *f) : super(f), phdri(NULL), shdri(NULL), page_mask(~0u<seek(0, SEEK_SET); f->readx(&ehdri, sizeof(ehdri)); @@ -631,7 +704,7 @@ PackLinuxElf64::buildLinuxLoader( } unsigned char const *const uncLoader = fold_hdrlen + fold; - h.sz_cpr = MemBuffer::getSizeForCompression(h.sz_unc); + h.sz_cpr = MemBuffer::getSizeForCompression(h.sz_unc + (0==h.sz_unc)); unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_cpr]; if (0 < szfold) { int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &h.sz_cpr, @@ -657,6 +730,9 @@ PackLinuxElf64::buildLinuxLoader( void PackLinuxElf64amd::defineSymbols(Filter const *) { + if (0!=xct_va) { // is shared lib + return; // no symbols needed + } 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, @@ -907,10 +983,18 @@ static const #include "stub/amd64-linux.elf-entry.h" static const #include "stub/amd64-linux.elf-fold.h" +static const +#include "stub/amd64-linux.shlib-init.h" void PackLinuxElf64amd::buildLoader(const Filter *ft) { + if (0!=xct_off) { // shared library + buildLinuxLoader( + stub_amd64_linux_shlib_init, sizeof(stub_amd64_linux_shlib_init), + NULL, 0, ft ); + return; + } buildLinuxLoader( stub_amd64_linux_elf_entry, sizeof(stub_amd64_linux_elf_entry), stub_amd64_linux_elf_fold, sizeof(stub_amd64_linux_elf_fold), ft); @@ -944,12 +1028,32 @@ Elf32_Shdr const *PackLinuxElf32::elf_find_section_type( return 0; } +Elf64_Shdr const *PackLinuxElf64::elf_find_section_type( + unsigned const type +) const +{ + Elf64_Shdr const *shdr = shdri; + int j = n_elf_shnum; + for (; 0 <=--j; ++shdr) { + if (type==get_te32(&shdr->sh_type)) { + return shdr; + } + } + return 0; +} + static unsigned umin(unsigned a, unsigned b) { return (a < b) ? a : b; } +static uint64_t +umin64(uint64_t a, uint64_t b) +{ + return (a < b) ? a : b; +} + bool PackLinuxElf32::canPack() { union { @@ -980,7 +1084,6 @@ bool PackLinuxElf32::canPack() } unsigned osabi0 = u.buf[Elf32_Ehdr::EI_OSABI]; - unsigned va_load = 0; // The first PT_LOAD32 must cover the beginning of the file (0==p_offset). Elf32_Phdr const *phdr = (Elf32_Phdr const *)(u.buf + e_phoff); for (unsigned j=0; j < e_phnum; ++phdr, ++j) { @@ -993,7 +1096,7 @@ bool PackLinuxElf32::canPack() throwCantPack("invalid Phdr p_offset; try '--force-execve'"); return false; } - va_load = phdr->p_vaddr; + load_va = get_te32(&phdr->p_vaddr); exetype = 1; } if (Elf32_Ehdr::ELFOSABI_NONE==osabi0 // Still seems to be generic. @@ -1121,11 +1224,11 @@ bool PackLinuxElf32::canPack() goto abandon; } for ((shdr= shdri), (j= n_elf_shnum); --j>=0; ++shdr) { - if ( shdr->sh_addr==va_gash - || (shdr->sh_addr==va_hash && 0==va_gash) ) { - shdr= &shdri[shdr->sh_link]; // the associated SHT_SYMTAB + unsigned const sh_addr = get_te32(&shdr->sh_addr); + if ( sh_addr==va_gash + || (sh_addr==va_hash && 0==va_gash) ) { + shdr= &shdri[get_te32(&shdr->sh_link)]; // the associated SHT_SYMTAB hatch_off = (char *)&ehdri.e_ident[12] - (char *)&ehdri; - hatch_va = hatch_off + va_load; break; } } @@ -1173,6 +1276,7 @@ PackLinuxElf64amd::canPack() throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'"); return false; } + acc_uint64l_t const e_shoff = get_te64(&ehdr->e_shoff); acc_uint64l_t const e_phoff = get_te64(&ehdr->e_phoff); if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'"); @@ -1190,11 +1294,125 @@ PackLinuxElf64amd::canPack() // throwCantPack("invalid Phdr p_offset; try '--force-execve'"); // return false; //} + load_va = get_te64(&phdr->p_vaddr); exetype = 1; break; } } + // We want to compress position-independent executable (gcc -pie) + // main programs, but compressing a shared library must be avoided + // because the result is no longer usable. In theory, there is no way + // to tell them apart: both are just ET_DYN. Also in theory, + // neither the presence nor the absence of any particular symbol name + // can be used to tell them apart; there are counterexamples. + // However, we will use the following heuristic suggested by + // Peter S. Mazinger September 2005: + // If a ET_DYN has __libc_start_main as a global undefined symbol, + // then the file is a position-independent executable main program + // (that depends on libc.so.6) and is eligible to be compressed. + // Otherwise (no __libc_start_main as global undefined): skip it. + // Also allow __uClibc_main and __uClibc_start_main . + if (Elf32_Ehdr::ET_DYN==get_te16(&ehdr->e_type)) { + // The DT_STRTAB has no designated length. Read the whole file. + file_image = new char[file_size]; + fi->seek(0, SEEK_SET); + fi->readx(file_image, file_size); + memcpy(&ehdri, ehdr, sizeof(Elf32_Ehdr)); + phdri= (Elf64_Phdr *)(e_phoff + file_image); // do not free() !! + shdri= (Elf64_Shdr const *)(e_shoff + file_image); // do not free() !! + + n_elf_shnum = get_te16(&ehdr->e_shnum); + //sec_strndx = &shdri[ehdr->e_shstrndx]; + //shstrtab = (char const *)(sec_strndx->sh_offset + file_image); + sec_dynsym = elf_find_section_type(Elf64_Shdr::SHT_DYNSYM); + if (sec_dynsym) + sec_dynstr = get_te32(&sec_dynsym->sh_link) + shdri; + + int j= e_phnum; + phdr= phdri; + for (; --j>=0; ++phdr) + if (Elf64_Phdr::PT_DYNAMIC==get_te32(&phdr->p_type)) { + dynseg= (Elf64_Dyn const *)(get_te32(&phdr->p_offset) + file_image); + break; + } + // elf_find_dynamic() returns 0 if 0==dynseg. + dynstr= (char const *)elf_find_dynamic(Elf64_Dyn::DT_STRTAB); + dynsym= (Elf64_Sym const *)elf_find_dynamic(Elf64_Dyn::DT_SYMTAB); + + // Modified 2009-10-10 to detect a ProgramLinkageTable relocation + // which references the symbol, because DT_GNU_HASH contains only + // defined symbols, and there might be no DT_HASH. + + Elf64_Rela const * + jmprela= (Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_JMPREL); + for ( int sz = elf_unsigned_dynamic(Elf64_Dyn::DT_PLTRELSZ); + 0 < sz; + (sz -= sizeof(Elf64_Rela)), ++jmprela + ) { + unsigned const symnum = get_te64(&jmprela->r_info) >> 32; + char const *const symnam = get_te32(&dynsym[symnum].st_name) + dynstr; + if (0==strcmp(symnam, "__libc_start_main") + || 0==strcmp(symnam, "__uClibc_main") + || 0==strcmp(symnam, "__uClibc_start_main")) + goto proceed; + } + + // Heuristic HACK for shared libraries (compare Darwin (MacOS) Dylib.) + // If there is an existing DT_INIT, and if everything that the dynamic + // linker ld-linux needs to perform relocations before calling DT_INIT + // resides below the first SHT_EXECINSTR Section in one PT_LOAD, then + // compress from the first executable Section to the end of that PT_LOAD. + // We must not alter anything that ld-linux might touch before it calls + // the DT_INIT function. + // + // Obviously this hack requires that the linker script put pieces + // into good positions when building the original shared library, + // and also requires ld-linux to behave. + + if (elf_find_dynamic(Elf64_Dyn::DT_INIT)) { + Elf64_Shdr const *shdr = shdri; + xct_va = ~0ull; + for (j= n_elf_shnum; --j>=0; ++shdr) { + if (Elf64_Shdr::SHF_EXECINSTR & get_te32(&shdr->sh_flags)) { + xct_va = umin64(xct_va, get_te64(&shdr->sh_addr)); + } + } + // Rely on 0==elf_unsigned_dynamic(tag) if no such tag. + uint64_t const va_gash = elf_unsigned_dynamic(Elf64_Dyn::DT_GNU_HASH); + uint64_t const va_hash = elf_unsigned_dynamic(Elf64_Dyn::DT_HASH); + if (xct_va < va_gash || (0==va_gash && xct_va < va_hash) + || xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_STRTAB) + || xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_SYMTAB) + || xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_REL) + || xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_RELA) + || xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_JMPREL) + || xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERDEF) + || xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERSYM) + || xct_va < elf_unsigned_dynamic(Elf64_Dyn::DT_VERNEEDED) ) { + goto abandon; + } + for ((shdr= shdri), (j= n_elf_shnum); --j>=0; ++shdr) { + uint64_t const sh_addr = get_te64(&shdr->sh_addr); + if ( sh_addr==va_gash + || (sh_addr==va_hash && 0==va_gash) ) { + shdr= &shdri[get_te32(&shdr->sh_link)]; // the associated SHT_SYMTAB + hatch_off = (char *)&ehdri.e_ident[11] - (char *)&ehdri; + break; + } + } + // FIXME: DT_TEXTREL + xct_off = elf_get_offset_from_address(xct_va); + goto proceed; // But proper packing depends on checking xct_va. + } +abandon: + phdri = 0; // Done with this + return false; +proceed: + phdri = 0; + } + // XXX Theoretically the following test should be first, + // but PackUnix::canPack() wants 0!=exetype ? if (!super::canPack()) return false; assert(exetype == 1); @@ -1459,7 +1677,7 @@ void PackLinuxElf32::pack1(OutputFile */*fo*/, Filter &/*ft*/) void PackLinuxElf32x86::pack1(OutputFile *fo, Filter &ft) { - PackLinuxElf32::pack1(fo, ft); + super::pack1(fo, ft); if (0==xct_off) // main executable generateElfHdr(fo, stub_i386_linux_elf_fold, getbrk(phdri, e_phnum) ); @@ -1469,7 +1687,6 @@ void PackLinuxElf32x86::pack1(OutputFile *fo, Filter &ft) sz_elf_hdrs = xct_off - sizeof(l_info); fo->write(ibuf, xct_off); - } } @@ -1543,7 +1760,15 @@ void PackLinuxElf64::pack1(OutputFile */*fo*/, Filter &/*ft*/) void PackLinuxElf64amd::pack1(OutputFile *fo, Filter &ft) { super::pack1(fo, ft); - generateElfHdr(fo, stub_amd64_linux_elf_fold, getbrk(phdri, e_phnum) ); + if (0==xct_off) // main executable + generateElfHdr(fo, stub_amd64_linux_elf_fold, getbrk(phdri, e_phnum) ); + else { // shared library + fi->seek(0, SEEK_SET); + fi->readx(ibuf, xct_off); + + sz_elf_hdrs = xct_off - sizeof(l_info); + fo->write(ibuf, xct_off); + } } // Determine length of gap between PT_LOAD phdr[k] and closest PT_LOAD @@ -1588,28 +1813,12 @@ void PackLinuxElf32::pack2(OutputFile *fo, Filter &ft) { Extent x; unsigned k; - bool is_shlib = (0!=xct_off); - - if (0) { // Only to make unpacking easier! - struct b_info h; memset(&h, 0, sizeof(h)); - h.sz_unc = sizeof(ehdri) + sizeof(*phdri) * e_phnum; - h.b_method = (unsigned char) ph.method; - int const r = upx_compress(ibuf, h.sz_unc, obuf, &h.sz_cpr, - NULL, ph.method, 10, NULL, NULL ); - if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc) - throwInternalError("loader compression failed"); - - unsigned const clen = h.sz_cpr; - set_te32(&h.sz_unc, h.sz_unc); - set_te32(&h.sz_cpr, h.sz_cpr); - fo->write(&h, sizeof(h)); - fo->write(obuf, clen); - } + bool const is_shlib = (0!=xct_off); // count passes, set ptload vars uip->ui_total_passes = 0; for (k = 0; k < e_phnum; ++k) { - if (PT_LOAD32 == get_te32(&phdri[k].p_type)) { + if (PT_LOAD32==get_te32(&phdri[k].p_type)) { uip->ui_total_passes++; if (find_LOAD_gap(phdri, k, e_phnum)) { uip->ui_total_passes++; @@ -1711,6 +1920,7 @@ void PackLinuxElf64::pack2(OutputFile *fo, Filter &ft) { Extent x; unsigned k; + bool const is_shlib = (0!=xct_off); // count passes, set ptload vars uip->ui_total_passes = 0; @@ -1722,13 +1932,14 @@ void PackLinuxElf64::pack2(OutputFile *fo, Filter &ft) } } } + uip->ui_total_passes -= !!is_shlib; // not .data of shlib // compress extents - unsigned total_in = 0; - unsigned total_out = 0; - unsigned hdr_u_len = sizeof(Elf64_Ehdr) + sz_phdrs; + unsigned total_in = xct_off - (is_shlib ? hdr_u_len : 0); + unsigned total_out = xct_off; + uip->ui_pass = 0; ft.addvalue = 0; @@ -1740,19 +1951,24 @@ void PackLinuxElf64::pack2(OutputFile *fo, Filter &ft) x.offset = get_te64(&phdri[k].p_offset); x.size = get_te64(&phdri[k].p_filesz); if (0 == nx) { // 1st PT_LOAD64 must cover Ehdr at 0==p_offset - unsigned const delta = sizeof(Elf64_Ehdr) + sz_phdrs; + unsigned const delta = !is_shlib + ? (sizeof(Elf64_Ehdr) + sz_phdrs) // main executable + : xct_off; // shared library if (ft.id < 0x40) { // FIXME: ?? ft.addvalue += delta; } - x.offset += delta; - x.size -= delta; + x.offset += delta; + x.size -= delta; } // compressWithFilters() always assumes a "loader", so would // throw NotCompressible for small .data Extents, which PowerPC // sometimes marks as PF_X anyway. So filter only first segment. + if (0==nx || !is_shlib) packExtent(x, total_in, total_out, ((0==nx && (Elf64_Phdr::PF_X & get_te64(&phdri[k].p_flags))) ? &ft : 0 ), fo, hdr_u_len); + else + total_in += x.size; hdr_u_len = 0; ++nx; } @@ -2074,9 +2290,43 @@ void PackLinuxElf64::pack4(OutputFile *fo, Filter &ft) #endif /*}*/ // rewrite Elf header + if (Elf64_Ehdr::ET_DYN==get_te16(&ehdri.e_type)) { + uint64_t const base= get_te64(&elfout.phdr[0].p_vaddr); + set_te16(&elfout.ehdr.e_type, Elf64_Ehdr::ET_DYN); + set_te16(&elfout.ehdr.e_phnum, 1); + set_te64( &elfout.ehdr.e_entry, + get_te64(&elfout.ehdr.e_entry) - base); + set_te64(&elfout.phdr[0].p_vaddr, get_te64(&elfout.phdr[0].p_vaddr) - base); + set_te64(&elfout.phdr[0].p_paddr, get_te64(&elfout.phdr[0].p_paddr) - base); + // Strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X + //elfout.phdr[0].p_flags |= Elf64_Phdr::PF_W; + } + fo->seek(0, SEEK_SET); - fo->rewrite(&elfout, sz_elf_hdrs); - fo->rewrite(&linfo, sizeof(linfo)); + if (0!=xct_off) { // shared library + ehdri.e_ident[0+hatch_off] = 0x0f; // syscall [munmap] + ehdri.e_ident[1+hatch_off] = 0x05; + ehdri.e_ident[2+hatch_off] = 0x5f; // pop %rdi (arg1) + ehdri.e_ident[3+hatch_off] = 0x5e; // pop %rsi (arg2) + ehdri.e_ident[4+hatch_off] = 0xc3; // RET + fo->rewrite(&ehdri, sizeof(ehdri)); + fo->rewrite(phdri, e_phnum * sizeof(*phdri)); + } + else { + if (Elf64_Phdr::PT_NOTE==get_te64(&elfout.phdr[2].p_type)) { + uint64_t const reloc = get_te64(&elfout.phdr[0].p_vaddr); + set_te64( &elfout.phdr[2].p_vaddr, + reloc + get_te64(&elfout.phdr[2].p_vaddr)); + set_te64( &elfout.phdr[2].p_paddr, + reloc + get_te64(&elfout.phdr[2].p_paddr)); + fo->rewrite(&elfout, sz_elf_hdrs); + // FIXME fo->rewrite(&elfnote, sizeof(elfnote)); + } + else { + fo->rewrite(&elfout, sz_elf_hdrs); + } + fo->rewrite(&linfo, sizeof(linfo)); + } } void PackLinuxElf64::unpack(OutputFile *fo) @@ -2340,7 +2590,7 @@ Linker* PackLinuxElf32armBe::newLinker() const } unsigned -PackLinuxElf32::elf_get_offset_from_address(unsigned const addr) const +PackLinuxElf32::elf_get_offset_from_address(uint64_t const addr) const { Elf32_Phdr const *phdr = phdri; int j = e_phnum; @@ -2380,12 +2630,12 @@ PackLinuxElf32::elf_unsigned_dynamic(unsigned int const key) const } unsigned -PackLinuxElf64::elf_get_offset_from_address(unsigned const addr) const +PackLinuxElf64::elf_get_offset_from_address(uint64_t const addr) const { Elf64_Phdr const *phdr = phdri; int j = e_phnum; - for (; --j>=0; ++phdr) if (PT_LOAD64 == get_te64(&phdr->p_type)) { - unsigned const t = addr - get_te64(&phdr->p_vaddr); + for (; --j>=0; ++phdr) if (PT_LOAD64 == get_te32(&phdr->p_type)) { + uint64_t const t = addr - get_te64(&phdr->p_vaddr); if (t < get_te64(&phdr->p_filesz)) { return t + get_te64(&phdr->p_offset); } @@ -2399,7 +2649,7 @@ PackLinuxElf64::elf_find_dynamic(unsigned int const key) const Elf64_Dyn const *dynp= dynseg; if (dynp) for (; Elf64_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te64(&dynp->d_tag)==key) { - unsigned const t= elf_get_offset_from_address(get_te64(&dynp->d_val)); + uint64_t const t= elf_get_offset_from_address(get_te64(&dynp->d_val)); if (t) { return t + file_image; } @@ -2534,7 +2784,7 @@ void PackLinuxElf32::unpack(OutputFile *fo) ph.u_len = get_te32(&bhdr.sz_unc); ph.c_len = get_te32(&bhdr.sz_cpr); ph.filter_cto = bhdr.b_cto8; - bool const is_shlib = ehdr->e_ident[12]==0xcd; + bool const is_shlib = (ehdr->e_ident[12]==0xcd) || (ehdr->e_ident[11]==0x0f); // Peek at resulting Ehdr and Phdrs for use in controlling unpacking. // Uncompress an extra time, and don't verify or update checksums. diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index 8996a2b6..47b9f250 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -63,7 +63,7 @@ protected: virtual void addStubEntrySections(Filter const *); virtual void unpack(OutputFile *fo); - virtual unsigned elf_get_offset_from_address(unsigned) const = 0; + virtual unsigned elf_get_offset_from_address(uint64_t) const = 0; virtual void const *elf_find_dynamic(unsigned) const = 0; virtual uint64_t elf_unsigned_dynamic(unsigned) const = 0; @@ -78,9 +78,9 @@ protected: unsigned lg2_page; // log2(PAGE_SIZE) unsigned page_size; // 1u< + + John F. Reiser + + */ + + +#define STUB_AMD64_LINUX_SHLIB_INIT_SIZE 9544 +#define STUB_AMD64_LINUX_SHLIB_INIT_ADLER32 0x8b37e549 +#define STUB_AMD64_LINUX_SHLIB_INIT_CRC32 0x4f89c1b6 + +unsigned char stub_amd64_linux_shlib_init[9544] = { +/* 0x0000 */ 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x0010 */ 1, 0, 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 0x0020 */ 0, 0, 0, 0, 0, 0, 0, 0,144, 25, 0, 0, 0, 0, 0, 0, +/* 0x0030 */ 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 64, 0, 22, 0, 19, 0, +/* 0x0040 */ 80, 86, 87, 80, 82, 85, 72,137,229,232, 0, 0, 0, 0, 85, 83, +/* 0x0050 */ 81, 82, 72, 1,254, 86, 72,137,254, 72,137,215, 49,219, 49,201, +/* 0x0060 */ 72,131,205,255,232, 80, 0, 0, 0, 1,219,116, 2,243,195,139, +/* 0x0070 */ 30, 72,131,238,252, 17,219,138, 22,243,195, 72,141, 4, 47,131, +/* 0x0080 */ 249, 5,138, 16,118, 33, 72,131,253,252,119, 27,131,233, 4,139, +/* 0x0090 */ 16, 72,131,192, 4,131,233, 4,137, 23, 72,141,127, 4,115,239, +/* 0x00a0 */ 131,193, 4,138, 16,116, 16, 72,255,192,136, 23,131,233, 1,138, +/* 0x00b0 */ 16, 72,141,127, 1,117,240,243,195,252, 65, 91, 65,128,248, 8, +/* 0x00c0 */ 116, 13,233,172, 0, 0, 0, 72,255,198,136, 23, 72,255,199,138, +/* 0x00d0 */ 22, 1,219,117, 10,139, 30, 72,131,238,252, 17,219,138, 22,114, +/* 0x00e0 */ 230,141, 65, 1,235, 7,255,200, 65,255,211, 17,192, 65,255,211, +/* 0x00f0 */ 17,192, 1,219,117, 10,139, 30, 72,131,238,252, 17,219,138, 22, +/* 0x0100 */ 115,228,131,232, 3,114, 29,193,224, 8, 15,182,210, 9,208, 72, +/* 0x0110 */ 255,198,131,240,255, 15,132, 0, 0, 0, 0,209,248, 72, 99,232, +/* 0x0120 */ 114, 56,235, 14, 1,219,117, 8,139, 30, 72,131,238,252, 17,219, +/* 0x0130 */ 114, 40,255,193, 1,219,117, 8,139, 30, 72,131,238,252, 17,219, +/* 0x0140 */ 114, 24, 65,255,211, 17,201, 1,219,117, 8,139, 30, 72,131,238, +/* 0x0150 */ 252, 17,219,115,237,131,193, 2,235, 5, 65,255,211, 17,201, 72, +/* 0x0160 */ 129,253, 0,251,255,255,131,209, 2,232, 0, 0, 0, 0,233, 92, +/* 0x0170 */ 255,255,255, 65,128,248, 5,116, 13,233,147, 0, 0, 0, 72,255, +/* 0x0180 */ 198,136, 23, 72,255,199,138, 22, 1,219,117, 10,139, 30, 72,131, +/* 0x0190 */ 238,252, 17,219,138, 22,114,230,141, 65, 1,235, 7,255,200, 65, +/* 0x01a0 */ 255,211, 17,192, 65,255,211, 17,192, 1,219,117, 10,139, 30, 72, +/* 0x01b0 */ 131,238,252, 17,219,138, 22,115,228,131,232, 3,114, 27,193,224, +/* 0x01c0 */ 8, 15,182,210, 9,208, 72,255,198,131,240,255, 15,132, 0, 0, +/* 0x01d0 */ 0, 0,209,248, 72, 99,232,235, 3, 65,255,211, 17,201, 65,255, +/* 0x01e0 */ 211, 17,201,117, 24,255,193, 65,255,211, 17,201, 1,219,117, 8, +/* 0x01f0 */ 139, 30, 72,131,238,252, 17,219,115,237,131,193, 2, 72,129,253, +/* 0x0200 */ 0,251,255,255,131,209, 1,232, 0, 0, 0, 0,233,117,255,255, +/* 0x0210 */ 255, 65,128,248, 2,116, 13,233,133, 0, 0, 0, 72,255,198,136, +/* 0x0220 */ 23, 72,255,199,138, 22, 1,219,117, 10,139, 30, 72,131,238,252, +/* 0x0230 */ 17,219,138, 22,114,230,141, 65, 1, 65,255,211, 17,192, 1,219, +/* 0x0240 */ 117, 10,139, 30, 72,131,238,252, 17,219,138, 22,115,235,131,232, +/* 0x0250 */ 3,114, 23,193,224, 8, 15,182,210, 9,208, 72,255,198,131,240, +/* 0x0260 */ 255, 15,132, 0, 0, 0, 0, 72, 99,232,141, 65, 1, 65,255,211, +/* 0x0270 */ 17,201, 65,255,211, 17,201,117, 24,137,193,131,192, 2, 65,255, +/* 0x0280 */ 211, 17,201, 1,219,117, 8,139, 30, 72,131,238,252, 17,219,115, +/* 0x0290 */ 237, 72,129,253, 0,243,255,255, 17,193,232, 0, 0, 0, 0,235, +/* 0x02a0 */ 131, 65,128,248, 14, 15,133, 0, 0, 0, 0, 85, 72,137,229, 68, +/* 0x02b0 */ 139, 9, 73,137,208, 72,137,242, 72,141,119, 2, 86,138, 7,255, +/* 0x02c0 */ 202,136,193, 36, 7,192,233, 3, 72,199,195, 0,253,255,255, 72, +/* 0x02d0 */ 211,227,136,193, 72,141,156, 92,136,241,255,255, 72,131,227,192, +/* 0x02e0 */ 106, 0, 72, 57,220,117,249, 83, 72,141,123, 8,138, 78,255,255, +/* 0x02f0 */ 202,136, 71, 2,136,200,192,233, 4,136, 79, 1, 36, 15,136, 7, +/* 0x0300 */ 72,141, 79,252, 80, 65, 87, 72,141, 71, 4, 69, 49,255, 65, 86, +/* 0x0310 */ 65,190, 1, 0, 0, 0, 65, 85, 69, 49,237, 65, 84, 85, 83, 72, +/* 0x0320 */ 137, 76, 36,240, 72,137, 68, 36,216,184, 1, 0, 0, 0, 72,137, +/* 0x0330 */ 116, 36,248, 76,137, 68, 36,232,137,195, 68,137, 76, 36,228, 15, +/* 0x0340 */ 182, 79, 2,211,227,137,217, 72,139, 92, 36, 56,255,201,137, 76, +/* 0x0350 */ 36,212, 15,182, 79, 1,211,224, 72,139, 76, 36,240,255,200,137, +/* 0x0360 */ 68, 36,208, 15,182, 7,199, 1, 0, 0, 0, 0,199, 68, 36,200, +/* 0x0370 */ 0, 0, 0, 0,199, 68, 36,196, 1, 0, 0, 0,199, 68, 36,192, +/* 0x0380 */ 1, 0, 0, 0,199, 68, 36,188, 1, 0, 0, 0,199, 3, 0, 0, +/* 0x0390 */ 0, 0,137, 68, 36,204, 15,182, 79, 1, 1,193,184, 0, 3, 0, +/* 0x03a0 */ 0,211,224, 49,201,141,184, 54, 7, 0, 0, 65, 57,255,115, 19, +/* 0x03b0 */ 72,139, 92, 36,216,137,200,255,193, 57,249,102,199, 4, 67, 0, +/* 0x03c0 */ 4,235,235, 72,139,124, 36,248,137,208, 69, 49,210, 65,131,203, +/* 0x03d0 */ 255, 49,210, 73,137,252, 73, 1,196, 76, 57,231, 15,132,239, 8, +/* 0x03e0 */ 0, 0, 15,182, 7, 65,193,226, 8,255,194, 72,255,199, 65, 9, +/* 0x03f0 */ 194,131,250, 4,126,227, 68, 59,124, 36,228, 15,131,218, 8, 0, +/* 0x0400 */ 0,139, 68, 36,212, 72, 99, 92, 36,200, 72,139, 84, 36,216, 68, +/* 0x0410 */ 33,248,137, 68, 36,184, 72, 99,108, 36,184, 72,137,216, 72,193, +/* 0x0420 */ 224, 4, 72, 1,232, 65,129,251,255,255,255, 0, 76,141, 12, 66, +/* 0x0430 */ 119, 26, 76, 57,231, 15,132,150, 8, 0, 0, 15,182, 7, 65,193, +/* 0x0440 */ 226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, 15,183, 17, +/* 0x0450 */ 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194, 15, +/* 0x0460 */ 131,197, 1, 0, 0, 65,137,195,184, 0, 8, 0, 0, 72,139, 92, +/* 0x0470 */ 36,216, 41,200, 15,182, 76, 36,204,190, 1, 0, 0, 0,193,248, +/* 0x0480 */ 5,141, 4, 2, 65, 15,182,213,102, 65,137, 1,139, 68, 36,208, +/* 0x0490 */ 68, 33,248,211,224,185, 8, 0, 0, 0, 43, 76, 36,204,211,250, +/* 0x04a0 */ 1,208,105,192, 0, 3, 0, 0,131,124, 36,200, 6,137,192, 76, +/* 0x04b0 */ 141,140, 67,108, 14, 0, 0, 15,142,184, 0, 0, 0, 72,139, 84, +/* 0x04c0 */ 36,232, 68,137,248, 68, 41,240, 15,182, 44, 2, 1,237, 72, 99, +/* 0x04d0 */ 214,137,235,129,227, 0, 1, 0, 0, 65,129,251,255,255,255, 0, +/* 0x04e0 */ 72, 99,195, 73,141, 4, 65, 76,141, 4, 80,119, 26, 76, 57,231, +/* 0x04f0 */ 15,132,219, 7, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, +/* 0x0500 */ 8, 72,255,199, 65, 9,194, 65, 15,183,144, 0, 2, 0, 0, 68, +/* 0x0510 */ 137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 32, +/* 0x0520 */ 65,137,195,184, 0, 8, 0, 0, 1,246, 41,200,193,248, 5,133, +/* 0x0530 */ 219,141, 4, 2,102, 65,137,128, 0, 2, 0, 0,116, 33,235, 45, +/* 0x0540 */ 65, 41,195, 65, 41,194,137,208,102,193,232, 5,141,116, 54, 1, +/* 0x0550 */ 102, 41,194,133,219,102, 65,137,144, 0, 2, 0, 0,116, 14,129, +/* 0x0560 */ 254,255, 0, 0, 0, 15,142, 97,255,255,255,235,120,129,254,255, +/* 0x0570 */ 0, 0, 0,127,112, 72, 99,198, 65,129,251,255,255,255, 0, 77, +/* 0x0580 */ 141, 4, 65,119, 26, 76, 57,231, 15,132, 67, 7, 0, 0, 15,182, +/* 0x0590 */ 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, +/* 0x05a0 */ 15,183, 16, 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, +/* 0x05b0 */ 57,194,115, 24, 65,137,195,184, 0, 8, 0, 0, 1,246, 41,200, +/* 0x05c0 */ 193,248, 5,141, 4, 2,102, 65,137, 0,235,161, 65, 41,195, 65, +/* 0x05d0 */ 41,194,137,208,102,193,232, 5,141,116, 54, 1,102, 41,194,102, +/* 0x05e0 */ 65,137, 16,235,136, 72,139, 76, 36,232, 68,137,248, 65,255,199, +/* 0x05f0 */ 65,137,245, 64,136, 52, 1,131,124, 36,200, 3,127, 13,199, 68, +/* 0x0600 */ 36,200, 0, 0, 0, 0,233,166, 6, 0, 0,139, 84, 36,200,139, +/* 0x0610 */ 68, 36,200,131,234, 3,131,232, 6,131,124, 36,200, 9, 15, 79, +/* 0x0620 */ 208,137, 84, 36,200,233,135, 6, 0, 0, 65, 41,195, 65, 41,194, +/* 0x0630 */ 137,208,102,193,232, 5,102, 41,194, 72,139, 68, 36,216, 65,129, +/* 0x0640 */ 251,255,255,255, 0,102, 65,137, 17, 72,141, 52, 88,119, 26, 76, +/* 0x0650 */ 57,231, 15,132,121, 6, 0, 0, 15,182, 7, 65,193,226, 8, 65, +/* 0x0660 */ 193,227, 8, 72,255,199, 65, 9,194, 15,183,150,128, 1, 0, 0, +/* 0x0670 */ 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194,115, +/* 0x0680 */ 78, 65,137,195,184, 0, 8, 0, 0, 76,139, 76, 36,216, 41,200, +/* 0x0690 */ 139, 76, 36,196, 68,137,116, 36,196,193,248, 5,141, 4, 2,139, +/* 0x06a0 */ 84, 36,192,137, 76, 36,192,102,137,134,128, 1, 0, 0, 49,192, +/* 0x06b0 */ 131,124, 36,200, 6,137, 84, 36,188, 15,159,192, 73,129,193,100, +/* 0x06c0 */ 6, 0, 0,141, 4, 64,137, 68, 36,200,233, 84, 2, 0, 0, 65, +/* 0x06d0 */ 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41,194, 65,129, +/* 0x06e0 */ 251,255,255,255, 0,102,137,150,128, 1, 0, 0,119, 26, 76, 57, +/* 0x06f0 */ 231, 15,132,218, 5, 0, 0, 15,182, 7, 65,193,226, 8, 65,193, +/* 0x0700 */ 227, 8, 72,255,199, 65, 9,194, 15,183,150,152, 1, 0, 0, 68, +/* 0x0710 */ 137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194, 15,131, +/* 0x0720 */ 208, 0, 0, 0, 65,184, 0, 8, 0, 0, 65,137,195, 72,193,227, +/* 0x0730 */ 5, 68,137,192, 41,200,193,248, 5,141, 4, 2,102,137,134,152, +/* 0x0740 */ 1, 0, 0, 72,139, 68, 36,216, 72, 1,216, 65,129,251,255,255, +/* 0x0750 */ 255, 0, 72,141, 52,104,119, 26, 76, 57,231, 15,132,112, 5, 0, +/* 0x0760 */ 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, +/* 0x0770 */ 9,194, 15,183,150,224, 1, 0, 0, 68,137,216,193,232, 11, 15, +/* 0x0780 */ 183,202, 15,175,193, 65, 57,194,115, 79, 65, 41,200, 65,137,195, +/* 0x0790 */ 65,193,248, 5, 69,133,255, 66,141, 4, 2,102,137,134,224, 1, +/* 0x07a0 */ 0, 0, 15,132, 41, 5, 0, 0, 49,192,131,124, 36,200, 6, 72, +/* 0x07b0 */ 139, 92, 36,232, 15,159,192,141, 68, 0, 9,137, 68, 36,200, 68, +/* 0x07c0 */ 137,248, 68, 41,240, 68, 15,182, 44, 3, 68,137,248, 65,255,199, +/* 0x07d0 */ 68,136, 44, 3,233,216, 4, 0, 0, 65, 41,195, 65, 41,194,137, +/* 0x07e0 */ 208,102,193,232, 5,102, 41,194,102,137,150,224, 1, 0, 0,233, +/* 0x07f0 */ 17, 1, 0, 0, 65, 41,195, 65, 41,194,137,208,102,193,232, 5, +/* 0x0800 */ 102, 41,194, 65,129,251,255,255,255, 0,102,137,150,152, 1, 0, +/* 0x0810 */ 0,119, 26, 76, 57,231, 15,132,181, 4, 0, 0, 15,182, 7, 65, +/* 0x0820 */ 193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 15,183,150, +/* 0x0830 */ 176, 1, 0, 0, 68,137,216,193,232, 11, 15,183,202, 15,175,193, +/* 0x0840 */ 65, 57,194,115, 32, 65,137,195,184, 0, 8, 0, 0, 41,200,193, +/* 0x0850 */ 248, 5,141, 4, 2,102,137,134,176, 1, 0, 0,139, 68, 36,196, +/* 0x0860 */ 233,152, 0, 0, 0, 65, 41,195, 65, 41,194,137,208,102,193,232, +/* 0x0870 */ 5,102, 41,194, 65,129,251,255,255,255, 0,102,137,150,176, 1, +/* 0x0880 */ 0, 0,119, 26, 76, 57,231, 15,132, 68, 4, 0, 0, 15,182, 7, +/* 0x0890 */ 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 15,183, +/* 0x08a0 */ 150,200, 1, 0, 0, 68,137,216,193,232, 11, 15,183,202, 15,175, +/* 0x08b0 */ 193, 65, 57,194,115, 29, 65,137,195,184, 0, 8, 0, 0, 41,200, +/* 0x08c0 */ 193,248, 5,141, 4, 2,102,137,134,200, 1, 0, 0,139, 68, 36, +/* 0x08d0 */ 192,235, 34, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, +/* 0x08e0 */ 41,194,139, 68, 36,188,102,137,150,200, 1, 0, 0,139, 84, 36, +/* 0x08f0 */ 192,137, 84, 36,188,139, 76, 36,196,137, 76, 36,192, 68,137,116, +/* 0x0900 */ 36,196, 65,137,198, 49,192,131,124, 36,200, 6, 76,139, 76, 36, +/* 0x0910 */ 216, 15,159,192, 73,129,193,104, 10, 0, 0,141, 68, 64, 8,137, +/* 0x0920 */ 68, 36,200, 65,129,251,255,255,255, 0,119, 26, 76, 57,231, 15, +/* 0x0930 */ 132,156, 3, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, +/* 0x0940 */ 72,255,199, 65, 9,194, 65, 15,183, 17, 68,137,216,193,232, 11, +/* 0x0950 */ 15,183,202, 15,175,193, 65, 57,194,115, 39, 65,137,195,184, 0, +/* 0x0960 */ 8, 0, 0, 69, 49,237, 41,200,193,248, 5,141, 4, 2,102, 65, +/* 0x0970 */ 137, 1, 72, 99, 68, 36,184, 72,193,224, 4, 77,141, 68, 1, 4, +/* 0x0980 */ 235,120, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41, +/* 0x0990 */ 194, 65,129,251,255,255,255, 0,102, 65,137, 17,119, 26, 76, 57, +/* 0x09a0 */ 231, 15,132, 42, 3, 0, 0, 15,182, 7, 65,193,226, 8, 65,193, +/* 0x09b0 */ 227, 8, 72,255,199, 65, 9,194, 65, 15,183, 81, 2, 68,137,216, +/* 0x09c0 */ 193,232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 52, 65,137, +/* 0x09d0 */ 195,184, 0, 8, 0, 0, 65,189, 8, 0, 0, 0, 41,200,193,248, +/* 0x09e0 */ 5,141, 4, 2,102, 65,137, 65, 2, 72, 99, 68, 36,184, 72,193, +/* 0x09f0 */ 224, 4, 77,141,132, 1, 4, 1, 0, 0, 65,185, 3, 0, 0, 0, +/* 0x0a00 */ 235, 39, 65, 41,195, 65, 41,194,137,208,102,193,232, 5, 77,141, +/* 0x0a10 */ 129, 4, 2, 0, 0, 65,189, 16, 0, 0, 0,102, 41,194,102, 65, +/* 0x0a20 */ 137, 81, 2, 65,185, 8, 0, 0, 0, 68,137,203,189, 1, 0, 0, +/* 0x0a30 */ 0, 72, 99,197, 65,129,251,255,255,255, 0, 73,141, 52, 64,119, +/* 0x0a40 */ 26, 76, 57,231, 15,132,135, 2, 0, 0, 15,182, 7, 65,193,226, +/* 0x0a50 */ 8, 65,193,227, 8, 72,255,199, 65, 9,194, 15,183, 14, 68,137, +/* 0x0a60 */ 216,193,232, 11, 15,183,209, 15,175,194, 65, 57,194,115, 23, 65, +/* 0x0a70 */ 137,195,184, 0, 8, 0, 0, 1,237, 41,208,193,248, 5,141, 4, +/* 0x0a80 */ 1,102,137, 6,235, 22, 65, 41,195, 65, 41,194,137,200,102,193, +/* 0x0a90 */ 232, 5,141,108, 45, 1,102, 41,193,102,137, 14,255,203,117,145, +/* 0x0aa0 */ 184, 1, 0, 0, 0, 68,137,201,211,224, 41,197, 68, 1,237,131, +/* 0x0ab0 */ 124, 36,200, 3, 15,143,194, 1, 0, 0,131, 68, 36,200, 7,184, +/* 0x0ac0 */ 3, 0, 0, 0,131,253, 4, 15, 76,197, 72,139, 92, 36,216, 65, +/* 0x0ad0 */ 184, 1, 0, 0, 0, 72,152, 72,193,224, 7, 76,141,140, 3, 96, +/* 0x0ae0 */ 3, 0, 0,187, 6, 0, 0, 0, 73, 99,192, 65,129,251,255,255, +/* 0x0af0 */ 255, 0, 73,141, 52, 65,119, 26, 76, 57,231, 15,132,208, 1, 0, +/* 0x0b00 */ 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, +/* 0x0b10 */ 9,194, 15,183, 22, 68,137,216,193,232, 11, 15,183,202, 15,175, +/* 0x0b20 */ 193, 65, 57,194,115, 24, 65,137,195,184, 0, 8, 0, 0, 69, 1, +/* 0x0b30 */ 192, 41,200,193,248, 5,141, 4, 2,102,137, 6,235, 23, 65, 41, +/* 0x0b40 */ 195, 65, 41,194,137,208,102,193,232, 5, 71,141, 68, 0, 1,102, +/* 0x0b50 */ 41,194,102,137, 22,255,203,117,143, 65,131,232, 64, 65,131,248, +/* 0x0b60 */ 3, 69,137,198, 15,142, 13, 1, 0, 0, 65,131,230, 1, 68,137, +/* 0x0b70 */ 192,209,248, 65,131,206, 2, 65,131,248, 13,141,112,255,127, 35, +/* 0x0b80 */ 137,241, 72,139, 92, 36,216, 73, 99,192, 65,211,230, 72, 1,192, +/* 0x0b90 */ 68,137,242, 72,141, 20, 83, 72, 41,194, 76,141,138, 94, 5, 0, +/* 0x0ba0 */ 0,235, 81,141,112,251, 65,129,251,255,255,255, 0,119, 26, 76, +/* 0x0bb0 */ 57,231, 15,132, 25, 1, 0, 0, 15,182, 7, 65,193,226, 8, 65, +/* 0x0bc0 */ 193,227, 8, 72,255,199, 65, 9,194, 65,209,235, 69, 1,246, 69, +/* 0x0bd0 */ 57,218,114, 7, 69, 41,218, 65,131,206, 1,255,206,117,199, 76, +/* 0x0be0 */ 139, 76, 36,216, 65,193,230, 4,190, 4, 0, 0, 0, 73,129,193, +/* 0x0bf0 */ 68, 6, 0, 0, 65,189, 1, 0, 0, 0,187, 1, 0, 0, 0, 72, +/* 0x0c00 */ 99,195, 65,129,251,255,255,255, 0, 77,141, 4, 65,119, 26, 76, +/* 0x0c10 */ 57,231, 15,132,185, 0, 0, 0, 15,182, 7, 65,193,226, 8, 65, +/* 0x0c20 */ 193,227, 8, 72,255,199, 65, 9,194, 65, 15,183, 16, 68,137,216, +/* 0x0c30 */ 193,232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 24, 65,137, +/* 0x0c40 */ 195,184, 0, 8, 0, 0, 1,219, 41,200,193,248, 5,141, 4, 2, +/* 0x0c50 */ 102, 65,137, 0,235, 26, 65, 41,195, 65, 41,194,137,208,102,193, +/* 0x0c60 */ 232, 5,141, 92, 27, 1, 69, 9,238,102, 41,194,102, 65,137, 16, +/* 0x0c70 */ 69, 1,237,255,206,117,136, 65,255,198,116, 64,131,197, 2, 69, +/* 0x0c80 */ 57,254,119, 77, 72,139, 84, 36,232, 68,137,248, 68, 41,240, 68, +/* 0x0c90 */ 15,182, 44, 2, 68,137,248, 65,255,199,255,205, 68,136, 44, 2, +/* 0x0ca0 */ 15,149,194, 49,192, 68, 59,124, 36,228, 15,146,192,133,194,117, +/* 0x0cb0 */ 211, 68, 59,124, 36,228, 15,130, 69,247,255,255, 65,129,251,255, +/* 0x0cc0 */ 255,255, 0,119, 22, 76, 57,231,184, 1, 0, 0, 0,116, 35,235, +/* 0x0cd0 */ 7,184, 1, 0, 0, 0,235, 26, 72,255,199,137,248, 43, 68, 36, +/* 0x0ce0 */ 248, 72,139, 76, 36,240, 72,139, 92, 36, 56,137, 1, 68,137, 59, +/* 0x0cf0 */ 49,192, 91, 93, 65, 92, 65, 93, 65, 94, 65, 95, 65, 87, 72,141, +/* 0x0d00 */ 71, 4, 69, 49,255, 65, 86, 65,190, 1, 0, 0, 0, 65, 85, 69, +/* 0x0d10 */ 49,237, 65, 84, 85, 83, 72,137, 76, 36,240, 72,137, 68, 36,216, +/* 0x0d20 */ 184, 1, 0, 0, 0, 72,137,116, 36,248, 76,137, 68, 36,232,137, +/* 0x0d30 */ 195, 68,137, 76, 36,228, 15,182, 79, 2,211,227,137,217, 72,139, +/* 0x0d40 */ 92, 36, 56,255,201,137, 76, 36,212, 15,182, 79, 1,211,224, 72, +/* 0x0d50 */ 139, 76, 36,240,255,200,137, 68, 36,208, 15,182, 7,199, 1, 0, +/* 0x0d60 */ 0, 0, 0,199, 68, 36,200, 0, 0, 0, 0,199, 68, 36,196, 1, +/* 0x0d70 */ 0, 0, 0,199, 68, 36,192, 1, 0, 0, 0,199, 68, 36,188, 1, +/* 0x0d80 */ 0, 0, 0,199, 3, 0, 0, 0, 0,137, 68, 36,204, 15,182, 79, +/* 0x0d90 */ 1, 1,193,184, 0, 3, 0, 0,211,224, 49,201,141,184, 54, 7, +/* 0x0da0 */ 0, 0, 65, 57,255,115, 19, 72,139, 92, 36,216,137,200,255,193, +/* 0x0db0 */ 57,249,102,199, 4, 67, 0, 4,235,235, 72,139,124, 36,248,137, +/* 0x0dc0 */ 208, 69, 49,210, 65,131,203,255, 49,210, 73,137,252, 73, 1,196, +/* 0x0dd0 */ 76, 57,231, 15,132,239, 8, 0, 0, 15,182, 7, 65,193,226, 8, +/* 0x0de0 */ 255,194, 72,255,199, 65, 9,194,131,250, 4,126,227, 68, 59,124, +/* 0x0df0 */ 36,228, 15,131,218, 8, 0, 0,139, 68, 36,212, 72, 99, 92, 36, +/* 0x0e00 */ 200, 72,139, 84, 36,216, 68, 33,248,137, 68, 36,184, 72, 99,108, +/* 0x0e10 */ 36,184, 72,137,216, 72,193,224, 4, 72, 1,232, 65,129,251,255, +/* 0x0e20 */ 255,255, 0, 76,141, 12, 66,119, 26, 76, 57,231, 15,132,150, 8, +/* 0x0e30 */ 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, +/* 0x0e40 */ 65, 9,194, 65, 15,183, 17, 68,137,216,193,232, 11, 15,183,202, +/* 0x0e50 */ 15,175,193, 65, 57,194, 15,131,197, 1, 0, 0, 65,137,195,184, +/* 0x0e60 */ 0, 8, 0, 0, 72,139, 92, 36,216, 41,200, 15,182, 76, 36,204, +/* 0x0e70 */ 190, 1, 0, 0, 0,193,248, 5,141, 4, 2, 65, 15,182,213,102, +/* 0x0e80 */ 65,137, 1,139, 68, 36,208, 68, 33,248,211,224,185, 8, 0, 0, +/* 0x0e90 */ 0, 43, 76, 36,204,211,250, 1,208,105,192, 0, 3, 0, 0,131, +/* 0x0ea0 */ 124, 36,200, 6,137,192, 76,141,140, 67,108, 14, 0, 0, 15,142, +/* 0x0eb0 */ 184, 0, 0, 0, 72,139, 84, 36,232, 68,137,248, 68, 41,240, 15, +/* 0x0ec0 */ 182, 44, 2, 1,237, 72, 99,214,137,235,129,227, 0, 1, 0, 0, +/* 0x0ed0 */ 65,129,251,255,255,255, 0, 72, 99,195, 73,141, 4, 65, 76,141, +/* 0x0ee0 */ 4, 80,119, 26, 76, 57,231, 15,132,219, 7, 0, 0, 15,182, 7, +/* 0x0ef0 */ 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, 15, +/* 0x0f00 */ 183,144, 0, 2, 0, 0, 68,137,216,193,232, 11, 15,183,202, 15, +/* 0x0f10 */ 175,193, 65, 57,194,115, 32, 65,137,195,184, 0, 8, 0, 0, 1, +/* 0x0f20 */ 246, 41,200,193,248, 5,133,219,141, 4, 2,102, 65,137,128, 0, +/* 0x0f30 */ 2, 0, 0,116, 33,235, 45, 65, 41,195, 65, 41,194,137,208,102, +/* 0x0f40 */ 193,232, 5,141,116, 54, 1,102, 41,194,133,219,102, 65,137,144, +/* 0x0f50 */ 0, 2, 0, 0,116, 14,129,254,255, 0, 0, 0, 15,142, 97,255, +/* 0x0f60 */ 255,255,235,120,129,254,255, 0, 0, 0,127,112, 72, 99,198, 65, +/* 0x0f70 */ 129,251,255,255,255, 0, 77,141, 4, 65,119, 26, 76, 57,231, 15, +/* 0x0f80 */ 132, 67, 7, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, +/* 0x0f90 */ 72,255,199, 65, 9,194, 65, 15,183, 16, 68,137,216,193,232, 11, +/* 0x0fa0 */ 15,183,202, 15,175,193, 65, 57,194,115, 24, 65,137,195,184, 0, +/* 0x0fb0 */ 8, 0, 0, 1,246, 41,200,193,248, 5,141, 4, 2,102, 65,137, +/* 0x0fc0 */ 0,235,161, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,141, +/* 0x0fd0 */ 116, 54, 1,102, 41,194,102, 65,137, 16,235,136, 72,139, 76, 36, +/* 0x0fe0 */ 232, 68,137,248, 65,255,199, 65,137,245, 64,136, 52, 1,131,124, +/* 0x0ff0 */ 36,200, 3,127, 13,199, 68, 36,200, 0, 0, 0, 0,233,166, 6, +/* 0x1000 */ 0, 0,139, 84, 36,200,139, 68, 36,200,131,234, 3,131,232, 6, +/* 0x1010 */ 131,124, 36,200, 9, 15, 79,208,137, 84, 36,200,233,135, 6, 0, +/* 0x1020 */ 0, 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41,194, +/* 0x1030 */ 72,139, 68, 36,216, 65,129,251,255,255,255, 0,102, 65,137, 17, +/* 0x1040 */ 72,141, 52, 88,119, 26, 76, 57,231, 15,132,121, 6, 0, 0, 15, +/* 0x1050 */ 182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, +/* 0x1060 */ 15,183,150,128, 1, 0, 0, 68,137,216,193,232, 11, 15,183,202, +/* 0x1070 */ 15,175,193, 65, 57,194,115, 78, 65,137,195,184, 0, 8, 0, 0, +/* 0x1080 */ 76,139, 76, 36,216, 41,200,139, 76, 36,196, 68,137,116, 36,196, +/* 0x1090 */ 193,248, 5,141, 4, 2,139, 84, 36,192,137, 76, 36,192,102,137, +/* 0x10a0 */ 134,128, 1, 0, 0, 49,192,131,124, 36,200, 6,137, 84, 36,188, +/* 0x10b0 */ 15,159,192, 73,129,193,100, 6, 0, 0,141, 4, 64,137, 68, 36, +/* 0x10c0 */ 200,233, 84, 2, 0, 0, 65, 41,195, 65, 41,194,137,208,102,193, +/* 0x10d0 */ 232, 5,102, 41,194, 65,129,251,255,255,255, 0,102,137,150,128, +/* 0x10e0 */ 1, 0, 0,119, 26, 76, 57,231, 15,132,218, 5, 0, 0, 15,182, +/* 0x10f0 */ 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 15, +/* 0x1100 */ 183,150,152, 1, 0, 0, 68,137,216,193,232, 11, 15,183,202, 15, +/* 0x1110 */ 175,193, 65, 57,194, 15,131,208, 0, 0, 0, 65,184, 0, 8, 0, +/* 0x1120 */ 0, 65,137,195, 72,193,227, 5, 68,137,192, 41,200,193,248, 5, +/* 0x1130 */ 141, 4, 2,102,137,134,152, 1, 0, 0, 72,139, 68, 36,216, 72, +/* 0x1140 */ 1,216, 65,129,251,255,255,255, 0, 72,141, 52,104,119, 26, 76, +/* 0x1150 */ 57,231, 15,132,112, 5, 0, 0, 15,182, 7, 65,193,226, 8, 65, +/* 0x1160 */ 193,227, 8, 72,255,199, 65, 9,194, 15,183,150,224, 1, 0, 0, +/* 0x1170 */ 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194,115, +/* 0x1180 */ 79, 65, 41,200, 65,137,195, 65,193,248, 5, 69,133,255, 66,141, +/* 0x1190 */ 4, 2,102,137,134,224, 1, 0, 0, 15,132, 41, 5, 0, 0, 49, +/* 0x11a0 */ 192,131,124, 36,200, 6, 72,139, 92, 36,232, 15,159,192,141, 68, +/* 0x11b0 */ 0, 9,137, 68, 36,200, 68,137,248, 68, 41,240, 68, 15,182, 44, +/* 0x11c0 */ 3, 68,137,248, 65,255,199, 68,136, 44, 3,233,216, 4, 0, 0, +/* 0x11d0 */ 65, 41,195, 65, 41,194,137,208,102,193,232, 5,102, 41,194,102, +/* 0x11e0 */ 137,150,224, 1, 0, 0,233, 17, 1, 0, 0, 65, 41,195, 65, 41, +/* 0x11f0 */ 194,137,208,102,193,232, 5,102, 41,194, 65,129,251,255,255,255, +/* 0x1200 */ 0,102,137,150,152, 1, 0, 0,119, 26, 76, 57,231, 15,132,181, +/* 0x1210 */ 4, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255, +/* 0x1220 */ 199, 65, 9,194, 15,183,150,176, 1, 0, 0, 68,137,216,193,232, +/* 0x1230 */ 11, 15,183,202, 15,175,193, 65, 57,194,115, 32, 65,137,195,184, +/* 0x1240 */ 0, 8, 0, 0, 41,200,193,248, 5,141, 4, 2,102,137,134,176, +/* 0x1250 */ 1, 0, 0,139, 68, 36,196,233,152, 0, 0, 0, 65, 41,195, 65, +/* 0x1260 */ 41,194,137,208,102,193,232, 5,102, 41,194, 65,129,251,255,255, +/* 0x1270 */ 255, 0,102,137,150,176, 1, 0, 0,119, 26, 76, 57,231, 15,132, +/* 0x1280 */ 68, 4, 0, 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72, +/* 0x1290 */ 255,199, 65, 9,194, 15,183,150,200, 1, 0, 0, 68,137,216,193, +/* 0x12a0 */ 232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 29, 65,137,195, +/* 0x12b0 */ 184, 0, 8, 0, 0, 41,200,193,248, 5,141, 4, 2,102,137,134, +/* 0x12c0 */ 200, 1, 0, 0,139, 68, 36,192,235, 34, 65, 41,195, 65, 41,194, +/* 0x12d0 */ 137,208,102,193,232, 5,102, 41,194,139, 68, 36,188,102,137,150, +/* 0x12e0 */ 200, 1, 0, 0,139, 84, 36,192,137, 84, 36,188,139, 76, 36,196, +/* 0x12f0 */ 137, 76, 36,192, 68,137,116, 36,196, 65,137,198, 49,192,131,124, +/* 0x1300 */ 36,200, 6, 76,139, 76, 36,216, 15,159,192, 73,129,193,104, 10, +/* 0x1310 */ 0, 0,141, 68, 64, 8,137, 68, 36,200, 65,129,251,255,255,255, +/* 0x1320 */ 0,119, 26, 76, 57,231, 15,132,156, 3, 0, 0, 15,182, 7, 65, +/* 0x1330 */ 193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, 15,183, +/* 0x1340 */ 17, 68,137,216,193,232, 11, 15,183,202, 15,175,193, 65, 57,194, +/* 0x1350 */ 115, 39, 65,137,195,184, 0, 8, 0, 0, 69, 49,237, 41,200,193, +/* 0x1360 */ 248, 5,141, 4, 2,102, 65,137, 1, 72, 99, 68, 36,184, 72,193, +/* 0x1370 */ 224, 4, 77,141, 68, 1, 4,235,120, 65, 41,195, 65, 41,194,137, +/* 0x1380 */ 208,102,193,232, 5,102, 41,194, 65,129,251,255,255,255, 0,102, +/* 0x1390 */ 65,137, 17,119, 26, 76, 57,231, 15,132, 42, 3, 0, 0, 15,182, +/* 0x13a0 */ 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, 65, +/* 0x13b0 */ 15,183, 81, 2, 68,137,216,193,232, 11, 15,183,202, 15,175,193, +/* 0x13c0 */ 65, 57,194,115, 52, 65,137,195,184, 0, 8, 0, 0, 65,189, 8, +/* 0x13d0 */ 0, 0, 0, 41,200,193,248, 5,141, 4, 2,102, 65,137, 65, 2, +/* 0x13e0 */ 72, 99, 68, 36,184, 72,193,224, 4, 77,141,132, 1, 4, 1, 0, +/* 0x13f0 */ 0, 65,185, 3, 0, 0, 0,235, 39, 65, 41,195, 65, 41,194,137, +/* 0x1400 */ 208,102,193,232, 5, 77,141,129, 4, 2, 0, 0, 65,189, 16, 0, +/* 0x1410 */ 0, 0,102, 41,194,102, 65,137, 81, 2, 65,185, 8, 0, 0, 0, +/* 0x1420 */ 68,137,203,189, 1, 0, 0, 0, 72, 99,197, 65,129,251,255,255, +/* 0x1430 */ 255, 0, 73,141, 52, 64,119, 26, 76, 57,231, 15,132,135, 2, 0, +/* 0x1440 */ 0, 15,182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, +/* 0x1450 */ 9,194, 15,183, 14, 68,137,216,193,232, 11, 15,183,209, 15,175, +/* 0x1460 */ 194, 65, 57,194,115, 23, 65,137,195,184, 0, 8, 0, 0, 1,237, +/* 0x1470 */ 41,208,193,248, 5,141, 4, 1,102,137, 6,235, 22, 65, 41,195, +/* 0x1480 */ 65, 41,194,137,200,102,193,232, 5,141,108, 45, 1,102, 41,193, +/* 0x1490 */ 102,137, 14,255,203,117,145,184, 1, 0, 0, 0, 68,137,201,211, +/* 0x14a0 */ 224, 41,197, 68, 1,237,131,124, 36,200, 3, 15,143,194, 1, 0, +/* 0x14b0 */ 0,131, 68, 36,200, 7,184, 3, 0, 0, 0,131,253, 4, 15, 76, +/* 0x14c0 */ 197, 72,139, 92, 36,216, 65,184, 1, 0, 0, 0, 72,152, 72,193, +/* 0x14d0 */ 224, 7, 76,141,140, 3, 96, 3, 0, 0,187, 6, 0, 0, 0, 73, +/* 0x14e0 */ 99,192, 65,129,251,255,255,255, 0, 73,141, 52, 65,119, 26, 76, +/* 0x14f0 */ 57,231, 15,132,208, 1, 0, 0, 15,182, 7, 65,193,226, 8, 65, +/* 0x1500 */ 193,227, 8, 72,255,199, 65, 9,194, 15,183, 22, 68,137,216,193, +/* 0x1510 */ 232, 11, 15,183,202, 15,175,193, 65, 57,194,115, 24, 65,137,195, +/* 0x1520 */ 184, 0, 8, 0, 0, 69, 1,192, 41,200,193,248, 5,141, 4, 2, +/* 0x1530 */ 102,137, 6,235, 23, 65, 41,195, 65, 41,194,137,208,102,193,232, +/* 0x1540 */ 5, 71,141, 68, 0, 1,102, 41,194,102,137, 22,255,203,117,143, +/* 0x1550 */ 65,131,232, 64, 65,131,248, 3, 69,137,198, 15,142, 13, 1, 0, +/* 0x1560 */ 0, 65,131,230, 1, 68,137,192,209,248, 65,131,206, 2, 65,131, +/* 0x1570 */ 248, 13,141,112,255,127, 35,137,241, 72,139, 92, 36,216, 73, 99, +/* 0x1580 */ 192, 65,211,230, 72, 1,192, 68,137,242, 72,141, 20, 83, 72, 41, +/* 0x1590 */ 194, 76,141,138, 94, 5, 0, 0,235, 81,141,112,251, 65,129,251, +/* 0x15a0 */ 255,255,255, 0,119, 26, 76, 57,231, 15,132, 25, 1, 0, 0, 15, +/* 0x15b0 */ 182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, +/* 0x15c0 */ 65,209,235, 69, 1,246, 69, 57,218,114, 7, 69, 41,218, 65,131, +/* 0x15d0 */ 206, 1,255,206,117,199, 76,139, 76, 36,216, 65,193,230, 4,190, +/* 0x15e0 */ 4, 0, 0, 0, 73,129,193, 68, 6, 0, 0, 65,189, 1, 0, 0, +/* 0x15f0 */ 0,187, 1, 0, 0, 0, 72, 99,195, 65,129,251,255,255,255, 0, +/* 0x1600 */ 77,141, 4, 65,119, 26, 76, 57,231, 15,132,185, 0, 0, 0, 15, +/* 0x1610 */ 182, 7, 65,193,226, 8, 65,193,227, 8, 72,255,199, 65, 9,194, +/* 0x1620 */ 65, 15,183, 16, 68,137,216,193,232, 11, 15,183,202, 15,175,193, +/* 0x1630 */ 65, 57,194,115, 24, 65,137,195,184, 0, 8, 0, 0, 1,219, 41, +/* 0x1640 */ 200,193,248, 5,141, 4, 2,102, 65,137, 0,235, 26, 65, 41,195, +/* 0x1650 */ 65, 41,194,137,208,102,193,232, 5,141, 92, 27, 1, 69, 9,238, +/* 0x1660 */ 102, 41,194,102, 65,137, 16, 69, 1,237,255,206,117,136, 65,255, +/* 0x1670 */ 198,116, 64,131,197, 2, 69, 57,254,119, 77, 72,139, 84, 36,232, +/* 0x1680 */ 68,137,248, 68, 41,240, 68, 15,182, 44, 2, 68,137,248, 65,255, +/* 0x1690 */ 199,255,205, 68,136, 44, 2, 15,149,194, 49,192, 68, 59,124, 36, +/* 0x16a0 */ 228, 15,146,192,133,194,117,211, 68, 59,124, 36,228, 15,130, 69, +/* 0x16b0 */ 247,255,255, 65,129,251,255,255,255, 0,119, 22, 76, 57,231,184, +/* 0x16c0 */ 1, 0, 0, 0,116, 35,235, 7,184, 1, 0, 0, 0,235, 26, 72, +/* 0x16d0 */ 255,199,137,248, 43, 68, 36,248, 72,139, 76, 36,240, 72,139, 92, +/* 0x16e0 */ 36, 56,137, 1, 68,137, 59, 49,192, 91, 93, 65, 92, 65, 93, 65, +/* 0x16f0 */ 94, 65, 95, 72,139,117,248, 72,139,125, 16,139, 75, 4, 72, 1, +/* 0x1700 */ 206,139, 19, 72, 1,215,201, 89, 72,137,240, 72, 41,200, 90, 72, +/* 0x1710 */ 41,215, 89,137, 57, 91, 93,195,104, 30, 0, 0, 0, 90,232, 0, +/* 0x1720 */ 0, 0, 0, 80, 82, 79, 84, 95, 69, 88, 69, 67,124, 80, 82, 79, +/* 0x1730 */ 84, 95, 87, 82, 73, 84, 69, 32,102, 97,105,108,101,100, 46, 10, +/* 0x1740 */ 0, 94,106, 2, 95,106, 1, 88, 15, 5,106,127, 95,106, 60, 88, +/* 0x1750 */ 15, 5, 90, 72,141,114,226, 72,137,241,173, 72, 41,193,173, 72, +/* 0x1760 */ 1,200, 72,137, 69, 40,173, 72, 1,200, 72,137, 69, 16,173, 72, +/* 0x1770 */ 141, 60, 1, 72,141,119, 12, 80, 80,173,173, 72, 1,198,173,173, +/* 0x1780 */ 72,137,249,129,225,255, 15, 0, 0, 72, 1,200, 80, 72, 41,207, +/* 0x1790 */ 87, 72, 41,200, 72, 1,207, 81,232, 80, 0, 0, 0,131,249, 73, +/* 0x17a0 */ 117, 74, 72,137,241, 72,137,254,235, 44,138, 7, 72,131,199, 1, +/* 0x17b0 */ 60,128,114, 10, 60,143,119, 6,128,127,254, 15,116, 6, 44,232, +/* 0x17c0 */ 60, 1,119, 35, 56, 23,117, 31,139, 7, 37, 0,255,255,255, 15, +/* 0x17d0 */ 200, 41,248, 1,240,171, 72,131,233, 4,138, 7, 72,131,199, 1, +/* 0x17e0 */ 72,255,201,117,217,235, 5, 72,255,201,117,190,195, 15,182, 78, +/* 0x17f0 */ 5, 81, 15,182, 78, 6, 81, 80, 72,137,225, 87, 82,173,137,194, +/* 0x1800 */ 173, 80, 81, 87, 82, 86, 72,139, 69,168, 3, 80,252, 72,139, 69, +/* 0x1810 */ 208, 3, 80,252,232, 92, 0, 0, 0,106, 0, 65, 89,106, 0, 65, +/* 0x1820 */ 88,106, 50, 65, 90,106, 3, 90, 72,139,117,232, 72,139,125,224, +/* 0x1830 */ 106, 9, 88, 15, 5, 72, 57,248,116, 1,244,139, 77,216, 72,137, +/* 0x1840 */ 199, 72,139,117,240,131,193, 3,193,233, 2,243,165, 95, 94, 90, +/* 0x1850 */ 89, 65, 88, 88,255,208, 95, 94, 90, 89, 88, 72,133,201,116, 2, +/* 0x1860 */ 255,208, 89, 95, 94,106, 5, 90,106, 10, 88, 15, 5, 95, 94,106, +/* 0x1870 */ 11, 88, 93, 90,195,139,117,216, 1,214, 88, 80, 3,112,252,106, +/* 0x1880 */ 0, 65, 89,106, 0, 65, 88,106, 34, 65, 90,106, 7, 90, 72,137, +/* 0x1890 */ 117,248,106, 0, 95,106, 9, 88, 15, 5, 72, 61, 0,240,255,255, +/* 0x18a0 */ 114, 1,244, 72,137, 69,240, 72,137,199, 88,139, 77,216, 72,139, +/* 0x18b0 */ 117,224,131,193, 3,193,233, 2,243,165, 94, 89, 81, 87,131,193, +/* 0x18c0 */ 3,193,233, 2,243,165, 72,139,117,168, 72,137,125,168,139, 78, +/* 0x18d0 */ 252,243,164, 72,139,117,208, 72,137,125,208,139, 78,252,243,164, +/* 0x18e0 */ 72,137,198, 87,139, 78,252,243,164,195,102,105,108,101, 32,102, +/* 0x18f0 */ 111,114,109, 97,116, 32,101,108,102, 54, 52, 45,120, 56, 54, 45, +/* 0x1900 */ 54, 52, 10, 10, 83,101, 99,116,105,111,110,115, 58, 10, 73,100, +/* 0x1910 */ 120, 32, 78, 97,109,101, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x1920 */ 83,105,122,101, 32, 32, 32, 32, 32, 32, 86, 77, 65, 32, 32, 32, +/* 0x1930 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 76, 77, 65, 32, +/* 0x1940 */ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 70,105, +/* 0x1950 */ 108,101, 32,111,102,102, 32, 32, 65,108,103,110, 32, 32, 70,108, +/* 0x1960 */ 97,103,115, 10, 32, 32, 48, 32, 69, 76, 70, 77, 65, 73, 78, 88, +/* 0x1970 */ 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, 49, 54, 32, 32, +/* 0x1980 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1990 */ 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x19a0 */ 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 52, 48, 32, 32, 50, 42, +/* 0x19b0 */ 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, +/* 0x19c0 */ 76, 79, 67, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, +/* 0x19d0 */ 49, 32, 78, 82, 86, 95, 72, 69, 65, 68, 32, 32, 32, 32, 32, 32, +/* 0x19e0 */ 48, 48, 48, 48, 48, 48, 54, 54, 32, 32, 48, 48, 48, 48, 48, 48, +/* 0x19f0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, +/* 0x1a00 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, +/* 0x1a10 */ 48, 48, 48, 48, 53, 54, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, +/* 0x1a20 */ 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, +/* 0x1a30 */ 10, 32, 32, 50, 32, 78, 82, 86, 50, 69, 32, 32, 32, 32, 32, 32, +/* 0x1a40 */ 32, 32, 32, 48, 48, 48, 48, 48, 48, 98, 55, 32, 32, 48, 48, 48, +/* 0x1a50 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x1a60 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, +/* 0x1a70 */ 32, 48, 48, 48, 48, 48, 48, 98, 99, 32, 32, 50, 42, 42, 48, 32, +/* 0x1a80 */ 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 76, 79, 67, +/* 0x1a90 */ 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 51, 32, 78, +/* 0x1aa0 */ 82, 86, 50, 68, 32, 32, 32, 32, 32, 32, 32, 32, 32, 48, 48, 48, +/* 0x1ab0 */ 48, 48, 48, 57,101, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1ac0 */ 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, +/* 0x1ad0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, +/* 0x1ae0 */ 49, 55, 51, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, +/* 0x1af0 */ 78, 84, 83, 44, 32, 82, 69, 76, 79, 67, 44, 32, 82, 69, 65, 68, +/* 0x1b00 */ 79, 78, 76, 89, 10, 32, 32, 52, 32, 78, 82, 86, 50, 66, 32, 32, +/* 0x1b10 */ 32, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, 57, 48, 32, +/* 0x1b20 */ 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1b30 */ 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1b40 */ 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 50, 49, 49, 32, 32, 50, +/* 0x1b50 */ 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, +/* 0x1b60 */ 69, 76, 79, 67, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, +/* 0x1b70 */ 32, 53, 32, 76, 90, 77, 65, 95, 69, 76, 70, 48, 48, 32, 32, 32, +/* 0x1b80 */ 32, 48, 48, 48, 48, 48, 48, 54, 52, 32, 32, 48, 48, 48, 48, 48, +/* 0x1b90 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, +/* 0x1ba0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x1bb0 */ 48, 48, 48, 48, 50, 97, 49, 32, 32, 50, 42, 42, 48, 32, 32, 67, +/* 0x1bc0 */ 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 76, 79, 67, 44, 32, +/* 0x1bd0 */ 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 54, 32, 76, 90, 77, +/* 0x1be0 */ 65, 95, 68, 69, 67, 49, 48, 32, 32, 32, 32, 48, 48, 48, 48, 48, +/* 0x1bf0 */ 57,102, 55, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1c00 */ 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1c10 */ 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 51, 48, +/* 0x1c20 */ 53, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, +/* 0x1c30 */ 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, 32, 55, 32, +/* 0x1c40 */ 76, 90, 77, 65, 95, 68, 69, 67, 50, 48, 32, 32, 32, 32, 48, 48, +/* 0x1c50 */ 48, 48, 48, 57,102, 55, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1c60 */ 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, +/* 0x1c70 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, +/* 0x1c80 */ 48, 99,102, 99, 32, 32, 50, 42, 42, 48, 32, 32, 67, 79, 78, 84, +/* 0x1c90 */ 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, +/* 0x1ca0 */ 32, 56, 32, 76, 90, 77, 65, 95, 68, 69, 67, 51, 48, 32, 32, 32, +/* 0x1cb0 */ 32, 48, 48, 48, 48, 48, 48, 49, 52, 32, 32, 48, 48, 48, 48, 48, +/* 0x1cc0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, +/* 0x1cd0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x1ce0 */ 48, 48, 48, 49, 54,102, 51, 32, 32, 50, 42, 42, 48, 32, 32, 67, +/* 0x1cf0 */ 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, +/* 0x1d00 */ 89, 10, 32, 32, 57, 32, 78, 82, 86, 95, 84, 65, 73, 76, 32, 32, +/* 0x1d10 */ 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, +/* 0x1d20 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, +/* 0x1d30 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1d40 */ 32, 32, 48, 48, 48, 48, 49, 55, 48, 55, 32, 32, 50, 42, 42, 48, +/* 0x1d50 */ 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, +/* 0x1d60 */ 79, 78, 76, 89, 10, 32, 49, 48, 32, 69, 76, 70, 77, 65, 73, 78, +/* 0x1d70 */ 89, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 48, 51, 97, 32, +/* 0x1d80 */ 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1d90 */ 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1da0 */ 48, 48, 48, 32, 32, 48, 48, 48, 48, 49, 55, 48, 55, 32, 32, 50, +/* 0x1db0 */ 42, 42, 48, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, +/* 0x1dc0 */ 69, 76, 79, 67, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, 32, +/* 0x1dd0 */ 49, 49, 32, 69, 76, 70, 77, 65, 73, 78, 90, 32, 32, 32, 32, 32, +/* 0x1de0 */ 32, 48, 48, 48, 48, 48, 49, 97, 57, 32, 32, 48, 48, 48, 48, 48, +/* 0x1df0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, 48, 48, +/* 0x1e00 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 48, +/* 0x1e10 */ 48, 48, 48, 49, 55, 52, 49, 32, 32, 50, 42, 42, 48, 32, 32, 67, +/* 0x1e20 */ 79, 78, 84, 69, 78, 84, 83, 44, 32, 82, 69, 65, 68, 79, 78, 76, +/* 0x1e30 */ 89, 10, 83, 89, 77, 66, 79, 76, 32, 84, 65, 66, 76, 69, 58, 10, +/* 0x1e40 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1e50 */ 32,108, 32, 32, 32, 32,100, 32, 32, 78, 82, 86, 95, 72, 69, 65, +/* 0x1e60 */ 68, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1e70 */ 48, 48, 32, 78, 82, 86, 95, 72, 69, 65, 68, 10, 48, 48, 48, 48, +/* 0x1e80 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, +/* 0x1e90 */ 32, 32,100, 32, 32, 76, 90, 77, 65, 95, 68, 69, 67, 51, 48, 9, +/* 0x1ea0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1eb0 */ 32, 76, 90, 77, 65, 95, 68, 69, 67, 51, 48, 10, 48, 48, 48, 48, +/* 0x1ec0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, +/* 0x1ed0 */ 32, 32,100, 32, 32, 69, 76, 70, 77, 65, 73, 78, 89, 9, 48, 48, +/* 0x1ee0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 69, +/* 0x1ef0 */ 76, 70, 77, 65, 73, 78, 89, 10, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1f00 */ 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, +/* 0x1f10 */ 32, 69, 76, 70, 77, 65, 73, 78, 90, 9, 48, 48, 48, 48, 48, 48, +/* 0x1f20 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 69, 76, 70, 77, 65, +/* 0x1f30 */ 73, 78, 90, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1f40 */ 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 69, 76, 70, +/* 0x1f50 */ 77, 65, 73, 78, 88, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1f60 */ 48, 48, 48, 48, 48, 48, 32, 69, 76, 70, 77, 65, 73, 78, 88, 10, +/* 0x1f70 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1f80 */ 32,108, 32, 32, 32, 32,100, 32, 32, 78, 82, 86, 50, 69, 9, 48, +/* 0x1f90 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, +/* 0x1fa0 */ 78, 82, 86, 50, 69, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1fb0 */ 48, 48, 48, 48, 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 78, +/* 0x1fc0 */ 82, 86, 50, 68, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x1fd0 */ 48, 48, 48, 48, 48, 32, 78, 82, 86, 50, 68, 10, 48, 48, 48, 48, +/* 0x1fe0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, 32, 32, +/* 0x1ff0 */ 32, 32,100, 32, 32, 78, 82, 86, 50, 66, 9, 48, 48, 48, 48, 48, +/* 0x2000 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 78, 82, 86, 50, +/* 0x2010 */ 66, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2020 */ 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 76, 90, 77, 65, 95, +/* 0x2030 */ 69, 76, 70, 48, 48, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2040 */ 48, 48, 48, 48, 48, 48, 32, 76, 90, 77, 65, 95, 69, 76, 70, 48, +/* 0x2050 */ 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2060 */ 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 76, 90, 77, 65, 95, +/* 0x2070 */ 68, 69, 67, 49, 48, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2080 */ 48, 48, 48, 48, 48, 48, 32, 76, 90, 77, 65, 95, 68, 69, 67, 49, +/* 0x2090 */ 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x20a0 */ 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 76, 90, 77, 65, 95, +/* 0x20b0 */ 68, 69, 67, 50, 48, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x20c0 */ 48, 48, 48, 48, 48, 48, 32, 76, 90, 77, 65, 95, 68, 69, 67, 50, +/* 0x20d0 */ 48, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x20e0 */ 48, 48, 32,108, 32, 32, 32, 32,100, 32, 32, 78, 82, 86, 95, 84, +/* 0x20f0 */ 65, 73, 76, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2100 */ 48, 48, 48, 48, 32, 78, 82, 86, 95, 84, 65, 73, 76, 10, 48, 48, +/* 0x2110 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,103, +/* 0x2120 */ 32, 32, 32, 32, 32, 32, 32, 69, 76, 70, 77, 65, 73, 78, 88, 9, +/* 0x2130 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2140 */ 32, 95,115,116, 97,114,116, 10, 10, 82, 69, 76, 79, 67, 65, 84, +/* 0x2150 */ 73, 79, 78, 32, 82, 69, 67, 79, 82, 68, 83, 32, 70, 79, 82, 32, +/* 0x2160 */ 91, 69, 76, 70, 77, 65, 73, 78, 88, 93, 58, 10, 79, 70, 70, 83, +/* 0x2170 */ 69, 84, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 84, 89, 80, +/* 0x2180 */ 69, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, +/* 0x2190 */ 65, 76, 85, 69, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x21a0 */ 48, 48, 48, 48, 97, 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 80, +/* 0x21b0 */ 67, 51, 50, 32, 32, 32, 32, 32, 69, 76, 70, 77, 65, 73, 78, 90, +/* 0x21c0 */ 43, 48,120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x21d0 */ 48, 48,100, 10, 10, 82, 69, 76, 79, 67, 65, 84, 73, 79, 78, 32, +/* 0x21e0 */ 82, 69, 67, 79, 82, 68, 83, 32, 70, 79, 82, 32, 91, 78, 82, 86, +/* 0x21f0 */ 50, 69, 93, 58, 10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 32, 32, +/* 0x2200 */ 32, 32, 32, 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, 32, 32, 32, +/* 0x2210 */ 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, 10, 48, 48, +/* 0x2220 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 97,101, 32, 82, +/* 0x2230 */ 95, 88, 56, 54, 95, 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, +/* 0x2240 */ 32, 78, 82, 86, 95, 72, 69, 65, 68, 43, 48,120, 48, 48, 48, 48, +/* 0x2250 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, 49, 10, 48, 48, 48, +/* 0x2260 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 98, 32, 82, 95, +/* 0x2270 */ 88, 56, 54, 95, 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, 32, +/* 0x2280 */ 69, 76, 70, 77, 65, 73, 78, 89, 43, 48,120,102,102,102,102,102, +/* 0x2290 */ 102,102,102,102,102,102,102,102,102,102, 99, 10, 10, 82, 69, 76, +/* 0x22a0 */ 79, 67, 65, 84, 73, 79, 78, 32, 82, 69, 67, 79, 82, 68, 83, 32, +/* 0x22b0 */ 70, 79, 82, 32, 91, 78, 82, 86, 50, 68, 93, 58, 10, 79, 70, 70, +/* 0x22c0 */ 83, 69, 84, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 84, 89, +/* 0x22d0 */ 80, 69, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x22e0 */ 86, 65, 76, 85, 69, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x22f0 */ 48, 48, 48, 48, 57, 53, 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, +/* 0x2300 */ 80, 67, 51, 50, 32, 32, 32, 32, 32, 78, 82, 86, 95, 72, 69, 65, +/* 0x2310 */ 68, 43, 48,120, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2320 */ 48, 48, 50, 49, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, +/* 0x2330 */ 48, 48, 48, 53, 98, 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 80, +/* 0x2340 */ 67, 51, 50, 32, 32, 32, 32, 32, 69, 76, 70, 77, 65, 73, 78, 89, +/* 0x2350 */ 43, 48,120,102,102,102,102,102,102,102,102,102,102,102,102,102, +/* 0x2360 */ 102,102, 99, 10, 10, 82, 69, 76, 79, 67, 65, 84, 73, 79, 78, 32, +/* 0x2370 */ 82, 69, 67, 79, 82, 68, 83, 32, 70, 79, 82, 32, 91, 78, 82, 86, +/* 0x2380 */ 50, 66, 93, 58, 10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 32, 32, +/* 0x2390 */ 32, 32, 32, 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, 32, 32, 32, +/* 0x23a0 */ 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, 10, 48, 48, +/* 0x23b0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, 97, 32, 82, +/* 0x23c0 */ 95, 88, 56, 54, 95, 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, +/* 0x23d0 */ 32, 78, 82, 86, 95, 72, 69, 65, 68, 43, 48,120, 48, 48, 48, 48, +/* 0x23e0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, 49, 10, 48, 48, 48, +/* 0x23f0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 50, 32, 82, 95, +/* 0x2400 */ 88, 56, 54, 95, 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, 32, +/* 0x2410 */ 69, 76, 70, 77, 65, 73, 78, 89, 43, 48,120,102,102,102,102,102, +/* 0x2420 */ 102,102,102,102,102,102,102,102,102,102, 99, 10, 10, 82, 69, 76, +/* 0x2430 */ 79, 67, 65, 84, 73, 79, 78, 32, 82, 69, 67, 79, 82, 68, 83, 32, +/* 0x2440 */ 70, 79, 82, 32, 91, 76, 90, 77, 65, 95, 69, 76, 70, 48, 48, 93, +/* 0x2450 */ 58, 10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x2460 */ 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x2470 */ 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, 10, 48, 48, 48, 48, 48, +/* 0x2480 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 54, 32, 82, 95, 88, 56, +/* 0x2490 */ 54, 95, 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, 32, 76, 90, +/* 0x24a0 */ 77, 65, 95, 68, 69, 67, 51, 48, 43, 48,120, 48, 48, 48, 48, 48, +/* 0x24b0 */ 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 48, 10, 10, 82, 69, 76, +/* 0x24c0 */ 79, 67, 65, 84, 73, 79, 78, 32, 82, 69, 67, 79, 82, 68, 83, 32, +/* 0x24d0 */ 70, 79, 82, 32, 91, 69, 76, 70, 77, 65, 73, 78, 89, 93, 58, 10, +/* 0x24e0 */ 79, 70, 70, 83, 69, 84, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x24f0 */ 32, 84, 89, 80, 69, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +/* 0x2500 */ 32, 32, 32, 86, 65, 76, 85, 69, 10, 48, 48, 48, 48, 48, 48, 48, +/* 0x2510 */ 48, 48, 48, 48, 48, 48, 48, 49, 56, 32, 82, 95, 88, 56, 54, 95, +/* 0x2520 */ 54, 52, 95, 80, 67, 51, 50, 32, 32, 32, 32, 32, 69, 76, 70, 77, +/* 0x2530 */ 65, 73, 78, 90, 43, 48,120,102,102,102,102,102,102,102,102,102, +/* 0x2540 */ 102,102,102,102,102,102, 99, 10 +}; diff --git a/src/stub/src/amd64-linux.shlib-init.S b/src/stub/src/amd64-linux.shlib-init.S new file mode 100644 index 00000000..4ebd86b6 --- /dev/null +++ b/src/stub/src/amd64-linux.shlib-init.S @@ -0,0 +1,411 @@ +/* amd64-linux.shlib-init.S -- Linux program entry point & decompressor (Elf shared lib) +* +* This file is part of the UPX executable compressor. +* +* Copyright (C) 1996-2009 Markus Franz Xaver Johannes Oberhumer +* Copyright (C) 1996-2009 Laszlo Molnar +* Copyright (C) 2000-2009 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 +* +*/ + +#include "arch/amd64/macros.S" +#include "arch/amd64/regs.h" + +sz_Ehdr= 64 +sz_Phdr= 56 + +sz_l_info= 12 + l_lsize= 8 + +sz_p_info= 12 + +sz_b_info= 12 + sz_unc= 0 + sz_cpr= 4 + b_method= 8 + +PROT_READ= 1 +PROT_WRITE= 2 +PROT_EXEC= 4 + +MAP_PRIVATE= 2 +MAP_FIXED= 0x10 +MAP_ANONYMOUS= 0x20 + +__NR_mmap= 9 // 64-bit mode only! /usr/include/asm/unistd_64.h +__NR_mprotect= 10 +__NR_munmap= 11 + +__NR_write= 1 +__NR_exit= 60 + +PAGE_SHIFT= 12 +PAGE_MASK= (~0<likely, n==>unlikely} */ +/* Prediction omitted for now. */ +/* On refill: prefetch next byte, for latency reduction on literals and offsets. */ +#define jnextb0np jnextb0yp +#define jnextb0yp GETBITp; jnc +#define jnextb1np jnextb1yp +#define jnextb1yp GETBITp; jc +#define GETBITp \ + addl bits,bits; jnz 0f; \ + movl (%rsi),bits; subq $-4,%rsi; \ + adcl bits,bits; movb (%rsi),%dl; \ +0: +/* Same, but without prefetch (not useful for length of match.) */ +#define jnextb0n jnextb0y +#define jnextb0y GETBIT; jnc +#define jnextb1n jnextb1y +#define jnextb1y GETBIT; jc +#define GETBIT \ + addl bits,bits; jnz 0f; \ + movl (%rsi),bits; subq $-4,%rsi; \ + adcl bits,bits; \ +0: + +/* rotate next bit into bottom bit of reg */ +#define getnextbp(reg) call *%r11; adcl reg,reg +#define getnextb(reg) getnextbp(reg) + + +getbit: + addl bits,bits; jz refill // Carry= next bit + rep; ret +refill: + movl (%rsi),bits; subq $-4,%rsi // next 32 bits; set Carry + adcl bits,bits // LSB= 1 (CarryIn); CarryOut= next bit + movb (%rsi),%dl // speculate: literal, or bottom 8 bits of offset + rep; ret + +copy: // In: len, %rdi, disp; Out: 0==len, %rdi, disp; trashes %rax, %rdx + leaq (%rdi,disp),%rax; cmpl $5,len // <=3 is forced + movb (%rax),%dl; jbe copy1 // <=5 for better branch predict + cmpq $-4,disp; ja copy1 // 4-byte chunks would overlap + subl $4,len // adjust for termination cases +copy4: + movl (%rax),%edx; addq $4, %rax; subl $4,len + movl %edx,(%rdi); leaq 4(%rdi),%rdi; jnc copy4 + addl $4,len; movb (%rax),%dl; jz copy0 +copy1: + incq %rax; movb %dl,(%rdi); subl $1,len + movb (%rax),%dl + leaq 1(%rdi),%rdi; jnz copy1 +copy0: + rep; ret + +setup: + cld + pop %r11 // addq $ getbit - ra_setup,%r11 # &getbit + + section NRV2E +#include "arch/amd64/nrv2e_d.S" + + section NRV2D +#include "arch/amd64/nrv2d_d.S" + + section NRV2B +#include "arch/amd64/nrv2b_d.S" + +#include "arch/amd64/lzma_d.S" + + section NRV_TAIL + // empty + +#undef off +#undef len +#undef lenq +#undef bits +#undef disp + + section ELFMAINY +eof: + pop %rcx // &input_eof + movq %rsi,%rax; subq %rcx,%rax // src -= eof; // return 0: good; else: bad + pop %rdx; subq %rdx,%rdi // dst -= original dst + pop %rcx; movl %edi,(%rcx) // actual length used at dst XXX: 4GB + pop %rbx; pop %rbp + ret + +msg_SELinux: + push $ L71 - L70; pop %arg3 // length + call L72 +L70: + .asciz "PROT_EXEC|PROT_WRITE failed.\n" +L71: + // IDENTSTR goes here + + section ELFMAINZ +L72: + pop %arg2 // message text + push $2; pop %arg1 // fd stderr + push $ __NR_write; pop %rax + syscall +die: + push $127; pop %arg1 + push $ __NR_exit; pop %rax + syscall + +main: +//// nop; int3; int3 + +// 1. allocate temporary pages +// 2. copy to temporary pages: +// fragment of page below dst; compressed src; +// decompress+unfilter; supervise +// 3. mmap destination pages for decompressed data +// 4. create escape hatch +// 5. jump to temporary pages +// 6. uncompress +// 7. unfilter +// 8. mprotect decompressed pages +// 9 setup args for unmap of temp pages +// 10. jump to escape hatch +// 11. unmap temporary pages +// 12. goto user DT_INIT + + pop %rdx // &decompress + + lea _start - decompress - 4*4(%rdx),%rsi + mov %rsi,%rcx + lodsl; sub %rax,%rcx; //mov %rcx,o_reloc(%rbp) + lodsl; add %rcx,%rax; mov %rax,o_uinit(%rbp) // reloc DT_INIT for step 12 + lodsl; add %rcx,%rax; mov %rax,o_hatch(%rbp) // reloc &hatch for step 10 + lodsl; lea (%rcx,%rax),%rdi // &p_info; also destination for decompress + lea sz_p_info(%rdi),%rsi // &b_info + + push %rax; push %rax // param space: munmap temp pages step 9 +p_unmap= -2*8 + + lodsl; lodsl; add %rax,%rsi; lodsl // skip unpack helper block + + lodsl // eax=dstlen + mov %rdi,%rcx + and $~PAGE_MASK,%ecx // %ecx= fragment + add %rcx,%rax; push %rax // params: mprotect restored pages step 8 + sub %rcx,%rdi; push %rdi +p_mprot= -4*8 + sub %rcx,%rax // restore + add %rcx,%rdi + push %rcx // fragment +o_frag = -5*8 + + call L210 +#include "arch/amd64/bxx.S" +L210: +o_unflt= -6*8 + movzbl b_method-4+1(%rsi),%ecx; push %rcx // ftid + movzbl b_method-4+2(%rsi),%ecx; push %rcx // cto8 + push %rax; mov %rsp,%rcx // dstlen also for unfilter step 7 + push %rdi // dst param for unfilter step 7 +p_unflt= -10*8 + + push %rdx // &decompress +o_uncpr= -11*8 + lodsl; mov %eax,%edx // %rdx= srclen + lodsl; push %rax // method,filter,cto,junk + push %rcx // &dstlen + push %rdi // dst + push %rdx // srclen + push %rsi // src; arglist ready for decompress step 6 +p_uncpr= -16*8 + + mov o_uncpr(%rbp),%rax; add -4(%rax),%edx // l_d_cpr + l_f_unc + mov o_unflt(%rbp),%rax; add -4(%rax),%edx // l_d_cpr + l_f_unc + l_f_unf + + call L220 +supervise: + // Allocate pages for result of decompressing. + // These replace the compressed source and the following hole. + push $0; pop %arg6 + push $0; pop %arg5 + push $MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED; pop %sys4 + push $PROT_READ|PROT_WRITE; pop %arg3 + movq p_mprot+8(%rbp),%arg2 // dstlen + movq p_mprot (%rbp),%arg1 // dst + push $__NR_mmap; pop %rax; syscall + cmp %arg1,%rax; je 0f; hlt; 0: + + // Restore fragment of page below dst + movl o_frag(%rbp),%ecx + mov %rax,%rdi + mov p_unmap(%rbp),%rsi + add $3,%ecx; shr $2,%ecx // FIXME: is this safe? + rep movsl + + pop %arg1 + pop %arg2 + pop %arg3 + pop %arg4 + pop %arg5 + pop %rax; call *%rax // decompress +//p_unflt + pop %arg1 + pop %arg2 + pop %arg3 + pop %arg4 + pop %rax; + test %arg4,%arg4; je 0f // 0==ftid ==> no filter + call *%rax // unfilter +0: + pop %rcx // toss fragment +//p_mprot + pop %arg1 // dst including fragment + pop %arg2 // dstlen + push $PROT_READ|PROT_EXEC; pop %arg3 + push $__NR_mprotect; pop %rax; syscall +//p_unmap + pop %arg1 // &temp pages + pop %arg2 // length + push $__NR_munmap; pop %rax + +//// nop; int3; int3 + + pop %rbp + pop %arg3 // third arg to DT_INIT() + ret // goto escape hatch +//hatch: +// syscall // munmap temporary pages +// pop %arg1 // first two args to DT_INIT() +// pop %arg2 +// ret // goto user DT_INIT + +L220: + mov o_frag(%rbp),%arg2l // fragment + add %edx,%arg2l // + l_d_cpr + l_f_unc + l_f_unf + pop %rax; push %rax // &supervise + add -4(%rax),%arg2l // total length to allocate + + // Allocate pages to hold temporary copy. + push $0; pop %arg6 + push $0; pop %arg5 + push $MAP_PRIVATE|MAP_ANONYMOUS; pop %sys4 + push $PROT_READ|PROT_WRITE|PROT_EXEC; pop %arg3 + mov %arg2,p_unmap+8(%rbp) // length to unmap + push $0; pop %arg1 // addr + push $__NR_mmap; pop %rax; syscall + cmpq $PAGE_MASK,%rax; jb 0f; hlt; 0: + + mov %rax,p_unmap (%rbp) // addr + mov %rax,%rdi // %rdi= dst + pop %rax // &supervise + mov o_frag(%rbp),%ecx // fragment +//p_uncpr + mov p_mprot(%rbp),%rsi + add $3,%ecx; shr $2,%ecx // FIXME: is this safe? + rep movsl // copy the fragment + + pop %rsi // &src data (after fragment) + pop %rcx; push %rcx // length + push %rdi // &copied data (after fragment) + add $3,%ecx; shr $2,%ecx + rep movsl // copy compressed data + + mov o_uncpr(%rbp),%rsi + mov %rdi,o_uncpr(%rbp) + mov -4(%rsi),%ecx + rep movsb // copy decompressor + + mov o_unflt(%rbp),%rsi + mov %rdi,o_unflt(%rbp) + mov -4(%rsi),%ecx + rep movsb // copy unfilter + +//o_super + mov %rax,%rsi // %rsi= &supervise + push %rdi // &copied + mov -4(%rsi),%ecx + rep movsb // copy supervisor + + ret // goto copied supervise: + +/*__XTHEENDX__*/ + +/* +vi:ts=8:et:nowrap + */ + diff --git a/src/stub/tmp/amd64-linux.shlib-init.bin.dump b/src/stub/tmp/amd64-linux.shlib-init.bin.dump new file mode 100644 index 00000000..304c45b3 --- /dev/null +++ b/src/stub/tmp/amd64-linux.shlib-init.bin.dump @@ -0,0 +1,57 @@ +file format elf64-x86-64 + +Sections: +Idx Name Size VMA LMA File off Algn Flags + 0 ELFMAINX 00000016 0000000000000000 0000000000000000 00000040 2**0 CONTENTS, RELOC, READONLY + 1 NRV_HEAD 00000066 0000000000000000 0000000000000000 00000056 2**0 CONTENTS, READONLY + 2 NRV2E 000000b7 0000000000000000 0000000000000000 000000bc 2**0 CONTENTS, RELOC, READONLY + 3 NRV2D 0000009e 0000000000000000 0000000000000000 00000173 2**0 CONTENTS, RELOC, READONLY + 4 NRV2B 00000090 0000000000000000 0000000000000000 00000211 2**0 CONTENTS, RELOC, READONLY + 5 LZMA_ELF00 00000064 0000000000000000 0000000000000000 000002a1 2**0 CONTENTS, RELOC, READONLY + 6 LZMA_DEC10 000009f7 0000000000000000 0000000000000000 00000305 2**0 CONTENTS, READONLY + 7 LZMA_DEC20 000009f7 0000000000000000 0000000000000000 00000cfc 2**0 CONTENTS, READONLY + 8 LZMA_DEC30 00000014 0000000000000000 0000000000000000 000016f3 2**0 CONTENTS, READONLY + 9 NRV_TAIL 00000000 0000000000000000 0000000000000000 00001707 2**0 CONTENTS, READONLY + 10 ELFMAINY 0000003a 0000000000000000 0000000000000000 00001707 2**0 CONTENTS, RELOC, READONLY + 11 ELFMAINZ 000001a9 0000000000000000 0000000000000000 00001741 2**0 CONTENTS, READONLY +SYMBOL TABLE: +0000000000000000 l d NRV_HEAD 0000000000000000 NRV_HEAD +0000000000000000 l d LZMA_DEC30 0000000000000000 LZMA_DEC30 +0000000000000000 l d ELFMAINY 0000000000000000 ELFMAINY +0000000000000000 l d ELFMAINZ 0000000000000000 ELFMAINZ +0000000000000000 l d ELFMAINX 0000000000000000 ELFMAINX +0000000000000000 l d NRV2E 0000000000000000 NRV2E +0000000000000000 l d NRV2D 0000000000000000 NRV2D +0000000000000000 l d NRV2B 0000000000000000 NRV2B +0000000000000000 l d LZMA_ELF00 0000000000000000 LZMA_ELF00 +0000000000000000 l d LZMA_DEC10 0000000000000000 LZMA_DEC10 +0000000000000000 l d LZMA_DEC20 0000000000000000 LZMA_DEC20 +0000000000000000 l d NRV_TAIL 0000000000000000 NRV_TAIL +0000000000000000 g ELFMAINX 0000000000000000 _start + +RELOCATION RECORDS FOR [ELFMAINX]: +OFFSET TYPE VALUE +000000000000000a R_X86_64_PC32 ELFMAINZ+0x000000000000000d + +RELOCATION RECORDS FOR [NRV2E]: +OFFSET TYPE VALUE +00000000000000ae R_X86_64_PC32 NRV_HEAD+0x0000000000000021 +000000000000005b R_X86_64_PC32 ELFMAINY+0xfffffffffffffffc + +RELOCATION RECORDS FOR [NRV2D]: +OFFSET TYPE VALUE +0000000000000095 R_X86_64_PC32 NRV_HEAD+0x0000000000000021 +000000000000005b R_X86_64_PC32 ELFMAINY+0xfffffffffffffffc + +RELOCATION RECORDS FOR [NRV2B]: +OFFSET TYPE VALUE +000000000000008a R_X86_64_PC32 NRV_HEAD+0x0000000000000021 +0000000000000052 R_X86_64_PC32 ELFMAINY+0xfffffffffffffffc + +RELOCATION RECORDS FOR [LZMA_ELF00]: +OFFSET TYPE VALUE +0000000000000006 R_X86_64_PC32 LZMA_DEC30+0x0000000000000010 + +RELOCATION RECORDS FOR [ELFMAINY]: +OFFSET TYPE VALUE +0000000000000018 R_X86_64_PC32 ELFMAINZ+0xfffffffffffffffc