Reduce EXE and DLL Size with LIBCTINY.LIB figure

来源:互联网 发布:搜索引擎优化期末考试 编辑:程序博客网 时间:2024/05/20 19:19
 
Figure 1

Figure 1 Hello World .MAP File

Address         Publics by Value              Rva+Base     Lib:Object
0001:00000000 _main 00401000 f hello.obj
0001:0000000c _printf 0040100c f LIBC:printf.obj
0001:0000003d _mainCRTStartup 0040103d f LIBC:crt0.obj
0001:0000011c __amsg_exit 0040111c f LIBC:crt0.obj
0001:00000165 __stbuf 00401165 f LIBC:_sftbuf.obj
0001:000001f2 __ftbuf 004011f2 f LIBC:_sftbuf.obj
0001:0000022f __output 0040122f f LIBC:output.obj
0001:00000a39 ___initstdio 00401a39 f LIBC:_file.obj
0001:00000ade ___endstdio 00401ade f LIBC:_file.obj
0001:00000af2 __cinit 00401af2 f LIBC:crt0dat.obj
0001:00000b1f _exit 00401b1f f LIBC:crt0dat.obj
0001:00000b30 __exit 00401b30 f LIBC:crt0dat.obj
0001:00000bf4 __XcptFilter 00401bf4 f LIBC:winxfltr.obj
0001:00000d78 __setenvp 00401d78 f LIBC:stdenvp.obj
0001:00000e31 __setargv 00401e31 f LIBC:stdargv.obj
0001:0000107e ___crtGetEnvironmentStringsA 0040207e f LIBC:a_env.obj
0001:000011b0 __ioinit 004021b0 f LIBC:ioinit.obj
0001:0000135b __heap_init 0040235b f LIBC:heapinit.obj
0001:00001398 __global_unwind2 00402398 f LIBC:exsup.obj
0001:000013da __local_unwind2 004023da f LIBC:exsup.obj
0001:00001432 __NLG_Return2 00402432 f LIBC:exsup.obj
0001:00001442 __abnormal_termination 00402442 f LIBC:exsup.obj
0001:00001465 __NLG_Notify1 00402465 f LIBC:exsup.obj
0001:0000146e __NLG_Notify 0040246e f LIBC:exsup.obj
0001:00001481 __NLG_Dispatch 00402481 f LIBC:exsup.obj
0001:00001490 __except_handler3 00402490 f LIBC:exsup3.obj
0001:0000154d __seh_longjmp_unwind@4 0040254d f LIBC:exsup3.obj
0001:00001568 __FF_MSGBANNER 00402568 f LIBC:crt0msg.obj
0001:000015a1 __NMSG_WRITE 004025a1 f LIBC:crt0msg.obj
0001:000016f4 _malloc 004026f4 f LIBC:malloc.obj
0001:00001706 __nh_malloc 00402706 f LIBC:malloc.obj
0001:00001732 __heap_alloc 00402732 f LIBC:malloc.obj
0001:00001768 __isatty 00402768 f LIBC:isatty.obj
0001:0000178e _fflush 0040278e f LIBC:fflush.obj
0001:000017c9 __flush 004027c9 f LIBC:fflush.obj
0001:00001825 __flushall 00402825 f LIBC:fflush.obj
0001:000018a0 _strlen 004028a0 f LIBC:strlen.obj
0001:0000191b _wctomb 0040291b f LIBC:wctomb.obj
0001:00001990 __aulldiv 00402990 f LIBC:ulldiv.obj
0001:00001a00 __aullrem 00402a00 f LIBC:ullrem.obj
0001:00001a75 __flsbuf 00402a75 f LIBC:_flsbuf.obj
0001:00001b8a _calloc 00402b8a f LIBC:calloc.obj
0001:00001c07 __fcloseall 00402c07 f LIBC:closeall.obj
0001:00001c5f _free 00402c5f f LIBC:free.obj
0001:00001c90 _strcpy 00402c90 f LIBC:strcat.obj
0001:00001ca0 _strcat 00402ca0 f LIBC:strcat.obj
0001:00001d80 __setmbcp 00402d80 f LIBC:mbctype.obj
0001:00002144 ___initmbctable 00403144 f LIBC:mbctype.obj
0001:00002160 _memcpy 00403160 f LIBC:memcpy.obj
0001:00002495 ___sbh_heap_init 00403495 f LIBC:sbheap.obj
0001:000024d3 ___sbh_find_block 004034d3 f LIBC:sbheap.obj
0001:000024fe ___sbh_free_block 004034fe f LIBC:sbheap.obj
0001:00002829 ___sbh_alloc_block 00403829 f LIBC:sbheap.obj
0001:00002b32 ___sbh_alloc_new_region 00403b32 f LIBC:sbheap.obj
0001:00002be3 ___sbh_alloc_new_group 00403be3 f LIBC:sbheap.obj
0001:00002cde ___crtMessageBoxA 00403cde f LIBC:crtmbox.obj
0001:00002d70 _strncpy 00403d70 f LIBC:strncpy.obj
0001:00002e6e __callnewh 00403e6e f LIBC:handler.obj
0001:00002e89 __commit 00403e89 f LIBC:commit.obj
0001:00002ee0 __write 00403ee0 f LIBC:write.obj
0001:0000308d __fptrap 0040408d f LIBC:crt0fp.obj
0001:00003096 __lseek 00404096 f LIBC:lseek.obj
0001:00003130 __getbuf 00404130 f LIBC:_getbuf.obj
0001:00003180 _memset 00404180 f LIBC:memset.obj
0001:000031d8 _fclose 004041d8 f LIBC:fclose.obj
0001:0000322e ___crtLCMapStringA 0040422e f LIBC:a_map.obj
0001:0000347d ___crtGetStringTypeA 0040447d f LIBC:a_str.obj
0001:000035d0 _memmove 004045d0 f LIBC:memmove.obj
0001:00003905 __free_osfhnd 00404905 f LIBC:osfinfo.obj
0001:0000397f __get_osfhandle 0040497f f LIBC:osfinfo.obj
0001:000039bc __dosmaperr 004049bc f LIBC:dosmap.obj
0001:00003a23 __close 00404a23 f LIBC:close.obj
0001:00003ad6 __freebuf 00404ad6 f LIBC:_freebuf.obj
0001:00003b10 __alloca_probe 00404b10 f LIBC:chkstk.obj
0001:00003b10 __chkstk 00404b10 f LIBC:chkstk.obj

