-1

I've a big C file 400M approx. The file size is due to big resources within the code itself. I'm trying to compile with MinGW32 but with the mingw32-gcc.exe -O0 -g3 -ggdb3 -o file.exe file.c but the compiler shows me this error cc1.exe: out of memory allocating #N bytes. How can I solve this problem?

AhmedKamal
  • 11
  • 1
  • 4
  • 2
    If the resources are media like videos, images, documents, etc. you could place them in separate files and load them within your program. That said, this is difficult to diagnose without a [mcve]. – Govind Parmar Oct 30 '18 at 16:30
  • 1
    Are these resources stored in one big array or structure? Is there any reason why you cannot put each resource into a separete file? – Gerhardh Oct 30 '18 at 16:31
  • The file is just like this #include int main() { __asm__("nop;"); //millions of times return 0; } – AhmedKamal Oct 30 '18 at 16:33
  • 1
    @Govind: A complete example in this case would stretch the definition of "minimal". :-) – rici Oct 30 '18 at 16:33
  • 1
    Patient: "Doctor, it hurts with I hit my knee with this hammer; what should I do?" Doctor: "Well, lets start by not hitting your knee with a hammer." What problem is being "solved" by embedding 400-million nops in a single source file, and what are viable ways to solve the same problem *without* embedding 400-million nops in a single source file? – WhozCraig Oct 30 '18 at 16:46
  • 1
    What prevents a solution with a single NOP inside a loop? – Yunnosch Oct 30 '18 at 16:54
  • [XY problem](https://en.wikipedia.org/wiki/XY_problem). You have some problem (X) that you are trying to solve with a 400M C file. Now you have trouble implementing your solution, which becomes your *new* problem (Y). Instead of asking how to solve Y, ask about your original problem X. – n. m. could be an AI Oct 30 '18 at 17:12
  • why do you have a million nops in main ??? – bolov Oct 30 '18 at 17:23
  • @WhozCraig It's not about for loop or knee hurts. It's about making the file size too large to test it with a program. I hope it's clear for you! – AhmedKamal Oct 30 '18 at 18:59
  • @Yunnosch I want to make big executable with really big file size including any kind of instructions – AhmedKamal Oct 30 '18 at 18:59
  • @AhmedKamal you should [edit] your question to include this information. Also please consider this as a learning experience. You you have presented here is indeed an XY problem. So in the future state your X problem, not the Y. For instance this question should have read: "I want to generate a large binary to test some application. I have tried this and got this error." – bolov Oct 30 '18 at 20:55
  • So _"due to big resources"_ is not really true is it? If the compiler has a (not unreasonable) limitation on file size, then there is no solution that involves that compiler and that file size. Change one or reduce the other. Your question would better couched in terms of _"I want to do X, I tried Y, and it did not work because[...] - how can I achieve X?"_ whereas what you have asked is _"How can I make Y work?"_, leaving us to figure out what X might be - not helped by your misleading description. – Clifford Oct 30 '18 at 22:04

3 Answers3

0

As been mentioned in the comments, the best solution is to not have huge files.

In your particular case, where you mentioned that the main function just consists of millions of nop instructions (add that to the question btw) I'd say that the solution is to allocate memory dynamically and then use a loop to create the nop instructions. After that you make the memory executable and call it. I see that you're using mingw32 so I found this answer that describes how to do that in Windows.

The code (copied from mentioned answer) would with a slight modification look like this:

// 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);
klutt
  • 30,332
  • 17
  • 55
  • 95
  • Thank you for your help. Not exactly what I want. My purpose is to create big file actually. I doesn't matter how big it is but what I'm looking for the size of the file to help me test a program. Appreciating your help! – AhmedKamal Oct 30 '18 at 19:02
  • @AhmedKamal Do you just want a huge binary, or is the size of the source of any importance? – klutt Oct 30 '18 at 20:12
0

Assuming x86(-64), since you're on Windows, the following code performs 400 million nop instructions:

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

Notice that this is 11 bytes of code, not 400 million.

Equivalent C code:

int i;
for(i = 0; i < 400000000; i++)
{
    __asm__("nop;");
}
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
0

Since your ACTUAL problem is that you need a huge executable, the solution is something completely different from what you tried, and this is why you always should tell what your actual problem is, instead of assuming that your attempt is correct or suitable. As mentioned in the comments, this is an XY-problem

Here is a pretty easy solution. First, create the boilerplate for an assembly program. On my computer, using Linux and nasm it looks like this:

section .text
global  _start
_start:

I named this file nop.asm

Now, I used a simple bash loop to add 10 million nop:s:

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

Add the rest of the boilerplate:

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

Note: The boilerplate may look different on your system

Now you will have a file called nop.asm that looks like this:

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

Compile and link it:

$ nasm -f elf64 nop.asm
$ ld -s -o nop nop.o

And now you have a pretty big binary:

$ 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

If I would get the same problem with nasm as you got with gcc, I would consider writing a program that writes the executable directly.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • Thank you Broman! I solved by using mingw on windows and worked with 1.5G of code. I'll try this one. Appreciated – AhmedKamal Oct 30 '18 at 20:53