graphitemaster / incbin

Include binary files in C/C++
The Unlicense
938 stars 87 forks source link

INCBIN changes .section for subsequent code #45

Closed Habbie closed 2 years ago

Habbie commented 3 years ago

(full background, with some overhead, at https://github.com/PowerDNS/pdns/issues/9835#issuecomment-741748081)

We have this piece of code:

INCBIN(api_swagger_yaml, "api-swagger.yaml");
static const string g_api_swagger_yaml{(const char*)gapi_swagger_yamlData, gapi_swagger_yamlSize};
INCBIN(api_swagger_json, "api-swagger.json");
static const string g_api_swagger_json{(const char*)gapi_swagger_jsonData, gapi_swagger_jsonSize};

When we compile this with gcc's or clang's Address Sanitizer, it crashes in a string constructor.

Reordering the code like this fixes the problem:

INCBIN(api_swagger_yaml, "api-swagger.yaml");
INCBIN(api_swagger_json, "api-swagger.json");
static const string g_api_swagger_yaml{(const char*)gapi_swagger_yamlData, gapi_swagger_yamlSize};
static const string g_api_swagger_json{(const char*)gapi_swagger_jsonData, gapi_swagger_jsonSize};

A copy/paste of my understanding of the reason, from the linked ticket:

Now the question is - can we add something to the macro to 'restore' the previously active section, or inform the compiler that it needs to repeat its section choice?

graphitemaster commented 3 years ago

I think it may be possible to reset to the .text.

Theldus commented 3 years ago

Maybe .pushsection and .popsection?, I haven't used these before, so maybe I'm equivocated.

hhoffstaette commented 3 years ago

Hi! I encountered this problem when building a C++ program which refused to link with LTO, and found the solution in the GCC bug tracker: 78613 and 47071. The fix was indeed simple:

diff -up incbin.h~ incbin.h
--- incbin.h~   2018-11-12 09:33:58.000000000 +0100
+++ incbin.h    2021-03-13 17:53:28.552595628 +0100
@@ -216,6 +216,7 @@
             INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "Size:\n" \
                 INCBIN_INT INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "End - " \
                            INCBIN_MANGLE INCBIN_STRINGIZE(INCBIN_PREFIX) #NAME "Data\n" \
+            ".previous" "\n" \
     ); \
     INCBIN_EXTERN(NAME)

..and voilà: no more section mismatches during linking :smile:

graphitemaster commented 3 years ago

This is a good solution to the problem. I just need to make sure .previous works on all the assembler toolchains.

graphitemaster commented 2 years ago

It looks like this is already fixed with resetting back to the .text section so I sense you just have an out of date copy of incbin maybe?

hhoffstaette commented 2 years ago

It looks like this is already fixed with resetting back to the .text section so I sense you just have an out of date copy of incbin maybe?

I used (and patched) the one that came bundled with the source of the package that had problems, and that didn't yet have the fix on master. However said package no loger uses incbin, so .. ¯\_(ツ)_/¯