165042b18Sopenharmony_ci/* 265042b18Sopenharmony_ciCopyright (C) 2001-present by Serge Lamikhov-Center 365042b18Sopenharmony_ci 465042b18Sopenharmony_ciPermission is hereby granted, free of charge, to any person obtaining a copy 565042b18Sopenharmony_ciof this software and associated documentation files (the "Software"), to deal 665042b18Sopenharmony_ciin the Software without restriction, including without limitation the rights 765042b18Sopenharmony_cito use, copy, modify, merge, publish, distribute, sublicense, and/or sell 865042b18Sopenharmony_cicopies of the Software, and to permit persons to whom the Software is 965042b18Sopenharmony_cifurnished to do so, subject to the following conditions: 1065042b18Sopenharmony_ci 1165042b18Sopenharmony_ciThe above copyright notice and this permission notice shall be included in 1265042b18Sopenharmony_ciall copies or substantial portions of the Software. 1365042b18Sopenharmony_ci 1465042b18Sopenharmony_ciTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1565042b18Sopenharmony_ciIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1665042b18Sopenharmony_ciFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1765042b18Sopenharmony_ciAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1865042b18Sopenharmony_ciLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1965042b18Sopenharmony_ciOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2065042b18Sopenharmony_ciTHE SOFTWARE. 2165042b18Sopenharmony_ci*/ 2265042b18Sopenharmony_ci 2365042b18Sopenharmony_ci/* 2465042b18Sopenharmony_ci * This example shows how to create ELF executable file for Linux on x86-64 2565042b18Sopenharmony_ci * 2665042b18Sopenharmony_ci * Instructions: 2765042b18Sopenharmony_ci * 1. Compile and link this file with ELFIO library 2865042b18Sopenharmony_ci * g++ writer.cpp -o writer 2965042b18Sopenharmony_ci * 2. Execute result file writer 3065042b18Sopenharmony_ci * ./writer 3165042b18Sopenharmony_ci * 3. Add executable flag for the output file 3265042b18Sopenharmony_ci * chmod +x hello_x86_64 3365042b18Sopenharmony_ci * 4. Run the result file: 3465042b18Sopenharmony_ci * ./hello_x86_64 3565042b18Sopenharmony_ci */ 3665042b18Sopenharmony_ci 3765042b18Sopenharmony_ci#include <elfio/elfio.hpp> 3865042b18Sopenharmony_ci 3965042b18Sopenharmony_ciusing namespace ELFIO; 4065042b18Sopenharmony_ci 4165042b18Sopenharmony_ciconst Elf64_Addr CODE_ADDR = 0x00401000; 4265042b18Sopenharmony_ciconst Elf_Xword PAGE_SIZE = 0x1000; 4365042b18Sopenharmony_ciconst Elf64_Addr DATA_ADDR = CODE_ADDR + PAGE_SIZE; 4465042b18Sopenharmony_ci 4565042b18Sopenharmony_ciint main( void ) 4665042b18Sopenharmony_ci{ 4765042b18Sopenharmony_ci elfio writer; 4865042b18Sopenharmony_ci 4965042b18Sopenharmony_ci // You can't proceed without this function call! 5065042b18Sopenharmony_ci writer.create( ELFCLASS64, ELFDATA2LSB ); 5165042b18Sopenharmony_ci 5265042b18Sopenharmony_ci writer.set_os_abi( ELFOSABI_LINUX ); 5365042b18Sopenharmony_ci writer.set_type( ET_EXEC ); 5465042b18Sopenharmony_ci writer.set_machine( EM_X86_64 ); 5565042b18Sopenharmony_ci 5665042b18Sopenharmony_ci // Create code section 5765042b18Sopenharmony_ci section* text_sec = writer.sections.add( ".text" ); 5865042b18Sopenharmony_ci text_sec->set_type( SHT_PROGBITS ); 5965042b18Sopenharmony_ci text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR ); 6065042b18Sopenharmony_ci text_sec->set_addr_align( 0x10 ); 6165042b18Sopenharmony_ci 6265042b18Sopenharmony_ci // Add data into it 6365042b18Sopenharmony_ci char text[] = { 6465042b18Sopenharmony_ci '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4 6565042b18Sopenharmony_ci '\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1 6665042b18Sopenharmony_ci '\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg 6765042b18Sopenharmony_ci '\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14 6865042b18Sopenharmony_ci '\xCD', '\x80', // int 0x80 6965042b18Sopenharmony_ci '\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1 7065042b18Sopenharmony_ci '\xCD', '\x80' // int 0x80 7165042b18Sopenharmony_ci }; 7265042b18Sopenharmony_ci // Adjust data address for 'msg' 7365042b18Sopenharmony_ci *(uint32_t*)( text + 11 ) = DATA_ADDR; 7465042b18Sopenharmony_ci 7565042b18Sopenharmony_ci text_sec->set_data( text, sizeof( text ) ); 7665042b18Sopenharmony_ci 7765042b18Sopenharmony_ci // Create a loadable segment 7865042b18Sopenharmony_ci segment* text_seg = writer.segments.add(); 7965042b18Sopenharmony_ci text_seg->set_type( PT_LOAD ); 8065042b18Sopenharmony_ci text_seg->set_virtual_address( CODE_ADDR ); 8165042b18Sopenharmony_ci text_seg->set_physical_address( CODE_ADDR ); 8265042b18Sopenharmony_ci text_seg->set_flags( PF_X | PF_R ); 8365042b18Sopenharmony_ci text_seg->set_align( PAGE_SIZE ); 8465042b18Sopenharmony_ci 8565042b18Sopenharmony_ci // Add code section into program segment 8665042b18Sopenharmony_ci text_seg->add_section( text_sec, text_sec->get_addr_align() ); 8765042b18Sopenharmony_ci 8865042b18Sopenharmony_ci // Create data section 8965042b18Sopenharmony_ci section* data_sec = writer.sections.add( ".data" ); 9065042b18Sopenharmony_ci data_sec->set_type( SHT_PROGBITS ); 9165042b18Sopenharmony_ci data_sec->set_flags( SHF_ALLOC | SHF_WRITE ); 9265042b18Sopenharmony_ci data_sec->set_addr_align( 0x4 ); 9365042b18Sopenharmony_ci 9465042b18Sopenharmony_ci char data[] = { 9565042b18Sopenharmony_ci '\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10 9665042b18Sopenharmony_ci '\x2C', '\x20', '\x57', '\x6F', '\x72', 9765042b18Sopenharmony_ci '\x6C', '\x64', '\x21', '\x0A' }; 9865042b18Sopenharmony_ci data_sec->set_data( data, sizeof( data ) ); 9965042b18Sopenharmony_ci 10065042b18Sopenharmony_ci // Create a read/write segment 10165042b18Sopenharmony_ci segment* data_seg = writer.segments.add(); 10265042b18Sopenharmony_ci data_seg->set_type( PT_LOAD ); 10365042b18Sopenharmony_ci data_seg->set_virtual_address( DATA_ADDR ); 10465042b18Sopenharmony_ci data_seg->set_physical_address( DATA_ADDR ); 10565042b18Sopenharmony_ci data_seg->set_flags( PF_W | PF_R ); 10665042b18Sopenharmony_ci data_seg->set_align( PAGE_SIZE ); 10765042b18Sopenharmony_ci 10865042b18Sopenharmony_ci // Add code section into program segment 10965042b18Sopenharmony_ci data_seg->add_section( data_sec, data_sec->get_addr_align() ); 11065042b18Sopenharmony_ci 11165042b18Sopenharmony_ci // Add optional signature for the file producer 11265042b18Sopenharmony_ci section* note_sec = writer.sections.add( ".note" ); 11365042b18Sopenharmony_ci note_sec->set_type( SHT_NOTE ); 11465042b18Sopenharmony_ci note_sec->set_addr_align( 1 ); 11565042b18Sopenharmony_ci 11665042b18Sopenharmony_ci note_section_accessor note_writer( writer, note_sec ); 11765042b18Sopenharmony_ci note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 ); 11865042b18Sopenharmony_ci char descr[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 }; 11965042b18Sopenharmony_ci note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) ); 12065042b18Sopenharmony_ci 12165042b18Sopenharmony_ci // Setup entry point. Usually, a linker sets this address on base of 12265042b18Sopenharmony_ci // ‘_start’ label. 12365042b18Sopenharmony_ci // In this example, the code starts at the first address of the 12465042b18Sopenharmony_ci // 'text_seg' segment. Therefore, the start address is set 12565042b18Sopenharmony_ci // to be equal to the segment location 12665042b18Sopenharmony_ci writer.set_entry( text_seg->get_virtual_address() ); 12765042b18Sopenharmony_ci 12865042b18Sopenharmony_ci // Create ELF file 12965042b18Sopenharmony_ci writer.save( "hello_x86_64" ); 13065042b18Sopenharmony_ci 13165042b18Sopenharmony_ci return 0; 13265042b18Sopenharmony_ci} 133