     { d_tag Elf64_Sxword }
     { d_val Elf64_Xword  } ;
 
-SPECIALIZED-ARRAYS: Elf32_Shdr Elf64_Shdr uchar ;
+! Low-level interface
+SPECIALIZED-ARRAYS: Elf32_Shdr Elf64_Shdr Elf32_Sym Elf64_Sym Elf32_Phdr Elf64_Phdr uchar ;
 UNION: Elf32/64_Ehdr Elf32_Ehdr Elf64_Ehdr ;
 UNION: Elf32/64_Shdr Elf32_Shdr Elf64_Shdr ;
 UNION: Elf32/64_Shdr-array Elf32_Shdr-array Elf64_Shdr-array ;
+UNION: Elf32/64_Sym Elf32_Sym Elf64_Sym ;
+UNION: Elf32/64_Sym-array Elf32_Sym-array Elf64_Sym-array ;
+UNION: Elf32/64_Phdr Elf32_Phdr Elf64_Phdr ;
+UNION: Elf32/64_Phdr-array Elf32_Phdr-array Elf64_Phdr-array ;
 
 TYPED: 64-bit? ( elf: Elf32/64_Ehdr -- ? )
     e_ident>> EI_CLASS swap nth ELFCLASS64 = ;

    [ <direct-Elf64_Shdr-array> ]
    [ <direct-Elf32_Shdr-array> ] if ;

TYPED:: elf-section-data ( elf: Elf32/64_Ehdr header: Elf32/64_Shdr -- uchar-array/f )
    header [ sh_offset>> elf >c-ptr <displaced-alien> ] [ sh_size>> ] bi <direct-uchar-array> ;

TYPED:: elf-section-data-by-name ( elf: Elf32/64_Ehdr name: string -- header/f uchar-array/f )
    elf elf-section-headers                      :> sections
    elf e_shstrndx>>                             :> ndx
    elf ndx sections nth elf-section-data >c-ptr :> section-names

    sections 1 tail [
        sh_name>> section-names <displaced-alien> ascii alien>string name =
    ] find nip

    [ dup elf swap elf-section-data ]
    [ f f ] if* ;

TYPED:: elf-section-names ( elf: Elf32/64_Ehdr -- names )
    elf elf-section-headers                             :> sections
    elf ".shstrtab" elf-section-data-by-name nip >c-ptr :> section-names
    sections 1 tail [
        sh_name>> section-names <displaced-alien>
        ascii alien>string
    ] { } map-as ;

! Copyright (C) 2010 Erik Charlebois.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien alien.c-types alien.strings alien.syntax arrays
classes.struct io.encodings.ascii kernel locals math math.intervals
sequences specialized-arrays strings typed ;
IN: elf

! FFI data
CONSTANT: EI_NIDENT 16
CONSTANT: EI_MAG0       0
CONSTANT: EI_MAG1       1
