NAME

ELF::Writer - Encode elf files with pure-perl

VERSION

version 0.000_001

SYNOPSIS

my $elf= ELF::Writer::Linux_x86_64->new(
  type => 'executable',
  segments => [{
    offset      => 0, # overlap segment with elf header
    virt_addr   => 0x10000,
    data        => $my_machine_code,
    data_start  => undef # calculated below
  }],
);

# Overlap the first segment with the elf header, for size efficiency
# http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html

my $prog_offset= $elf->elf_header_len + $elf->segment_header_elem_len;
$elf->segments->[0]->data_start( $prog_offset );
$elf->entry_point( $elf->segments->[0]->virt_addr + $prog_offset );

# Write out an elf file
$elf->write_file($binary_name);

MODULE STATUS

I wrote this module while learning the ELF format. This is not the work of an expert. Yet, it could still be useful for people, so I decided to implement as much as I could and publish it. Bug reports are very welcome.

The API is not completely stable, but I will at least promise the numeric accessors for the header fields will remain as-is. (type_num, machine_num, class_num, version, etc.)

DESCRPTION

This module lets you define the attributes, segments, and sections of an ELF specification, and then serialize it to a file. All data must reside in memory before writing, so this module is really just a very elaborate call to 'pack'. This module also assumes you know how an ELF file is structured, and the purpose of Segments and Sections. Patches welcome for adding user-friendly features and sanity checks.

ATTRIBUTES

class

8-bit integer, or one of: '32bit' or '64bit'. Must be set before writing.

data

8-bit integer, or one of: '2LSB' or '2MSB'. (2's complement least/most significant byte first) i.e. little-endian or big-endian

Must be set before writing.

header_version

8-bit integer; defaults to '1' for original version of ELF.

osabi

8-bit integer, or one of: 'System V', 'HP-UX', 'NetBSD', 'Linux', 'Solaris', 'AIX', 'IRIX', 'FreeBSD', 'OpenBSD', 'OpenVMS'. Must be set before writing.

osabi_version

Depends on osabi. Not used for Linux. Defaults to 0.

type

16-bit integer, or one of: 'relocatable', 'executable', 'shared', 'core'. Must be set before writing.

machine

16-bit integer, or one of: 'Sparc', 'x86', 'MIPS', 'PowerPC', 'ARM', 'SuperH', 'IA-64', 'x86-64', 'AArch64'.

version

32-bit integer; defaults to '1' for original version of ELF.

entry_point

32-bit or 64-bit pointer to address where process starts executing. Defaults to 0 unless type is 'executable', then you must specify it before writing.

flags

32 bit flags, defined per-machine.

elf_header_len

Determined from "class". (52 or 64 bytes)

segment_header_elem_len

Determined from "class". (32 or 56 bytes)

section_header_elem_len

Determined from "class". (40 or 64 bytes)

segments

Arrayref of ELF::Writer::Segment objects. You can also pass hashrefs to the constructor which will be coerced automatically.

segment_count

Handy alias for $#{ $elf->segments }

segment_list

Handy alias for @{ $elf->segments }

sections

Arrayref of ELF::Writer::Section objects. You can also pass hashrefs to the constructor which will be coerced automatically.

section_count

Handy alias for $#{ $elf->sections }

section_list

Handy alias for @{ $elf->sections }

section_name_string_table_index

Insex into the section array of a string-table section where the names of the sections are stored.

METHODS

serialize

Return a string of the composed ELF file. Throws exceptions if required attributes are missing.

AUTHOR

Michael Conrad <mike@nrdvana.net>

COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.