Embedding binary data into an executable using LLVM tools












2















In the past I have embedded resource files (images) into programs by first converting them to .o files using the GNU linker. For example:



ld -r -b binary -o file.o file.svg


Starting with FreeBSD 12, the default linker has changed from GNU's to LLVM's. Although the linker appears to understand the command line options, it results in an error. For example:



ld -r -b binary -o file.o file.svg
ld: error: target emulation unknown: -m or at least one .o file required


Also tried using the command line options from the ld.lld(1) manual page:



ld --relocatable --format=binary -o file.o file.svg
ld: error: target emulation unknown: -m or at least one .o file required


Am I using the correct tool? Do I need to specify a value for the -m option?










share|improve this question



























    2















    In the past I have embedded resource files (images) into programs by first converting them to .o files using the GNU linker. For example:



    ld -r -b binary -o file.o file.svg


    Starting with FreeBSD 12, the default linker has changed from GNU's to LLVM's. Although the linker appears to understand the command line options, it results in an error. For example:



    ld -r -b binary -o file.o file.svg
    ld: error: target emulation unknown: -m or at least one .o file required


    Also tried using the command line options from the ld.lld(1) manual page:



    ld --relocatable --format=binary -o file.o file.svg
    ld: error: target emulation unknown: -m or at least one .o file required


    Am I using the correct tool? Do I need to specify a value for the -m option?










    share|improve this question

























      2












      2








      2








      In the past I have embedded resource files (images) into programs by first converting them to .o files using the GNU linker. For example:



      ld -r -b binary -o file.o file.svg


      Starting with FreeBSD 12, the default linker has changed from GNU's to LLVM's. Although the linker appears to understand the command line options, it results in an error. For example:



      ld -r -b binary -o file.o file.svg
      ld: error: target emulation unknown: -m or at least one .o file required


      Also tried using the command line options from the ld.lld(1) manual page:



      ld --relocatable --format=binary -o file.o file.svg
      ld: error: target emulation unknown: -m or at least one .o file required


      Am I using the correct tool? Do I need to specify a value for the -m option?










      share|improve this question














      In the past I have embedded resource files (images) into programs by first converting them to .o files using the GNU linker. For example:



      ld -r -b binary -o file.o file.svg


      Starting with FreeBSD 12, the default linker has changed from GNU's to LLVM's. Although the linker appears to understand the command line options, it results in an error. For example:



      ld -r -b binary -o file.o file.svg
      ld: error: target emulation unknown: -m or at least one .o file required


      Also tried using the command line options from the ld.lld(1) manual page:



      ld --relocatable --format=binary -o file.o file.svg
      ld: error: target emulation unknown: -m or at least one .o file required


      Am I using the correct tool? Do I need to specify a value for the -m option?







      freebsd linker llvm






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked yesterday









      Richard SmithRichard Smith

      8661410




      8661410






















          3 Answers
          3






          active

          oldest

          votes


















          1














          Is it really worth the trouble? That wasn't portable in the first place.



          You should better convert your .svg to a C char array; Example:



          $ cat Makefile
          .SUFFIXES: .svg
          .svg.c:
          od -tx1 $< | sed 's/ /,0x/g;s/[^,]*//;1s/,/char $*={/;$$s/$$/};/' > $@

          $ make file.o
          od -tx1 file.svg | sed 's/ /,0x/g;s/[^,]*//;1s/,/char file={/;$s/$/};/' > file.c
          cc -c -o file.o file.c
          rm file.c


          Of course, you can set the name of the array to something different / more robust (eg. char $(subst /,_,$*) = ... instead of char $* = ... with GNU make). Also, you could build an ad-hoc bin2c converter written in C instead of that horrible od+sed combo.






          share|improve this answer


























          • I like the idea of a bin2c converter

            – Richard Smith
            14 hours ago



















          0














          It seems you need to add -z noexecstack (This was added for ELF binaries as well in LLD 7.0.0). The default is to have an executable stack region which is vulnerable to exploitation via stack memory. Your binary image does not have an executable stack and I believe that is why it fails. The error throws you off as it asks you to tell what target emulation to use for your stack (which you do not have).



          David Herrmann did all the hard work and have found a cross platform solution which covers:




          • GNU-ld

          • GNU-gold

          • GNU-libtool

          • work with cross-compiling

          • work with LLVM

          • do not require any external non-standard tools


          The magic invocation is then:



          $(LD) -r -o "src/mydata.bin.o" -z noexecstack --format=binary "src/mydata.bin"


          And most often you want that binary segment to be read-only:



          $(OBJCOPY) --rename-section .data=.rodata,alloc,load,readonly,data,contents "src/mydata.bin.o"





          share|improve this answer
























          • I tried adding the -z noexecstack option, but I get the same error message. As you say, it's not a useful error message, you get the same error message if you type ld with no parameters at all!

            – Richard Smith
            yesterday



















          0














          After looking through the source, the correct target emulation for my platform is elf_amd64. So the conversion from binary to object file works using:



          ld -r -b binary -m elf_amd64 -o file.o file.svg





          share|improve this answer























            Your Answer








            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "106"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f494844%2fembedding-binary-data-into-an-executable-using-llvm-tools%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            Is it really worth the trouble? That wasn't portable in the first place.



            You should better convert your .svg to a C char array; Example:



            $ cat Makefile
            .SUFFIXES: .svg
            .svg.c:
            od -tx1 $< | sed 's/ /,0x/g;s/[^,]*//;1s/,/char $*={/;$$s/$$/};/' > $@

            $ make file.o
            od -tx1 file.svg | sed 's/ /,0x/g;s/[^,]*//;1s/,/char file={/;$s/$/};/' > file.c
            cc -c -o file.o file.c
            rm file.c


            Of course, you can set the name of the array to something different / more robust (eg. char $(subst /,_,$*) = ... instead of char $* = ... with GNU make). Also, you could build an ad-hoc bin2c converter written in C instead of that horrible od+sed combo.






            share|improve this answer


























            • I like the idea of a bin2c converter

              – Richard Smith
              14 hours ago
















            1














            Is it really worth the trouble? That wasn't portable in the first place.



            You should better convert your .svg to a C char array; Example:



            $ cat Makefile
            .SUFFIXES: .svg
            .svg.c:
            od -tx1 $< | sed 's/ /,0x/g;s/[^,]*//;1s/,/char $*={/;$$s/$$/};/' > $@

            $ make file.o
            od -tx1 file.svg | sed 's/ /,0x/g;s/[^,]*//;1s/,/char file={/;$s/$/};/' > file.c
            cc -c -o file.o file.c
            rm file.c


            Of course, you can set the name of the array to something different / more robust (eg. char $(subst /,_,$*) = ... instead of char $* = ... with GNU make). Also, you could build an ad-hoc bin2c converter written in C instead of that horrible od+sed combo.






            share|improve this answer


























            • I like the idea of a bin2c converter

              – Richard Smith
              14 hours ago














            1












            1








            1







            Is it really worth the trouble? That wasn't portable in the first place.



            You should better convert your .svg to a C char array; Example:



            $ cat Makefile
            .SUFFIXES: .svg
            .svg.c:
            od -tx1 $< | sed 's/ /,0x/g;s/[^,]*//;1s/,/char $*={/;$$s/$$/};/' > $@

            $ make file.o
            od -tx1 file.svg | sed 's/ /,0x/g;s/[^,]*//;1s/,/char file={/;$s/$/};/' > file.c
            cc -c -o file.o file.c
            rm file.c


            Of course, you can set the name of the array to something different / more robust (eg. char $(subst /,_,$*) = ... instead of char $* = ... with GNU make). Also, you could build an ad-hoc bin2c converter written in C instead of that horrible od+sed combo.






            share|improve this answer















            Is it really worth the trouble? That wasn't portable in the first place.



            You should better convert your .svg to a C char array; Example:



            $ cat Makefile
            .SUFFIXES: .svg
            .svg.c:
            od -tx1 $< | sed 's/ /,0x/g;s/[^,]*//;1s/,/char $*={/;$$s/$$/};/' > $@

            $ make file.o
            od -tx1 file.svg | sed 's/ /,0x/g;s/[^,]*//;1s/,/char file={/;$s/$/};/' > file.c
            cc -c -o file.o file.c
            rm file.c


            Of course, you can set the name of the array to something different / more robust (eg. char $(subst /,_,$*) = ... instead of char $* = ... with GNU make). Also, you could build an ad-hoc bin2c converter written in C instead of that horrible od+sed combo.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited yesterday

























            answered yesterday









            Uncle BillyUncle Billy

            4115




            4115













            • I like the idea of a bin2c converter

              – Richard Smith
              14 hours ago



















            • I like the idea of a bin2c converter

              – Richard Smith
              14 hours ago

















            I like the idea of a bin2c converter

            – Richard Smith
            14 hours ago





            I like the idea of a bin2c converter

            – Richard Smith
            14 hours ago













            0














            It seems you need to add -z noexecstack (This was added for ELF binaries as well in LLD 7.0.0). The default is to have an executable stack region which is vulnerable to exploitation via stack memory. Your binary image does not have an executable stack and I believe that is why it fails. The error throws you off as it asks you to tell what target emulation to use for your stack (which you do not have).



            David Herrmann did all the hard work and have found a cross platform solution which covers:




            • GNU-ld

            • GNU-gold

            • GNU-libtool

            • work with cross-compiling

            • work with LLVM

            • do not require any external non-standard tools


            The magic invocation is then:



            $(LD) -r -o "src/mydata.bin.o" -z noexecstack --format=binary "src/mydata.bin"


            And most often you want that binary segment to be read-only:



            $(OBJCOPY) --rename-section .data=.rodata,alloc,load,readonly,data,contents "src/mydata.bin.o"





            share|improve this answer
























            • I tried adding the -z noexecstack option, but I get the same error message. As you say, it's not a useful error message, you get the same error message if you type ld with no parameters at all!

              – Richard Smith
              yesterday
















            0














            It seems you need to add -z noexecstack (This was added for ELF binaries as well in LLD 7.0.0). The default is to have an executable stack region which is vulnerable to exploitation via stack memory. Your binary image does not have an executable stack and I believe that is why it fails. The error throws you off as it asks you to tell what target emulation to use for your stack (which you do not have).



            David Herrmann did all the hard work and have found a cross platform solution which covers:




            • GNU-ld

            • GNU-gold

            • GNU-libtool

            • work with cross-compiling

            • work with LLVM

            • do not require any external non-standard tools


            The magic invocation is then:



            $(LD) -r -o "src/mydata.bin.o" -z noexecstack --format=binary "src/mydata.bin"


            And most often you want that binary segment to be read-only:



            $(OBJCOPY) --rename-section .data=.rodata,alloc,load,readonly,data,contents "src/mydata.bin.o"





            share|improve this answer
























            • I tried adding the -z noexecstack option, but I get the same error message. As you say, it's not a useful error message, you get the same error message if you type ld with no parameters at all!

              – Richard Smith
              yesterday














            0












            0








            0







            It seems you need to add -z noexecstack (This was added for ELF binaries as well in LLD 7.0.0). The default is to have an executable stack region which is vulnerable to exploitation via stack memory. Your binary image does not have an executable stack and I believe that is why it fails. The error throws you off as it asks you to tell what target emulation to use for your stack (which you do not have).



            David Herrmann did all the hard work and have found a cross platform solution which covers:




            • GNU-ld

            • GNU-gold

            • GNU-libtool

            • work with cross-compiling

            • work with LLVM

            • do not require any external non-standard tools


            The magic invocation is then:



            $(LD) -r -o "src/mydata.bin.o" -z noexecstack --format=binary "src/mydata.bin"


            And most often you want that binary segment to be read-only:



            $(OBJCOPY) --rename-section .data=.rodata,alloc,load,readonly,data,contents "src/mydata.bin.o"





            share|improve this answer













            It seems you need to add -z noexecstack (This was added for ELF binaries as well in LLD 7.0.0). The default is to have an executable stack region which is vulnerable to exploitation via stack memory. Your binary image does not have an executable stack and I believe that is why it fails. The error throws you off as it asks you to tell what target emulation to use for your stack (which you do not have).



            David Herrmann did all the hard work and have found a cross platform solution which covers:




            • GNU-ld

            • GNU-gold

            • GNU-libtool

            • work with cross-compiling

            • work with LLVM

            • do not require any external non-standard tools


            The magic invocation is then:



            $(LD) -r -o "src/mydata.bin.o" -z noexecstack --format=binary "src/mydata.bin"


            And most often you want that binary segment to be read-only:



            $(OBJCOPY) --rename-section .data=.rodata,alloc,load,readonly,data,contents "src/mydata.bin.o"






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered yesterday









            Claus AndersenClaus Andersen

            1,654415




            1,654415













            • I tried adding the -z noexecstack option, but I get the same error message. As you say, it's not a useful error message, you get the same error message if you type ld with no parameters at all!

              – Richard Smith
              yesterday



















            • I tried adding the -z noexecstack option, but I get the same error message. As you say, it's not a useful error message, you get the same error message if you type ld with no parameters at all!

              – Richard Smith
              yesterday

















            I tried adding the -z noexecstack option, but I get the same error message. As you say, it's not a useful error message, you get the same error message if you type ld with no parameters at all!

            – Richard Smith
            yesterday





            I tried adding the -z noexecstack option, but I get the same error message. As you say, it's not a useful error message, you get the same error message if you type ld with no parameters at all!

            – Richard Smith
            yesterday











            0














            After looking through the source, the correct target emulation for my platform is elf_amd64. So the conversion from binary to object file works using:



            ld -r -b binary -m elf_amd64 -o file.o file.svg





            share|improve this answer




























              0














              After looking through the source, the correct target emulation for my platform is elf_amd64. So the conversion from binary to object file works using:



              ld -r -b binary -m elf_amd64 -o file.o file.svg





              share|improve this answer


























                0












                0








                0







                After looking through the source, the correct target emulation for my platform is elf_amd64. So the conversion from binary to object file works using:



                ld -r -b binary -m elf_amd64 -o file.o file.svg





                share|improve this answer













                After looking through the source, the correct target emulation for my platform is elf_amd64. So the conversion from binary to object file works using:



                ld -r -b binary -m elf_amd64 -o file.o file.svg






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 14 hours ago









                Richard SmithRichard Smith

                8661410




                8661410






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Unix & Linux Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f494844%2fembedding-binary-data-into-an-executable-using-llvm-tools%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Loup dans la culture

                    How to solve the problem of ntp “Unable to contact time server” from KDE?

                    ASUS Zenbook UX433/UX333 — Configure Touchpad-embedded numpad on Linux