c++assemblycoff

"Undefined reference" error when using assembly to embed data, using mingw-w64 compiling for windows (COFF instead of ELF)


In a different Stackoverflow Q/A there was a post that showed how to embed arbitrary data in assembly and reference it in C++.

This works fine in Linux, but when compiling for Windows (using mingw-w64), the assembly has to be different because the executable is using the COFF format instead of ELF.

My current assembly for embedding data is as follows (for COFF):

# data.asm
    .section .rodata
    .global data_bin
    .def data_bin; .scl 2; .type 50; .endef
    .align  4
data_bin:
    .incbin "dataFile"
data_bin_end:
    .global data_bin_size
    .def data_bin_size; .scl 2; .type 15; .endef
    .align  8
data_bin_size:
    .quad   data_bin_end - data_bin

(I'm using ".scl 2" because storage class "2" is apparently global/extern, and I'm using ".type 50" for the data as "50" is the value for an array of characters, and I'm using ".type 15" for the data_size as "15" is the value for an unsigned long (all this as specified here))

I'm still using the same header file to reference the data:

// data.hpp
#ifndef DATA_ASM_HPP
#define DATA_ASM_HPP

extern const char data_bin[];
extern const unsigned long long data_bin_size;

#endif

The assembly compiles fine, and so does the rest of the program. The issue arises when linking, where the linker claims data_bin and data_bin_size is undefined even though I defined them in the assembly code (undefined reference to 'data_bin').

Any ideas/solutions on how to fix this? I've double checked and the object file generated from compiling the assembly code is included in the linking step.


Solution

  • Add extern "C" { } around data.hpp (in linux, variable names are not mangled, but in windows, they are)

    And maybe, you'll need to prepend "_" to variable names in the asm.