[Home]Binutils/Bfd

ec2-3-145-131-238.us-east-2.compute.amazonaws.com | ToothyWiki | Binutils | RecentChanges | Login | Webcomic

libbfd


This library provides functions to read and write the contents of executable binaries and libraries.  To use the library, simply include "bfd.h", and link your program against libbdf.so. 

A binary file is represented by an instance of the "bfd" object.  Each file is broken into sections represented by "struct bfd_section" objects.  These can be retrieved by name.  For example, ".text" and ".data" are the standard section names in ELF for the code and data segments.

Although it would be possible to access the linking information directly from the appropriate bfd_sections, libbfd abstracts this functionality to allow the API to work independently of the binary structure.  To achieve this, bfd objects can be used to retrieve arrays of "struct bfd_symbol" that represent entries in the binary's linker tables.

Primary bfd object methods


Class representing a Binary File Descriptor
   // Open and close binary files
  bfd        * bfd_openr( const char * filename, const char * target );
  bfd_boolean  bfd_close( bfd * );

   //  Query file properties 
  char        * bfd_get_filename( bfd * );
  char        * bfd_get_target( bfd * );
  bfd_flavour  bfd_get_flavour( bfd * );
  flagword      bfd_get_flags(  bfd * );

   // Address of the start of executable code when loaded into memory (.text section in standard ELF)
  bfd_vma      bfd_get_start_address( bfd * );

   // Enumerate or retrieve file sections (for example ".text", ".data")
  //
  //  Callback prototype is:
  //  void callback( bfd * bfdFile,
  //                  struct bfd_section * section,
  //                  void * user_data );
  //
  void bfd_map_over_sections( bfd *, &callback, void * user_data );
  struct bfd_section * get_section_by_name( bfd *, const char * name );

   // Symbol access
  long bfd_get_symtab_upper_bound( bfd * );
  long bfd_canonicalize_symtab( bfd *, struct bfd_symbol ** symbols );

   long bfd_get_dynamic_symtab_upper_bound( bfd * );
  long bfd_canonicalize_dynamic_symtab( bfd *, struct bfd_symbol ** symbols );

Primary struct bfd_sections properties


Class representing a section in an binary file
   // Section name
  const char    * name;

   //  Address and size of section when loaded into memory
  bfd_vma        vma;
  bfd_size_type  size;

Primary "struct bfd_symbol" properties


Class representing an entry in one of the binary's symbol table
   //  The symbol name, the section it resides in, and standard symbol information structure
  const char * name
  struct bfd_section * section
  void bfd_symbol_info( struct bfd_symbol *, symbol_info * info );

Example: Opening an existing binary file


This code opens /bin/ls as an 64-bit x86 ELF binary.  Note that it is necessary to call bfd_check_format() before using the bfd instance.

   bfd_init();

   bfd * bfdFile = bfd_openr( "/bin/ls", "elf64-x86-64" );
  if ( bfdFile == NULL )
  {
      printf( "Error [%x]: %s\n", bfd_get_error(), bfd_errmsg(bfd_get_error()) );
      return;
  }

   if ( !bfd_check_format( bfdFile, bfd_object ))
  {
      printf( "Error [%x]: %s\n", bfd_get_error(), bfd_errmsg(bfd_get_error()) );
      return;
  }

   // Program goes here

   bfd_close( bfdFile );

Reading symbol tables


Retrieving the symbols included in the bfd file is slightly more complicated (you need to pass in a buffer of appropriate size). The code below extracts the dynamic symbols from a bfd instance (static symbols are similar):

    struct bfd_symbol ** symbols;
    long                symbolsSize;
    long                symbolsCount;

    long i;

    // Calculate required buffer size
    symbolsSize = bfd_get_dynamic_symtab_upper_bound( bfdFile );
    if ( symbolsSize < 0 )
    {
      printf( "Error [%x]: %s\n", bfd_get_error(), bfd_errmsg(bfd_get_error()) );
      return;
    }

    // Allocate buffer
    symbols = malloc( symbolsSize );
    if ( symbols == NULL )
    {
      printf( "Could not allocate memory\n" );
      return;
    }

    // Retrieve unpacked symbols
    symbolsCount = bfd_canonicalize_dynamic_symtab( bfdFile, symbols );
    if ( symbolsCount < 0 )
    {
      printf( "Error [%x]: %s\n", bfd_get_error(), bfd_errmsg(bfd_get_error()) );
      free( symbols );
      return;
    }

    // List symbols
    for ( i = 0; i < symbolsCount; i++ )
    {
      printf( "Symbol [flags %x][value %x] %s\n", symbols[i]->flags, symbols[i]->value, symbols[i]->name );
    }

    free( symbols );

Modifying and linking binary files


In addition to examining existing files, libbfd also has functionality for creating and modifying them.  The most advanced functionality is in the area of code disassemble/reassembly and linking.  This can even support code compiled for different machine architectures.

ec2-3-145-131-238.us-east-2.compute.amazonaws.com | ToothyWiki | Binutils | RecentChanges | Login | Webcomic
This page is read-only | View other revisions | Recently used referrers
Last edited January 12, 2009 11:10 pm (viewing revision 1, which is the newest) (diff)
Search: