Including file data in binary

Programming, for all ages and all languages.
Post Reply
Gnome

Including file data in binary

Post by Gnome »

Hey everyone,

I'm looking for a way to include the contents of a (binary) file in a compiled binary, such that a pointer to the data (and the length), is exported through a symbol. I faintly remember reading about some way of doing this, but I forget how. I figure it likely boils down to some trick with ld to make it include verbatim some file. One (ugly) way I see is to write a script to read the file and encode it as a C array, then compile and that in.

Specifically, I'm looking to include TTF font data in my kernel image to be used in the early stages of the boot process for writing status information to the VESA framebuffer, before the filesystem is loaded and I can get it off the disk.

Thanks in advance.
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re:Including file data in binary

Post by df »

here is my bin2c code.

it creates a .h file you include in your C.
it defines a {name}_size and {name}_data of the object.

Code: Select all

// bin2c v0.2 - stuart george
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
   unsigned long fsize;
   int lcount;
   unsigned char c;
   
   FILE *fp;
   if(argc<3)
   {
      printf("bin2c inputfile recordname\n");
      exit(0);
   }
   
   
   fp = fopen(argv[1], "rb");
   if(fp!=NULL)
   {
      fseek(fp, 0x0L, SEEK_END);
      fsize = ftell(fp);
      fseek(fp, 0x0L, SEEK_SET);
      
      lcount = 0;
      printf("unsigned long %s_size = %li\n", argv[2], fsize);
      printf("unsigned char %s_data[]=\n{\n\t", argv[2]);
      
      while(ftell(fp) < fsize)
      {
         c = fgetc(fp);
         
         if(lcount > 0)
            printf(", ");
         
         printf("0x%02X", c);
         
         lcount++;
         if(lcount == 10)
         {
            lcount = 0;
            printf("\n\t");
         }
      }
      fclose(fp);
      printf("\n};\n");
   }
   else
   {
      fprintf(stderr, "Could not open file\n");
   }
   
   return 0;
}
-- Stu --
Curufir

Re:Including file data in binary

Post by Curufir »

The real easy way would be to just include it in an asm file and link that into your C file.

Eg NASM

Code: Select all

global start_ttf, end_ttf
start_ttf:
  incbin "path_to_font"
end_ttf:
Assemble to a nice object format, then use those symbols in your C file.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Including file data in binary

Post by Candy »

Curufir wrote: The real easy way would be to just include it in an asm file and link that into your C file.

Eg NASM

Code: Select all

global start_ttf, end_ttf
start_ttf:
  incbin "path_to_font"
end_ttf:
Assemble to a nice object format, then use those symbols in your C file.

I think you could make that more slick by making a program called something like make_bin.sh that "compiles" the binary to an includable binary object. It'd make the nasm file above and then self-feed it through nasm, then delete the temp file and keep the output file.
Curufir

Re:Including file data in binary

Post by Curufir »

For your pleasure and amusement here's a script that'll let you get an object file with a start/end symbol for any binary input:

Code: Select all

#!/bin/bash

# This script may be considered placed within the public domain

TEMP_FILE="/var/tmp/bin2obj$RANDOM.asm"

if [ "$#" -ne 4 ]
   then
      echo "usage: $0 <input> <output> <start symbol> <end symbol>"
      exit 1
elif [ -f $1 ]
   then
      cat <<-Finish > $TEMP_FILE
         global $3, $4
         $3:
         incbin "$1"
         $4:
      Finish

      nasm -f elf -o $2 $TEMP_FILE
      rm $TEMP_FILE
      exit 0
else
   echo "Input file does not exist"
   exit 1
fi
Sample Usage:
bin2obj.sh /path/to/my_ttf_font /path/to/ttf.o start_symbol end_symbol
Gnome

Re:Including file data in binary

Post by Gnome »

Wow, thanks guys. I think that'll work wonders. :)
Post Reply