Компиляция больших файлов C - PullRequest
0 голосов
/ 30 октября 2018

У меня большой C-файл 400M ок. Размер файла обусловлен большими ресурсами внутри самого кода. Я пытаюсь скомпилировать с MinGW32, но с mingw32-gcc.exe -O0 -g3 -ggdb3 -o file.exe file.c, но компилятор показывает мне эту ошибку cc1.exe: out of memory allocating #N bytes. Как я могу решить эту проблему?

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

Предполагая x86 (-64), поскольку вы работаете в Windows, следующий код выполняет 400 миллионов 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 байт кода, а не 400 миллионов.

Эквивалентный код C:

int i;
for(i = 0; i < 400000000; i++)
{
    __asm__("nop;");
}
0 голосов
/ 30 октября 2018

Поскольку ваша АКТУАЛЬНАЯ проблема заключается в том, что вам нужен огромный исполняемый файл, решение является чем-то совершенно отличным от того, что вы пробовали, и именно поэтому вы всегда должны указывать, в чем заключается ваша настоящая проблема, а не предполагать, что ваша попытка является правильной или подходящей , Как упоминалось в комментариях, это XY-проблема

Вот довольно простое решение. Сначала создайте шаблон для программы сборки. На моем компьютере с использованием Linux и Nasm это выглядит так:

section .text
global  _start
_start:

Я назвал этот файл nop.asm

Теперь я использовал простой цикл bash, чтобы добавить 10 миллионов nop: s:

$ for i in $(seq 10000000); do echo nop >> nop.asm  ; done

Добавить остальную часть шаблона:

$ echo "mov eax,1" >> nop.asm
$ echo "int 0x80" >> nop.asm

Примечание: шаблон может отличаться в вашей системе

Теперь у вас будет файл с именем nop.asm, который выглядит следующим образом:

section .text
global  _start
_start:
nop
nop
...
nop
nop
mov eax,1
int 0x80

Скомпилируйте и свяжите это:

$ 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, я бы подумал написать программу, которая пишет исполняемый файл напрямую.

0 голосов
/ 30 октября 2018

Как уже упоминалось в комментариях, лучшее решение - не иметь огромных файлов.

В вашем конкретном случае, когда вы упомянули, что функция main состоит из миллионов 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);
...