# faerie [![Build Status](https://github.com/m4b/faerie/workflows/CI/badge.svg)](https://github.com/m4b/faerie/actions) [![Documentatation](https://docs.rs/faerie/badge.svg)](https://docs.rs/faerie). Emit some object files, at your leisure: ```rust let name = "test.o"; let file = File::create(Path::new(name))?; let mut obj = ArtifactBuilder::new(triple!("x86_64-unknown-unknown-unknown-elf")) .name(name.to_owned()) .finish(); // first we declare our symbolic references; // it is a runtime error to define a symbol _without_ declaring it first obj.declarations( [ ("deadbeef", Decl::function().into()), ("main", Decl::function().global().into()), ("str.1", Decl::cstring().into()), ("DEADBEEF", Decl::data_import().into()), ("printf", Decl::function_import().into()), ].iter().cloned() )?; // we now define our local functions and data // 0000000000000000 : // 0: 55 push %rbp // 1: 48 89 e5 mov %rsp,%rbp // 4: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # b // 7: R_X86_64_GOTPCREL DEADBEEF-0x4 // b: 8b 08 mov (%rax),%ecx // d: 83 c1 01 add $0x1,%ecx // 10: 89 c8 mov %ecx,%eax // 12: 5d pop %rbp // 13: c3 retq obj.define("deadbeef", vec![0x55, 0x48, 0x89, 0xe5, 0x48, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x08, 0x83, 0xc1, 0x01, 0x89, 0xc8, 0x5d, 0xc3])?; // main: // 55 push %rbp // 48 89 e5 mov %rsp,%rbp // b8 00 00 00 00 mov $0x0,%eax // e8 00 00 00 00 callq 0x0 // 89 c6 mov %eax,%esi // 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # will be: deadbeef: 0x%x\n // b8 00 00 00 00 mov $0x0,%eax // e8 00 00 00 00 callq 0x3f # printf // b8 00 00 00 00 mov $0x0,%eax // 5d pop %rbp // c3 retq obj.define("main", vec![0x55, 0x48, 0x89, 0xe5, 0xb8, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x89, 0xc6, 0x48, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xc3])?; obj.define("str.1", b"deadbeef: 0x%x\n\0".to_vec())?; // Next, we declare our relocations, // which are _always_ relative to the `from` symbol obj.link(Link { from: "main", to: "str.1", at: 19 })?; obj.link(Link { from: "main", to: "printf", at: 29 })?; obj.link(Link { from: "main", to: "deadbeef", at: 10 })?; obj.link(Link { from: "deadbeef", to: "DEADBEEF", at: 7 })?; // Finally, we write the object file obj.write(file)?; ``` Will emit an object file like this:
ELF REL X86_64-little-endian @ 0x0:

e_phoff: 0x0 e_shoff: 0x2a2 e_flags: 0x0 e_ehsize: 64 e_phentsize: 56 e_phnum: 0 e_shentsize: 64 e_shnum: 9 e_shstrndx: 1

SectionHeaders(9):
  Idx   Name                      Type   Flags                  Offset   Addr   Size    Link         Entsize   Align  
  0                           SHT_NULL                          0x0      0x0    0x0                  0x0       0x0    
  1     .strtab             SHT_STRTAB                          0x8c     0x0    0xc6                 0x0       0x1    
  2     .symtab             SHT_SYMTAB                          0x152    0x0    0xf0    .strtab(1)   0x18      0x8    
  3     .rodata.str.1       SHT_PROGBITS   ALLOC MERGE STRINGS    0x40     0x0    0x10                 0x1       0x1    
  4     .text.deadbeef    SHT_PROGBITS   ALLOC EXECINSTR        0x50     0x0    0x14                 0x0       0x10   
  5     .text.main        SHT_PROGBITS   ALLOC EXECINSTR        0x64     0x0    0x28                 0x0       0x10   
  6     .reloc.main           SHT_RELA                          0x242    0x0    0x48    .symtab(2)   0x18      0x8    
  7     .reloc.deadbeef       SHT_RELA                          0x28a    0x0    0x18    .symtab(2)   0x18      0x8    
  8     .note.GNU-stack   SHT_PROGBITS                          0x0      0x0    0x0                  0x0       0x1    

Syms(10):
               Addr   Bind       Type        Symbol     Size    Section             Other  
                 0    LOCAL      NOTYPE                 0x0                         0x0    
                 0    LOCAL      FILE        test.o     0x0     ABS                 0x0    
                 0    LOCAL      SECTION                0x0     .rodata.str.1(3)      0x0    
                 0    LOCAL      SECTION                0x0     .text.deadbeef(4)   0x0    
                 0    LOCAL      SECTION                0x0     .text.main(5)       0x0    
                 0    LOCAL      OBJECT      str.1      0x10    .rodata.str.1(3)      0x0    
                 0    LOCAL      FUNC        deadbeef   0x14    .text.deadbeef(4)   0x0    
                 0    GLOBAL     FUNC        main       0x28    .text.main(5)       0x0    
                 0    GLOBAL     NOTYPE      DEADBEEF   0x0                         0x0    
                 0    GLOBAL     NOTYPE      printf     0x0                         0x0    

Shdr Relocations(4):
  .text.main(3)
              13 X86_64_PC32 .rodata.str.1
              1d X86_64_PLT32 printf+-4
               a X86_64_PLT32 .text.deadbeef+-4

  .text.deadbeef(1)
               7 X86_64_GOTPCREL DEADBEEF+-4
:sunglasses: