No issues under Linux with Clang 14 as .cpp or as .c - though I also had suspected that the name mangling in C++ might be the problem.
HMG's suggestion to add -S for the assembly listing makes sense. With
and copy/pasting incbin.h as book.bin dummy file (hence the text stuff in gbookbinData), the assembly result looks like this:
Code: Select all
.text
.file "incbin.cpp"
# Start of file scope inline assembly
.section .rodata,"a",@progbits
.globl gbookbinData
.type gbookbinData,@object
.p2align 4
gbookbinData:
.ascii "#pragma once\r\n/**\r\n * @file incbin.h\r\n * @author Dale Weiler\r\n * @brief Utility for including binary files\r\n *\r\n * Facilities for including binary files into the current translation unit and\r\n * making use from them externally in other translation units.\r\n */\r\n#ifndef INCBIN_HDR\r\n#define INCBIN_HDR\r\n#include <limits.h>\r\n#if defined(__AVX512BW__) || \\\r\n defined(__AVX512CD__) || \\\r\n defined(__AVX512DQ__) || \\\r\n defined(__AVX512ER__) || \\\r\n defined(__AVX512PF__) || \\\r\n defined(__AVX512VL__) || \\\r\n defined(__AVX512F__)\r\n# define INCBIN_ALIGNMENT_INDEX 6\r\n#elif defined(__AVX__) || \\\r\n defined(__AVX2__)\r\n# define INCBIN_ALIGNMENT_INDEX 5\r\n#elif defined(__SSE__) || \\\r\n defined(__SSE2__) || \\\r\n defined(__SSE3__) || \\\r\n defined(__SSSE3__) || \\\r\n defined(__SSE4_1__) || \\\r\n defined(__SSE4_2__) || \\\r\n defined(__neon__)\r\n# define INCBIN_ALIGNMENT_INDEX 4\r\n#elif ULONG_MAX != 0xffffffffu\r\n# define INCBIN_ALIGNMENT_INDEX 3\r\n# else\r\n# define INCBIN_ALIGNMENT_INDEX 2\r\n#endif\r\n\r\n /* Lookup table of (1 << n) where `n' is `INCBIN_ALIGNMENT_INDEX' */\r\n#define INCBIN_ALIGN_SHIFT_0 1\r\n#define INCBIN_ALIGN_SHIFT_1 2\r\n#define INCBIN_ALIGN_SHIFT_2 4\r\n#define INCBIN_ALIGN_SHIFT_3 8\r\n#define INCBIN_ALIGN_SHIFT_4 16\r\n#define INCBIN_ALIGN_SHIFT_5 32\r\n#define INCBIN_ALIGN_SHIFT_6 64\r\n\r\n/* Actual alignment value */\r\n#define INCBIN_ALIGNMENT \\\r\n INCBIN_CONCATENATE( \\\r\n INCBIN_CONCATENATE(INCBIN_ALIGN_SHIFT, _), \\\r\n INCBIN_ALIGNMENT_INDEX)\r\n\r\n/* Stringize */\r\n#define INCBIN_STR(X) \\\r\n #X\r\n#define INCBIN_STRINGIZE(X) \\\r\n INCBIN_STR(X)\r\n/* Concatenate */\r\n#define INCBIN_CAT(X, Y) \\\r\n X ## Y\r\n#define INCBIN_CONCATENATE(X, Y) \\\r\n INCBIN_CAT(X, Y)\r\n/* Deferred macro expansion */\r\n#define INCBIN_EVAL(X) \\\r\n X\r\n#define INCBIN_INVOKE(N, ...) \\\r\n INCBIN_EVAL(N(__VA_ARGS__))\r\n\r\n/* Green Hills uses a different directive for including binary data */\r\n#if defined(__ghs__)\r\n# if (__ghs_asm == 2)\r\n# define INCBIN_MACRO \".file\"\r\n/* Or consider the \".myrawdata\" entry in the ld file */\r\n# else\r\n# define INCBIN_MACRO \"\\tINCBIN\"\r\n# endif\r\n#else\r\n# define INCBIN_MACRO \".incbin\"\r\n#endif\r\n\r\n#ifndef _MSC_VER\r\n# define INCBIN_ALIGN \\\r\n __attribute__((aligned(INCBIN_ALIGNMENT)))\r\n#else\r\n# define INCBIN_ALIGN __declspec(align(INCBIN_ALIGNMENT))\r\n#endif\r\n\r\n#if defined(__arm__) || /* GNU C and RealView */ \\\r\n defined(__arm) || /* Diab */ \\\r\n defined(_ARM) /* ImageCraft */\r\n# define INCBIN_ARM\r\n#endif\r\n\r\n#ifdef __GNUC__\r\n/* Utilize .balign where supported */\r\n# define INCBIN_ALIGN_HOST \".balign \" INCBIN_STRINGIZE(INCBIN_ALIGNMENT) \"\\n\"\r\n# define INCBIN_ALIGN_BYTE \".balign 1\\n\"\r\n#elif defined(INCBIN_ARM)\r\n/*\r\n * On arm assemblers, the alignment value is calculated as (1 << n) where `n' is\r\n * the shift count. This is the value passed to `.align'\r\n */\r\n# define INCBIN_ALIGN_HOST \".align \" INCBIN_STRINGIZE(INCBIN_ALIGNMENT_INDEX) \"\\n\"\r\n# define INCBIN_ALIGN_BYTE \".align 0\\n\"\r\n#else\r\n/* We assume other inline assembler's treat `.align' as `.balign' */\r\n# define INCBIN_ALIGN_HOST \".align \" INCBIN_STRINGIZE(INCBIN_ALIGNMENT) \"\\n\"\r\n# define INCBIN_ALIGN_BYTE \".align 1\\n\"\r\n#endif\r\n\r\n/* INCBIN_CONST is used by incbin.c generated files */\r\n#if defined(__cplusplus)\r\n# define INCBIN_EXTERNAL extern \"C\"\r\n# define INCBIN_CONST extern const\r\n#else\r\n# define INCBIN_EXTERNAL extern\r\n# define INCBIN_CONST const\r\n#endif\r\n\r\n/**\r\n * @brief Optionally override the linker section into which data is emitted.\r\n *\r\n * @warning If you use this facility, you'll have to deal with platform-specific linker output\r\n * section naming on your own\r\n *\r\n * Overriding the default linker output section, e.g for esp8266/Arduino:\r\n * @code\r\n * #define INCBIN_OUTPUT_SECTION \".irom.text\"\r\n * #include \"incbin.h\"\r\n * INCBIN(Foo, \"foo.txt\");\r\n * // Data is emitted into program memory that never gets copied to RAM\r\n * @endcode\r\n */\r\n#if !defined(INCBIN_OUTPUT_SECTION)\r\n# if defined(__APPLE__)\r\n# define INCBIN_OUTPUT_SECTION \".const_data\"\r\n# else\r\n# define INCBIN_OUTPUT_SECTION \".rodata\"\r\n# endif\r\n#endif\r\n\r\n#if defined(__APPLE__)\r\n /* The directives are different for Apple branded compilers */\r\n# define INCBIN_SECTION INCBIN_OUTPUT_SECTION \"\\n\"\r\n# define INCBIN_GLOBAL(NAME) \".globl \" INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME \"\\n\"\r\n# define INCBIN_INT \".long \"\r\n# define INCBIN_MANGLE \"_\"\r\n# define INCBIN_BYTE \".byte \"\r\n# define INCBIN_TYPE(...)\r\n#else\r\n# define INCBIN_SECTION \".section \" INCBIN_OUTPUT_SECTION \"\\n\"\r\n# define INCBIN_GLOBAL(NAME) \".global \" INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME \"\\n\"\r\n# if defined(__ghs__)\r\n# define INCBIN_INT \".word \"\r\n# else\r\n# define INCBIN_INT \".int \"\r\n# endif\r\n# if defined(__USER_LABEL_PREFIX__)\r\n# define INCBIN_MANGLE INCBIN_STRINGIZE(__USER_LABEL_PREFIX__)\r\n# else\r\n# define INCBIN_MANGLE \"\"\r\n# endif\r\n# if defined(INCBIN_ARM)\r\n /* On arm assemblers, `@' is used as a line comment token */\r\n# define INCBIN_TYPE(NAME) \".type \" INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME \", %object\\n\"\r\n# elif defined(__MINGW32__) || defined(__MINGW64__)\r\n /* Mingw doesn't support this directive either */\r\n# define INCBIN_TYPE(NAME)\r\n# else\r\n /* It's safe to use `@' on other architectures */\r\n# define INCBIN_TYPE(NAME) \".type \" INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME \", @object\\n\"\r\n# endif\r\n# define INCBIN_BYTE \".byte \"\r\n#endif\r\n\r\n/* List of style types used for symbol names */\r\n#define INCBIN_STYLE_CAMEL 0\r\n#define INCBIN_STYLE_SNAKE 1\r\n\r\n/**\r\n * @brief Specify the prefix to use for symbol names.\r\n *\r\n * By default this is `g', producing symbols of the form:\r\n * @code\r\n * #include \"incbin.h\"\r\n * INCBIN(Foo, \"foo.txt\");\r\n *\r\n * // Now you have the following symbols:\r\n * // const unsigned char gFooData[];\r\n * // const unsigned char *const gFooEnd;\r\n * // const unsigned int gFooSize;\r\n * @endcode\r\n *\r\n * If however you specify a prefix before including: e.g:\r\n * @code\r\n * #define INCBIN_PREFIX incbin\r\n * #include \"incbin.h\"\r\n * INCBIN(Foo, \"foo.txt\");\r\n *\r\n * // Now you have the following symbols instead:\r\n * // const unsigned char incbinFooData[];\r\n * // const unsigned char *const incbinFooEnd;\r\n * // const unsigned int incbinFooSize;\r\n * @endcode\r\n */\r\n#if !defined(INCBIN_PREFIX)\r\n# define INCBIN_PREFIX g\r\n#endif\r\n\r\n /**\r\n * @brief Specify the style used for symbol names.\r\n *\r\n * Possible options are\r\n * - INCBIN_STYLE_CAMEL \"CamelCase\"\r\n * - INCBIN_STYLE_SNAKE \"snake_case\"\r\n *\r\n * Default option is *INCBIN_STYLE_CAMEL* producing symbols of the form:\r\n * @code\r\n * #include \"incbin.h\"\r\n * INCBIN(Foo, \"foo.txt\");\r\n *\r\n * // Now you have the following symbols:\r\n * // const unsigned char <prefix>FooData[];\r\n * // const unsigned char *const <prefix>FooEnd;\r\n * // const unsigned int <prefix>FooSize;\r\n * @endcode\r\n *\r\n * If however you specify a style before including: e.g:\r\n * @code\r\n * #define INCBIN_STYLE INCBIN_STYLE_SNAKE\r\n * #include \"incbin.h\"\r\n * INCBIN(foo, \"foo.txt\");\r\n *\r\n * // Now you have the following symbols:\r\n * // const unsigned char <prefix>foo_data[];\r\n * // const unsigned char *const <prefix>foo_end;\r\n * // const unsigned int <prefix>foo_size;\r\n * @endcode\r\n */\r\n#if !defined(INCBIN_STYLE)\r\n# define INCBIN_STYLE INCBIN_STYLE_CAMEL\r\n#endif\r\n\r\n /* Style lookup tables */\r\n#define INCBIN_STYLE_0_DATA Data\r\n#define INCBIN_STYLE_0_END End\r\n#define INCBIN_STYLE_0_SIZE Size\r\n#define INCBIN_STYLE_1_DATA _data\r\n#define INCBIN_STYLE_1_END _end\r\n#define INCBIN_STYLE_1_SIZE _size\r\n\r\n/* Style lookup: returning identifier */\r\n#define INCBIN_STYLE_IDENT(TYPE) \\\r\n INCBIN_CONCATENATE( \\\r\n INCBIN_STYLE_, \\\r\n INCBIN_CONCATENATE( \\\r\n INCBIN_EVAL(INCBIN_STYLE), \\\r\n INCBIN_CONCATENATE(_, TYPE)))\r\n\r\n/* Style lookup: returning string literal */\r\n#define INCBIN_STYLE_STRING(TYPE) \\\r\n INCBIN_STRINGIZE( \\\r\n INCBIN_STYLE_IDENT(TYPE)) \\\r\n\r\n/* Generate the global labels by indirectly invoking the macro with our style\r\n * type and concatenating the name against them. */\r\n#define INCBIN_GLOBAL_LABELS(NAME, TYPE) \\\r\n INCBIN_INVOKE( \\\r\n INCBIN_GLOBAL, \\\r\n INCBIN_CONCATENATE( \\\r\n NAME, \\\r\n INCBIN_INVOKE( \\\r\n INCBIN_STYLE_IDENT, \\\r\n TYPE))) \\\r\n INCBIN_INVOKE( \\\r\n INCBIN_TYPE, \\\r\n INCBIN_CONCATENATE( \\\r\n NAME, \\\r\n INCBIN_INVOKE( \\\r\n INCBIN_STYLE_IDENT, \\\r\n TYPE)))\r\n\r\n /**\r\n * @brief Externally reference binary data included in another translation unit.\r\n *\r\n * Produces three external symbols that reference the binary data included in\r\n * another translation unit.\r\n *\r\n * The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with\r\n * \"Data\", as well as \"End\" and \"Size\" after. An example is provided below.\r\n *\r\n * @param NAME The name given for the binary data\r\n *\r\n * @code\r\n * INCBIN_EXTERN(Foo);\r\n *\r\n * // Now you have the following symbols:\r\n * // extern const unsigned char <prefix>FooData[];\r\n * // extern const unsigned char *const <prefix>FooEnd;\r\n * // extern const unsigned int <prefix>FooSize;\r\n * @endcode\r\n */\r\n#define INCBIN_EXTERN(NAME) \\\r\n INCBIN_EXTERNAL const INCBIN_ALIGN unsigned char \\\r\n INCBIN_CONCATENATE( \\\r\n INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \\\r\n INCBIN_STYLE_IDENT(DATA))[]; \\\r\n INCBIN_EXTERNAL const INCBIN_ALIGN unsigned char *const \\\r\n INCBIN_CONCATENATE( \\\r\n INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \\\r\n INCBIN_STYLE_IDENT(END)); \\\r\n INCBIN_EXTERNAL const unsigned int \\\r\n INCBIN_CONCATENATE( \\\r\n INCBIN_CONCATENATE(INCBIN_PREFIX, NAME), \\\r\n INCBIN_STYLE_IDENT(SIZE))\r\n\r\n /**\r\n * @brief Include a binary file into the current translation unit.\r\n *\r\n * Includes a binary file into the current translation unit, producing three symbols\r\n * for objects that encode the data and size respectively.\r\n *\r\n * The symbol names are a concatenation of `INCBIN_PREFIX' before *NAME*; with\r\n * \"Data\", as well as \"End\" and \"Size\" after. An example is provided below.\r\n *\r\n * @param NAME The name to associate with this binary data (as an identifier.)\r\n * @param FILENAME The file to include (as a string literal.)\r\n *\r\n * @code\r\n * INCBIN(Icon, \"icon.png\");\r\n *\r\n * // Now you have the following symbols:\r\n * // const unsigned char <prefix>IconData[];\r\n * // const unsigned char *const <prefix>IconEnd;\r\n * // const unsigned int <prefix>IconSize;\r\n * @endcode\r\n *\r\n * @warning This must be used in global scope\r\n * @warning The identifiers may be different if INCBIN_STYLE is not default\r\n *\r\n * To externally reference the data included by this in another translation unit\r\n * please @see INCBIN_EXTERN.\r\n */\r\n#ifdef _MSC_VER\r\n#define INCBIN(NAME, FILENAME) \\\r\n INCBIN_EXTERN(NAME)\r\n#else\r\n#define INCBIN(NAME, FILENAME) \\\r\n __asm__(INCBIN_SECTION \\\r\n INCBIN_GLOBAL_LABELS(NAME, DATA) \\\r\n INCBIN_ALIGN_HOST \\\r\n INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) \":\\n\" \\\r\n INCBIN_MACRO \" \\\"\" FILENAME \"\\\"\\n\" \\\r\n INCBIN_GLOBAL_LABELS(NAME, END) \\\r\n INCBIN_ALIGN_BYTE \\\r\n INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) \":\\n\" \\\r\n INCBIN_BYTE \"1\\n\" \\\r\n INCBIN_GLOBAL_LABELS(NAME, SIZE) \\\r\n INCBIN_ALIGN_HOST \\\r\n INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(SIZE) \":\\n\" \\\r\n INCBIN_INT INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(END) \" - \" \\\r\n INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME INCBIN_STYLE_STRING(DATA) \"\\n\" \\\r\n INCBIN_ALIGN_HOST \\\r\n \".text\\n\" \\\r\n ); \\\r\n INCBIN_EXTERN(NAME)\r\n\r\n#endif\r\n#endif\r\n\r\n\r\n"
.globl gbookbinEnd
.type gbookbinEnd,@object
.p2align 0
gbookbinEnd:
.byte 1
.globl gbookbinSize
.type gbookbinSize,@object
.p2align 4
gbookbinSize:
.long gbookbinEnd-gbookbinData
.p2align 4
.text
# End of file scope inline assembly
.globl main # -- Begin function main
.p2align 4, 0x90
.type main,@function
main: # @main
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movl $0, -4(%rbp)
movq gbookbinSize@GOTPCREL(%rip), %rax
movl (%rax), %esi
leaq .L.str(%rip), %rdi
movb $0, %al
callq printf@PLT
leaq .L.str.1(%rip), %rdi
movq gbookbinData@GOTPCREL(%rip), %rsi
movb $0, %al
callq printf@PLT
movq gbookbinEnd@GOTPCREL(%rip), %rax
movq (%rax), %rsi
leaq .L.str.2(%rip), %rdi
movb $0, %al
callq printf@PLT
xorl %eax, %eax
addq $16, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size main, .Lfunc_end0-main
.cfi_endproc
# -- End function
.type .L.str,@object # @.str
.section .rodata.str1.1,"aMS",@progbits,1
.L.str:
.asciz "bookbin_size = %d\n"
.size .L.str, 19
.type .L.str.1,@object # @.str.1
.L.str.1:
.asciz "bookbin_data = %p\n"
.size .L.str.1, 19
.type .L.str.2,@object # @.str.2
.L.str.2:
.asciz "bookbin_end = %p\n"
.size .L.str.2, 18
.section ".linker-options","e",@llvm_linker_options
.ident "Ubuntu clang version 14.0.0-1ubuntu1"
.section ".note.GNU-stack","",@progbits
.addrsig
.addrsig_sym printf
.addrsig_sym gbookbinSize
.addrsig_sym gbookbinData
.addrsig_sym gbookbinEnd