Figure 2 printf.cpp

//==========================================
// LIBCTINY - Matt Pietrek 2001
// MSDN Magazine, January 2001
//==========================================
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>

// Force the linker to include USER32.LIB
#pragma comment(linker, "/defaultlib:user32.lib")

extern "C" int __cdecl printf(const char * format, ...)
{
char szBuff[1024];
int retValue;
DWORD cbWritten;
va_list argptr;

va_start( argptr, format );
retValue = wvsprintf( szBuff, format, argptr );
va_end( argptr );

WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), szBuff, retValue,
&cbWritten, 0 );

return retValue;
}

Figure 3 initterm

//==========================================
// LIBCTINY - Matt Pietrek 2001
// MSDN Magazine, January 2001
//==========================================
#include <windows.h>
#include <malloc.h>
#include "initterm.h"

#pragma data_seg(".CRT$XCA")
_PVFV __xc_a[] = { NULL };


#pragma data_seg(".CRT$XCZ")
_PVFV __xc_z[] = { NULL };

#pragma data_seg() /* reset */

#pragma comment(linker, "/merge:.CRT=.data")

typedef void (__cdecl *_PVFV)(void);

void __cdecl _initterm (
_PVFV * pfbegin,
_PVFV * pfend
)
{
/*
* walk the table of function pointers from the bottom up, until
* the end is encountered. Do not skip the first entry. The initial
* value of pfbegin points to the first valid entry. Do not try to
* execute what pfend points to. Only entries before pfend are
* valid.
*/
while ( pfbegin < pfend )
{
// if current table entry is non-NULL, call thru it.
if ( *pfbegin != NULL )
(**pfbegin)();
++pfbegin;
}
}

static _PVFV * pf_atexitlist = 0;
static unsigned max_atexitlist_entries = 0;
static unsigned cur_atexitlist_entries = 0;

void __cdecl _atexit_init(void)
{
max_atexitlist_entries = 32;
pf_atexitlist = (_PVFV *)calloc( max_atexitlist_entries,
sizeof(_PVFV*) );
}

int __cdecl atexit (_PVFV func )
{
if ( cur_atexitlist_entries < max_atexitlist_entries )
{
pf_atexitlist[cur_atexitlist_entries++] = func;
return 0;
}

return -1;
}

void __cdecl _DoExit( void )
{
if ( cur_atexitlist_entries )
{
_initterm( pf_atexitlist,
// Use ptr math to find the end of the array
pf_atexitlist + cur_atexitlist_entries );
}
}

Figure 4 DLLCRTO.CPP

//==========================================
// LIBCTINY - Matt Pietrek 2001
// MSDN Magazine, January 2001
// FILE: DLLCRT0.CPP
//==========================================
#include <windows.h>
#include "initterm.h"

// Force the linker to include KERNEL32.LIB
#pragma comment(linker, "/defaultlib:kernel32.lib")

// Force 512 byte section alignment in the PE file
#pragma comment(linker, "/OPT:NOWIN98")

// #pragma comment(linker, "/nodefaultlib:libc.lib")
// #pragma comment(linker, "/nodefaultlib:libcmt.lib")

// User routine DllMain is called on all notifications

extern BOOL WINAPI DllMain(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
) ;

//
// Modified version of the Visual C++ startup code. Simplified to
// make it easier to read. Only supports ANSI programs.
//
extern "C"
BOOL WINAPI _DllMainCRTStartup(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
if ( dwReason == DLL_PROCESS_ATTACH )
{
// set up our minimal cheezy atexit table
_atexit_init();

// Call C++ constructors
_initterm( __xc_a, __xc_z );
}

BOOL retcode = DllMain(hDllHandle, dwReason, lpreserved);

if ( dwReason == DLL_PROCESS_DETACH )
{
_DoExit();
}

return retcode ;
}

Figure 5 TEST.CPP

// Small test program to exercise TINYCRT.  Does nothing useful
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( int argc, char *argv[] )
{
int i;

for ( i = 0; i < argc; i++ )
{
printf( "argc: %u /'%s/'/n", i, argv[i] );
}

char * p = new char[10];

lstrcpy( p, "Hello" );

delete p;

printf( "%s/n", strlwr( "MyLowerCaseString" ) );

printf ( "strcmpi: %u/n", strcmpi( "Abc", "abc" ) );

strrchr( "foo", 'o' );

return 0;
}

// Declare a simple C++ class with a constructor
class TestClass
{
public:
TestClass(void)
{
printf( "In TestClass constructor/n" );
}
~TestClass(void)
{
printf( "In TestClass destructor/n" );
}
};

// Create a global instance of the class
TestClass g_TestClassInstance;