Difference between revisions of "incbin()"

From vegard.wiki
Jump to navigation Jump to search
(add links)
(→‎See also: add link)
 
Line 52: Line 52:
  
 
* https://gist.github.com/mmozeiko/ed9655cf50341553d282
 
* https://gist.github.com/mmozeiko/ed9655cf50341553d282
 +
* https://github.com/graphitemaster/incbin
 
* http://smackerelofopinion.blogspot.com/2015/12/incorporating-and-accesses-binary-data.html
 
* http://smackerelofopinion.blogspot.com/2015/12/incorporating-and-accesses-binary-data.html
  

Latest revision as of 11:33, 28 April 2020

To include binary files directly in a C++ program without using an external tool you can use this handy macro (probably only works with the GNU assembler, though):

#include <stdio.h>

struct binfile {
    char *data;
    size_t size;

    binfile(char *data, size_t size):
        data(data),
        size(size)
    {
    }
};

#define _CONCAT(x, y) x##y
#define CONCAT(x, y) _CONCAT(x, y)

#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)

#define incbin(filename) \
    ({ \
        extern char CONCAT(incbin_data, __LINE__)[]; \
        extern unsigned long CONCAT(incbin_data_size, __LINE__); \
        asm (".pushsection .rodata, \"a\" ;" \
            ".global incbin_data" STRINGIFY(__LINE__) " ;" \
            "incbin_data" STRINGIFY(__LINE__) ": ;" \
            ".incbin " STRINGIFY(filename) " ;" \
            "incbin_data_end" STRINGIFY(__LINE__) ": ;" \
            ".byte 0 ;" \
            ".global incbin_data_size" STRINGIFY(__LINE__) " ;" \
            "incbin_data_size" STRINGIFY(__LINE__) ": ;" \
            ".quad (incbin_data_end" STRINGIFY(__LINE__) " - incbin_data" STRINGIFY(__LINE__) ") ;" \
            ".popsection"); \
        binfile(CONCAT(incbin_data, __LINE__), \
            CONCAT(incbin_data_size, __LINE__)); \
    })

int main(int argc, char *argv[])
{
    auto v = incbin("/etc/passwd");
    fwrite(v.data, 1, v.size, stdout);
    return 0;
}

It should also work for C with some minor changes.

See also