0
0 Comments

consider the following gas (GNU assembler) file for 64 bit linux

go.s

			
        .global _start
        .text

_start:
        mov     $60, %rax               # system call 60 is exit
        xor     %rdi, %rdi              # we want return code 0
        syscall  

Now to compile:

			
rm -f go go.o
as -o go.o go.s
ld -o go -s -nostartfiles go.o
ls -l go                                            # -> 344 bytes

We get a super-small size of 344 bytes.

Great! With gcc and separate

ld
command:

			
# gcc with separate link
rm -f go go.o
gcc -xassembler -c go.s
ld -s -nostartfiles -o go go.o
ls -l go                                            # -> 344 bytes

But how does one get that small size, using only a single gcc command?

			
# single gcc command                                                                                                                                                                     
rm -f go go.o
gcc -xassembler -s -static -nostartfiles -o go go.s
ls -l go                                            # -> 4400 bytes  too big!!!

Damn 4400 bytes! Which single line gcc invocation will give 344 bytes?

Running the above single line with the

-v
flag...

			
gcc -v -xassembler -s -static -nostartfiles -o go go.s

... shows that

-nostartfiles
is not passed to the
collect2
link command.

Hmmm...

So task: show me the single-line gcc invocation giving the minimal size!

Thanks.


Experimenting with the

-v
flag:

			
gcc -v -xassembler -s -static -nostartfiles -o go go.s

does the following:

as -v --64 -o go.o go.s

# will give 4400 bytes
/usr/lib/gcc/x86_64-linux-gnu/8/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/8/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lc --build-id -m elf_x86_64 --hash-style=gnu -static -o go -s -L/usr/lib/gcc/x86_64-linux-gnu/8 -L/usr/lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/8/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/8/../../.. go.o --start-group -lgcc -lgcc_eh -lc --end-group

Manually adding

-nostartfiles
to the
/usr/lib/gcc/x86_64-linux-gnu/8/collect2
command (above) gives a size of 520 bytes.

Manually adding

-nostartfiles
and removing
--build-id
gives a size of 344 bytes.

But how does one instruct gcc to do this?

Anonymous Asked question May 13, 2021