ELFIO/examples/write_obj/write_obj.cpp

113 lines
4.2 KiB
C++
Raw Normal View History

2012-02-18 10:01:36 +00:00
/*
2012-11-26 17:40:03 +00:00
* This example shows how to create ELF object file for Linux on x86
2012-02-18 10:01:36 +00:00
*
* Instructions:
* 1. Compile and link this file with ELFIO library
2012-11-26 17:40:03 +00:00
* g++ write_obj.cpp -o writer_obj
* 2. Execute result file write_obj
2012-11-26 17:40:03 +00:00
* ./write_obj
* 3. Link output file hello.o:
* gcc -m32 -s -nostartfiles -nostdlib hello.o -o hello
* 4. Run the result file:
* ./hello
2012-02-18 10:01:36 +00:00
*/
2012-11-26 17:40:03 +00:00
#include <elfio/elfio.hpp>
using namespace ELFIO;
2012-02-18 10:01:36 +00:00
int main( void )
{
elfio writer;
2012-02-18 10:01:36 +00:00
// You can't proceed before this function call!
writer.create( ELFCLASS32, ELFDATA2LSB );
2012-11-26 17:40:03 +00:00
writer.set_os_abi( ELFOSABI_LINUX );
2012-11-26 17:40:03 +00:00
writer.set_type( ET_REL );
writer.set_machine( EM_386 );
2012-02-18 10:01:36 +00:00
2012-11-26 17:40:03 +00:00
// This is our code
2012-06-24 06:00:28 +00:00
char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
'\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
'\xCD', '\x80', // int 0x80
'\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1
'\xCD', '\x80', // int 0x80
2012-02-18 10:01:36 +00:00
'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
'\x2C', '\x20', '\x57', '\x6F', '\x72',
'\x6C', '\x64', '\x21', '\x0A'
};
2012-11-26 17:40:03 +00:00
Elf64_Addr place_to_adjust = 11;
// Create code section
section* text_sec = writer.sections.add( ".text" );
text_sec->set_type ( SHT_PROGBITS );
text_sec->set_flags ( SHF_ALLOC | SHF_EXECINSTR );
text_sec->set_addr_align( 0x10 );
text_sec->set_data ( text, sizeof( text ) );
2012-02-18 10:01:36 +00:00
// Create string table section
section* str_sec = writer.sections.add( ".strtab" );
2012-11-26 17:40:03 +00:00
str_sec->set_type ( SHT_STRTAB );
2012-02-18 10:01:36 +00:00
// Create string table writer
2012-11-26 17:40:03 +00:00
string_section_accessor stra( str_sec );
2012-02-18 10:01:36 +00:00
// Add label name
2012-11-26 17:40:03 +00:00
Elf32_Word str_index = stra.add_string( "msg" );
2012-02-18 10:01:36 +00:00
// Create symbol table section
section* sym_sec = writer.sections.add( ".symtab" );
2012-11-26 17:40:03 +00:00
sym_sec->set_type ( SHT_SYMTAB );
sym_sec->set_info ( 2 );
sym_sec->set_addr_align( 0x4 );
2012-11-26 17:40:03 +00:00
sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) );
sym_sec->set_link ( str_sec->get_index() );
2012-02-18 10:01:36 +00:00
// Create symbol table writer
2012-11-26 17:40:03 +00:00
symbol_section_accessor syma( writer, sym_sec );
2012-02-18 10:01:36 +00:00
// Add symbol entry (msg has offset == 29)
2012-11-26 17:40:03 +00:00
Elf_Word sym_to_adjust = syma.add_symbol( str_index, 29, 0, STB_GLOBAL,
STT_OBJECT, 0,
text_sec->get_index() );
// Another way to add symbol
syma.add_symbol( stra, "_start", 0x00000000, 0, STB_WEAK, STT_FUNC, 0,
text_sec->get_index() );
2012-02-18 10:01:36 +00:00
// Create relocation table section
2012-11-26 17:40:03 +00:00
section* rel_sec = writer.sections.add( ".rel.text" );
rel_sec->set_type ( SHT_REL );
rel_sec->set_info ( text_sec->get_index() );
rel_sec->set_addr_align( 0x4 );
rel_sec->set_entry_size( writer.get_default_entry_size( SHT_REL ) );
rel_sec->set_link ( sym_sec->get_index() );
2012-02-18 10:01:36 +00:00
// Create relocation table writer
2012-11-26 17:40:03 +00:00
relocation_section_accessor rela( writer, rel_sec );
2012-02-18 10:01:36 +00:00
// Add relocation entry (adjust address at offset 11)
2012-11-26 17:40:03 +00:00
rela.add_entry( place_to_adjust, sym_to_adjust,
(unsigned char)R_386_RELATIVE );
2012-02-18 10:01:36 +00:00
2012-11-26 17:40:03 +00:00
// Another method to add the same relocation entry at one step is:
// rela.add_entry( stra, "msg",
// syma, 29, 0,
// ELF_ST_INFO( STB_GLOBAL, STT_OBJECT ), 0,
// text_sec->get_index(),
// place_to_adjust, (unsigned char)R_386_RELATIVE );
2012-02-18 10:01:36 +00:00
// Create note section
section* note_sec = writer.sections.add( ".note" );
note_sec->set_type( SHT_NOTE );
2012-11-26 17:40:03 +00:00
note_section_accessor note_writer( writer, note_sec );
note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 );
char descr[6] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36};
note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) );
2012-02-18 10:01:36 +00:00
// Create ELF object file
writer.save( "hello.o" );
2012-02-18 10:01:36 +00:00
return 0;
}