编译大 C 文件
Compiling big C files
我有一个400M左右的大C文件。文件大小是由于代码本身的大量资源造成的。我正在尝试使用 MinGW32 进行编译,但使用 mingw32-gcc.exe -O0 -g3 -ggdb3 -o file.exe file.c
,但编译器向我显示此错误 cc1.exe: out of memory allocating #N bytes
。我怎么解决这个问题?
正如评论中提到的,最好的解决方案是不要有大文件。
在您的特定情况下,您提到主函数仅由数百万条 nop 指令组成(顺便说一句,将其添加到问题中)我会说解决方案是动态分配内存,然后使用循环来创建 nop 指令。之后,您使内存可执行并调用它。我看到您正在使用 mingw32
,所以我在 Windows.
中找到了描述如何执行此操作的
代码(从提到的答案中复制)稍微修改后如下所示:
// Allocate some memory as readable+writable
// TODO: Check return value for error
LPVOID memPtr = VirtualAlloc(NULL, sizeof(myarr), MEM_COMMIT, PAGE_READWRITE);
// Write NOP:s
for(int i=0; i<size; i++)
memPtr[i] = // NOP code
// Change memory protection to readable+executable
// Again, TODO: Error checking
DWORD oldProtection; // Not used but required for the function
VirtualProtect(memPtr, sizeof(myarr), PAGE_EXECUTE_READ, &oldProtection);
// Assign and call the function
(void (*)()) myfunc = (void (*)()) memPtr;
myfunc();
// Free the memory
VirtualFree(memPtr, 0, MEM_RELEASE);
假设 x86(-64),因为你在 Windows,下面的代码执行 4 亿次 nop 指令:
00401000: B9 00 84 D7 17 mov ecx,17D78400h
00401005: 90 nop
00401006: E2 FD loop 00401005
00401008: 33 C0 xor eax,eax
0040100A: C3 ret
注意这是11字节的代码,不是4亿。
等效的 C 代码:
int i;
for(i = 0; i < 400000000; i++)
{
__asm__("nop;");
}
由于你的实际问题是你需要一个巨大的可执行文件,解决方案与你尝试的完全不同,这就是为什么你总是应该说出你的实际问题是什么,而不是假设你的尝试是正确的或适合。如评论中所述,这是 XY-problem
这是一个非常简单的解决方案。首先,为汇编程序创建样板。在我的电脑上,使用 Linux 和 nasm 看起来像这样:
section .text
global _start
_start:
我将这个文件命名为nop.asm
现在,我用一个简单的bash循环来加1000万nop:s:
$ for i in $(seq 10000000); do echo nop >> nop.asm ; done
添加其余样板文件:
$ echo "mov eax,1" >> nop.asm
$ echo "int 0x80" >> nop.asm
Note: The boilerplate may look different on your system
现在您将拥有一个名为 nop.asm 的文件,如下所示:
section .text
global _start
_start:
nop
nop
...
nop
nop
mov eax,1
int 0x80
编译并link它:
$ nasm -f elf64 nop.asm
$ ld -s -o nop nop.o
现在你有一个相当大的二进制文件:
$ ls -lh
total 94M
-rwxr-xr-x 1 klutt klutt 16M Oct 30 21:35 nop
-rw-r--r-- 1 klutt klutt 63M Oct 30 21:33 nop.asm
-rw-r--r-- 1 klutt klutt 16M Oct 30 21:34 nop.o
如果我在 nasm 中遇到与 gcc 相同的问题,我会考虑编写一个直接写入可执行文件的程序。
我有一个400M左右的大C文件。文件大小是由于代码本身的大量资源造成的。我正在尝试使用 MinGW32 进行编译,但使用 mingw32-gcc.exe -O0 -g3 -ggdb3 -o file.exe file.c
,但编译器向我显示此错误 cc1.exe: out of memory allocating #N bytes
。我怎么解决这个问题?
正如评论中提到的,最好的解决方案是不要有大文件。
在您的特定情况下,您提到主函数仅由数百万条 nop 指令组成(顺便说一句,将其添加到问题中)我会说解决方案是动态分配内存,然后使用循环来创建 nop 指令。之后,您使内存可执行并调用它。我看到您正在使用 mingw32
,所以我在 Windows.
代码(从提到的答案中复制)稍微修改后如下所示:
// Allocate some memory as readable+writable
// TODO: Check return value for error
LPVOID memPtr = VirtualAlloc(NULL, sizeof(myarr), MEM_COMMIT, PAGE_READWRITE);
// Write NOP:s
for(int i=0; i<size; i++)
memPtr[i] = // NOP code
// Change memory protection to readable+executable
// Again, TODO: Error checking
DWORD oldProtection; // Not used but required for the function
VirtualProtect(memPtr, sizeof(myarr), PAGE_EXECUTE_READ, &oldProtection);
// Assign and call the function
(void (*)()) myfunc = (void (*)()) memPtr;
myfunc();
// Free the memory
VirtualFree(memPtr, 0, MEM_RELEASE);
假设 x86(-64),因为你在 Windows,下面的代码执行 4 亿次 nop 指令:
00401000: B9 00 84 D7 17 mov ecx,17D78400h
00401005: 90 nop
00401006: E2 FD loop 00401005
00401008: 33 C0 xor eax,eax
0040100A: C3 ret
注意这是11字节的代码,不是4亿。
等效的 C 代码:
int i;
for(i = 0; i < 400000000; i++)
{
__asm__("nop;");
}
由于你的实际问题是你需要一个巨大的可执行文件,解决方案与你尝试的完全不同,这就是为什么你总是应该说出你的实际问题是什么,而不是假设你的尝试是正确的或适合。如评论中所述,这是 XY-problem
这是一个非常简单的解决方案。首先,为汇编程序创建样板。在我的电脑上,使用 Linux 和 nasm 看起来像这样:
section .text
global _start
_start:
我将这个文件命名为nop.asm
现在,我用一个简单的bash循环来加1000万nop:s:
$ for i in $(seq 10000000); do echo nop >> nop.asm ; done
添加其余样板文件:
$ echo "mov eax,1" >> nop.asm
$ echo "int 0x80" >> nop.asm
Note: The boilerplate may look different on your system
现在您将拥有一个名为 nop.asm 的文件,如下所示:
section .text
global _start
_start:
nop
nop
...
nop
nop
mov eax,1
int 0x80
编译并link它:
$ nasm -f elf64 nop.asm
$ ld -s -o nop nop.o
现在你有一个相当大的二进制文件:
$ ls -lh
total 94M
-rwxr-xr-x 1 klutt klutt 16M Oct 30 21:35 nop
-rw-r--r-- 1 klutt klutt 63M Oct 30 21:33 nop.asm
-rw-r--r-- 1 klutt klutt 16M Oct 30 21:34 nop.o
如果我在 nasm 中遇到与 gcc 相同的问题,我会考虑编写一个直接写入可执行文件的程序。