Skip to content

BUG: Using INCBIN sometimes puts variables in .text #71

@wdotmathree

Description

@wdotmathree

The way that INCBIN handles section switching causes unexpected issues if a non-static global variable declared after the last use of INCBIN is not the first one declared in the file (i.e. if there are any non-static global variables declared above the first use of INCBIN). More precisely, when the non-static variables immediately surrounding an INCBIN call are meant to be in the same section, the ones below end up in .text.

In the example below, a, b, g, and h are all meant to be in .bss, but g and h get put into .text due to the INCBIN call. The reason for this is because GCC believes it's only necessary to specify the section for the first variable, and INCBIN emits a .text directive to the assembler, thus putting the variables below it into .text.

#include <incbin.h>

// Any amount of (non-static) global variables before, these are handled correctly
int a, b;

// Static variables don't make a difference
static int c, d;

INCBIN(a, "a.txt");
INCBIN(b, "a.txt");

// Static variables don't make a difference
static int e, f;

// Any (non-static) global variable below will be put into .text
int g, h;

Leads to the following symbol table

test.o:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000000 l    df *ABS*		0000000000000000 tty.c
0000000000000008 l     O .bss		0000000000000004 c
000000000000000c l     O .bss		0000000000000004 d
0000000000000010 l     O .bss		0000000000000004 e
0000000000000014 l     O .bss		0000000000000004 f
0000000000000000 g     O .bss		0000000000000004 a
0000000000000004 g     O .bss		0000000000000004 b
0000000000000000 g     O .rodata	0000000000000000 gaData
0000000000000000 g     O .rodata	0000000000000000 gaEnd
0000000000000010 g     O .rodata	0000000000000000 gaSize
0000000000000020 g     O .rodata	0000000000000000 gbData
0000000000000020 g     O .rodata	0000000000000000 gbEnd
0000000000000030 g     O .rodata	0000000000000000 gbSize
0000000000000000 g     O .text		0000000000000004 g
0000000000000004 g     O .text		0000000000000004 h

GCC info

Configured with: ../gcc-releases-gcc-15.1.0/configure --target=x86_64-elf --prefix=/opt/cross --disable-nls --enable-languages=c,c++ --without-headers --disable-hosted-libstdcxx : (reconfigured) ../gcc-releases-gcc-15.1.0/configure --target=x86_64-elf --prefix=/opt/cross --disable-nls --enable-languages=c,c++ --without-headers --disable-hosted-libstdcxx
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 15.1.0 (GCC) 

Compilation command: gcc test.c -c

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions